mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-07 03:12:36 +01:00
Skeleton collision effect handling
This commit is contained in:
parent
4f0109b17e
commit
65f51bc3c2
@ -463,24 +463,32 @@ struct DynamicObjectData {
|
|||||||
float mass; // Kg
|
float mass; // Kg
|
||||||
float turnMass; // Kg m^3
|
float turnMass; // Kg m^3
|
||||||
float airRes; // fraction
|
float airRes; // fraction
|
||||||
float elacticity; // "
|
float elasticity; // "
|
||||||
float bouancy;
|
float buoyancy;
|
||||||
float uprootForce; // Force
|
float uprootForce; // Force
|
||||||
float collDamageMulti;
|
float collDamageMulti;
|
||||||
/*
|
|
||||||
* 1: change model
|
enum {
|
||||||
* 2: split model
|
Damage_ChangeModel = 1,
|
||||||
* 3: smash
|
Damage_SplitModel = 2,
|
||||||
* 4: change and smash
|
Damage_Smash = 3,
|
||||||
*/
|
Damage_ChangeThenSmash = 4,
|
||||||
uint8_t collDamageFlags;
|
Damage_SmashCardboard = 50,
|
||||||
/*
|
Damage_SmashWoodenBox = 60,
|
||||||
* 1: lampost
|
Damage_SmashTrafficCone = 70,
|
||||||
* 2: smallbox
|
Damage_SmashBarPost = 80,
|
||||||
* 3: bigbox
|
};
|
||||||
* 4: fencepart
|
uint8_t collDamageEffect;
|
||||||
*/
|
|
||||||
|
enum {
|
||||||
|
Response_None = 0,
|
||||||
|
Response_LampPost = 1,
|
||||||
|
Response_SmallBox = 2,
|
||||||
|
Response_BigBox = 3,
|
||||||
|
Response_FencePart = 4,
|
||||||
|
};
|
||||||
uint8_t collResponseFlags;
|
uint8_t collResponseFlags;
|
||||||
|
|
||||||
bool cameraAvoid;
|
bool cameraAvoid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -587,9 +587,12 @@ void handleInstanceResponse(InstanceObject *instance, const btManifoldPoint &mp,
|
|||||||
auto impulse = mp.getAppliedImpulse();
|
auto impulse = mp.getAppliedImpulse();
|
||||||
|
|
||||||
if (impulse > 0.0f) {
|
if (impulse > 0.0f) {
|
||||||
|
///@ todo Correctness: object damage calculation
|
||||||
|
constexpr auto kMinimumDamageImpulse = 500.f;
|
||||||
|
const auto hp = std::max(0.f, impulse - kMinimumDamageImpulse);
|
||||||
instance->takeDamage({{dmg.x(), dmg.y(), dmg.z()},
|
instance->takeDamage({{dmg.x(), dmg.y(), dmg.z()},
|
||||||
{dmg.x(), dmg.y(), dmg.z()},
|
{dmg.x(), dmg.y(), dmg.z()},
|
||||||
0.f,
|
hp,
|
||||||
GameObject::DamageInfo::Physics,
|
GameObject::DamageInfo::Physics,
|
||||||
impulse});
|
impulse});
|
||||||
}
|
}
|
||||||
|
@ -37,9 +37,9 @@ void GenericDATLoader::loadDynamicObjects(const std::string& name,
|
|||||||
if (ss.peek() == ',') ss.ignore(1);
|
if (ss.peek() == ',') ss.ignore(1);
|
||||||
ss >> dyndata->airRes;
|
ss >> dyndata->airRes;
|
||||||
if (ss.peek() == ',') ss.ignore(1);
|
if (ss.peek() == ',') ss.ignore(1);
|
||||||
ss >> dyndata->elacticity;
|
ss >> dyndata->elasticity;
|
||||||
if (ss.peek() == ',') ss.ignore(1);
|
if (ss.peek() == ',') ss.ignore(1);
|
||||||
ss >> dyndata->bouancy;
|
ss >> dyndata->buoyancy;
|
||||||
if (ss.peek() == ',') ss.ignore(1);
|
if (ss.peek() == ',') ss.ignore(1);
|
||||||
ss >> dyndata->uprootForce;
|
ss >> dyndata->uprootForce;
|
||||||
if (ss.peek() == ',') ss.ignore(1);
|
if (ss.peek() == ',') ss.ignore(1);
|
||||||
@ -47,7 +47,7 @@ void GenericDATLoader::loadDynamicObjects(const std::string& name,
|
|||||||
if (ss.peek() == ',') ss.ignore(1);
|
if (ss.peek() == ',') ss.ignore(1);
|
||||||
int tmp;
|
int tmp;
|
||||||
ss >> tmp;
|
ss >> tmp;
|
||||||
dyndata->collDamageFlags = tmp;
|
dyndata->collDamageEffect = tmp;
|
||||||
if (ss.peek() == ',') ss.ignore(1);
|
if (ss.peek() == ',') ss.ignore(1);
|
||||||
ss >> tmp;
|
ss >> tmp;
|
||||||
dyndata->collResponseFlags = tmp;
|
dyndata->collResponseFlags = tmp;
|
||||||
|
@ -47,7 +47,18 @@ InstanceObject::~InstanceObject() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InstanceObject::tick(float dt) {
|
void InstanceObject::tick(float dt) {
|
||||||
if (dynamics && body) {
|
if (animator) animator->tick(dt);
|
||||||
|
|
||||||
|
if (!body || !dynamics) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changeAtomic != -1) {
|
||||||
|
RW_ASSERT(getModelInfo<SimpleModelInfo>()->getNumAtomics() >
|
||||||
|
changeAtomic);
|
||||||
|
changeModel(getModelInfo<SimpleModelInfo>(), changeAtomic);
|
||||||
|
changeAtomic = -1;
|
||||||
|
}
|
||||||
if (_enablePhysics) {
|
if (_enablePhysics) {
|
||||||
if (body->getBulletBody()->isStaticObject()) {
|
if (body->getBulletBody()->isStaticObject()) {
|
||||||
body->changeMass(dynamics->mass);
|
body->changeMass(dynamics->mass);
|
||||||
@ -78,7 +89,7 @@ void InstanceObject::tick(float dt) {
|
|||||||
|
|
||||||
if (inWater) {
|
if (inWater) {
|
||||||
float oZ =
|
float oZ =
|
||||||
-(body->getBoundingHeight() * (dynamics->bouancy / 100.f));
|
-(body->getBoundingHeight() * (dynamics->buoyancy / 100.f));
|
||||||
body->getBulletBody()->activate(true);
|
body->getBulletBody()->activate(true);
|
||||||
// Damper motion
|
// Damper motion
|
||||||
body->getBulletBody()->setDamping(0.95f, 0.9f);
|
body->getBulletBody()->setDamping(0.95f, 0.9f);
|
||||||
@ -91,19 +102,6 @@ void InstanceObject::tick(float dt) {
|
|||||||
h += engine->data->getWaveHeightAt(ws);
|
h += engine->data->getWaveHeightAt(ws);
|
||||||
|
|
||||||
if (ws.z <= h) {
|
if (ws.z <= h) {
|
||||||
/*if( dynamics->uprootForce > 0.f &&
|
|
||||||
(body->body->getCollisionFlags() &
|
|
||||||
btRigidBody::CF_STATIC_OBJECT) != 0 ) {
|
|
||||||
// Apparently bodies must be removed and re-added if
|
|
||||||
their mass changes.
|
|
||||||
engine->dynamicsWorld->removeRigidBody(body->body);
|
|
||||||
btVector3 inert;
|
|
||||||
body->getCollisionShape()->calculateLocalInertia(dynamics->mass,
|
|
||||||
inert);
|
|
||||||
body->setMassProps(dynamics->mass, inert);
|
|
||||||
engine->dynamicsWorld->addRigidBody(body);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
float x = (h - ws.z);
|
float x = (h - ws.z);
|
||||||
float F =
|
float F =
|
||||||
WATER_BUOYANCY_K * x +
|
WATER_BUOYANCY_K * x +
|
||||||
@ -121,12 +119,9 @@ void InstanceObject::tick(float dt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (animator) animator->tick(dt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceObject::changeModel(BaseModelInfo* incoming) {
|
void InstanceObject::changeModel(BaseModelInfo* incoming, int atomicNumber) {
|
||||||
if (body) {
|
if (body) {
|
||||||
body.reset();
|
body.reset();
|
||||||
}
|
}
|
||||||
@ -141,12 +136,13 @@ void InstanceObject::changeModel(BaseModelInfo* incoming) {
|
|||||||
setModel(getModelInfo<SimpleModelInfo>()->getModel());
|
setModel(getModelInfo<SimpleModelInfo>()->getModel());
|
||||||
auto collision = getModelInfo<SimpleModelInfo>()->getCollision();
|
auto collision = getModelInfo<SimpleModelInfo>()->getCollision();
|
||||||
|
|
||||||
auto modelatomic = getModelInfo<SimpleModelInfo>()->getAtomic(0);
|
RW_ASSERT(getModelInfo<SimpleModelInfo>()->getNumAtomics() > atomicNumber);
|
||||||
if (modelatomic) {
|
auto atomic = getModelInfo<SimpleModelInfo>()->getAtomic(atomicNumber);
|
||||||
auto previousatomic = atomic_;
|
if (atomic) {
|
||||||
atomic_ = modelatomic->clone();
|
auto previous = atomic_;
|
||||||
if (previousatomic) {
|
atomic_ = atomic->clone();
|
||||||
atomic_->setFrame(previousatomic->getFrame());
|
if (previous) {
|
||||||
|
atomic_->setFrame(previous->getFrame());
|
||||||
} else {
|
} else {
|
||||||
atomic_->setFrame(std::make_shared<ModelFrame>());
|
atomic_->setFrame(std::make_shared<ModelFrame>());
|
||||||
}
|
}
|
||||||
@ -182,20 +178,41 @@ void InstanceObject::setRotation(const glm::quat& r) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool InstanceObject::takeDamage(const GameObject::DamageInfo& dmg) {
|
bool InstanceObject::takeDamage(const GameObject::DamageInfo& dmg) {
|
||||||
bool smash = false;
|
if (!dynamics) {
|
||||||
if (dynamics) {
|
return false;
|
||||||
smash = dynamics->collDamageFlags == 80;
|
}
|
||||||
|
|
||||||
|
const auto effect = dynamics->collDamageEffect;
|
||||||
|
|
||||||
|
if (dmg.hitpoints > 0.f) {
|
||||||
|
switch (effect) {
|
||||||
|
case DynamicObjectData::Damage_ChangeModel:
|
||||||
|
changeAtomic = 1;
|
||||||
|
break;
|
||||||
|
case DynamicObjectData::Damage_ChangeThenSmash:
|
||||||
|
changeAtomic = 1;
|
||||||
|
RW_UNIMPLEMENTED("Collision Damage Effect: Changing, then Smashing");
|
||||||
|
break;
|
||||||
|
case DynamicObjectData::Damage_Smash:
|
||||||
|
RW_UNIMPLEMENTED("Collision Damage Effect: Smashing");
|
||||||
|
break;
|
||||||
|
case DynamicObjectData::Damage_SmashCardboard:
|
||||||
|
case DynamicObjectData::Damage_SmashWoodenBox:
|
||||||
|
case DynamicObjectData::Damage_SmashTrafficCone:
|
||||||
|
case DynamicObjectData::Damage_SmashBarPost:
|
||||||
|
RW_UNIMPLEMENTED("Collision Damage Effect");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dmg.impulse >= dynamics->uprootForce &&
|
if (dmg.impulse >= dynamics->uprootForce &&
|
||||||
body->getBulletBody()->isStaticObject()) {
|
body->getBulletBody()->isStaticObject()) {
|
||||||
_enablePhysics = true;
|
_enablePhysics = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (smash) {
|
|
||||||
health -= dmg.hitpoints;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceObject::setSolid(bool solid) {
|
void InstanceObject::setSolid(bool solid) {
|
||||||
|
@ -19,6 +19,7 @@ class GameWorld;
|
|||||||
class InstanceObject : public GameObject {
|
class InstanceObject : public GameObject {
|
||||||
float health;
|
float health;
|
||||||
bool visible = true;
|
bool visible = true;
|
||||||
|
int changeAtomic = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Atomic instance for this object
|
* The Atomic instance for this object
|
||||||
@ -47,7 +48,7 @@ public:
|
|||||||
|
|
||||||
void tick(float dt) override;
|
void tick(float dt) override;
|
||||||
|
|
||||||
void changeModel(BaseModelInfo* incoming);
|
void changeModel(BaseModelInfo* incoming, int atomicNumber = 0);
|
||||||
|
|
||||||
void setPosition(const glm::vec3& pos) override;
|
void setPosition(const glm::vec3& pos) override;
|
||||||
|
|
||||||
|
@ -59,11 +59,11 @@ BOOST_AUTO_TEST_CASE(test_dynamic_dat_loader) {
|
|||||||
BOOST_CHECK_EQUAL(lamp->mass, 600.0);
|
BOOST_CHECK_EQUAL(lamp->mass, 600.0);
|
||||||
BOOST_CHECK_EQUAL(lamp->turnMass, 4000.0);
|
BOOST_CHECK_EQUAL(lamp->turnMass, 4000.0);
|
||||||
BOOST_CHECK_CLOSE(lamp->airRes, 0.99, 1.0);
|
BOOST_CHECK_CLOSE(lamp->airRes, 0.99, 1.0);
|
||||||
BOOST_CHECK_CLOSE(lamp->elacticity, 0.05, 0.01);
|
BOOST_CHECK_CLOSE(lamp->elasticity, 0.05, 0.01);
|
||||||
BOOST_CHECK_EQUAL(lamp->bouancy, 50.0);
|
BOOST_CHECK_EQUAL(lamp->buoyancy, 50.0);
|
||||||
BOOST_CHECK_EQUAL(lamp->uprootForce, 400);
|
BOOST_CHECK_EQUAL(lamp->uprootForce, 400);
|
||||||
BOOST_CHECK_EQUAL(lamp->collDamageMulti, 1.0);
|
BOOST_CHECK_EQUAL(lamp->collDamageMulti, 1.0);
|
||||||
BOOST_CHECK_EQUAL(lamp->collDamageFlags, 1);
|
BOOST_CHECK_EQUAL(lamp->collDamageEffect, 1);
|
||||||
BOOST_CHECK_EQUAL(lamp->collResponseFlags, 1);
|
BOOST_CHECK_EQUAL(lamp->collResponseFlags, 1);
|
||||||
BOOST_CHECK_EQUAL(lamp->cameraAvoid, false);
|
BOOST_CHECK_EQUAL(lamp->cameraAvoid, false);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user