mirror of
https://github.com/rwengine/openrw.git
synced 2024-09-15 06:52:34 +02:00
Make DamageInfo construction more explicit
This commit is contained in:
parent
bdacc1137a
commit
f59653eeea
@ -570,41 +570,39 @@ void GameWorld::destroyEffect(VisualFX& effect) {
|
|||||||
void GameWorld::doWeaponScan(const WeaponScan& scan) {
|
void GameWorld::doWeaponScan(const WeaponScan& scan) {
|
||||||
if (scan.type == ScanType::Radius) {
|
if (scan.type == ScanType::Radius) {
|
||||||
HitTest test {*dynamicsWorld};
|
HitTest test {*dynamicsWorld};
|
||||||
const auto result = test.sphereTest(scan.center, scan.radius);
|
const auto& result = test.sphereTest(scan.center, scan.radius);
|
||||||
|
|
||||||
for(const auto& target : result) {
|
for(const auto& target : result) {
|
||||||
if (!scan.doesDamage(target.object)) {
|
if (!scan.doesDamage(target.object)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameObject::DamageInfo di;
|
target.object->takeDamage(
|
||||||
di.damageSource = scan.center;
|
{
|
||||||
di.type = GameObject::DamageInfo::Melee;
|
GameObject::DamageInfo::DamageType::Melee,
|
||||||
di.hitpoints = scan.damage;
|
{}, scan.center, scan.damage
|
||||||
target.object->takeDamage(di);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (scan.type == ScanType::HitScan) {
|
} else if (scan.type == ScanType::HitScan) {
|
||||||
btVector3 from(scan.center.x, scan.center.y, scan.center.z),
|
btVector3 from(scan.center.x, scan.center.y, scan.center.z),
|
||||||
to(scan.end.x, scan.end.y, scan.end.z);
|
to(scan.end.x, scan.end.y, scan.end.z);
|
||||||
glm::vec3 hitEnd = scan.end;
|
|
||||||
btCollisionWorld::ClosestRayResultCallback cb(from, to);
|
btCollisionWorld::ClosestRayResultCallback cb(from, to);
|
||||||
cb.m_collisionFilterGroup = btBroadphaseProxy::AllFilter;
|
cb.m_collisionFilterGroup = btBroadphaseProxy::AllFilter;
|
||||||
dynamicsWorld->rayTest(from, to, cb);
|
dynamicsWorld->rayTest(from, to, cb);
|
||||||
// TODO: did any weapons penetrate?
|
if (!cb.hasHit()) {
|
||||||
|
return;
|
||||||
if (cb.hasHit()) {
|
|
||||||
GameObject* go = static_cast<GameObject*>(
|
|
||||||
cb.m_collisionObject->getUserPointer());
|
|
||||||
GameObject::DamageInfo di;
|
|
||||||
hitEnd = di.damageLocation =
|
|
||||||
glm::vec3(cb.m_hitPointWorld.x(), cb.m_hitPointWorld.y(),
|
|
||||||
cb.m_hitPointWorld.z());
|
|
||||||
di.damageSource = scan.center;
|
|
||||||
di.type = GameObject::DamageInfo::Bullet;
|
|
||||||
di.hitpoints = scan.damage;
|
|
||||||
go->takeDamage(di);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto go = static_cast<GameObject *>(
|
||||||
|
cb.m_collisionObject->getUserPointer());
|
||||||
|
go->takeDamage(
|
||||||
|
{
|
||||||
|
GameObject::DamageInfo::DamageType::Bullet,
|
||||||
|
{cb.m_hitPointWorld.x(), cb.m_hitPointWorld.y(),
|
||||||
|
cb.m_hitPointWorld.z()},
|
||||||
|
scan.center, scan.damage
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,11 +669,13 @@ void handleVehicleResponse(GameObject* object, btManifoldPoint& mp, bool isA) {
|
|||||||
dmg = mp.getPositionWorldOnB();
|
dmg = mp.getPositionWorldOnB();
|
||||||
}
|
}
|
||||||
|
|
||||||
object->takeDamage({{dmg.x(), dmg.y(), dmg.z()},
|
object->takeDamage({
|
||||||
|
GameObject::DamageInfo::DamageType::Physics,
|
||||||
|
{dmg.x(), dmg.y(), dmg.z()},
|
||||||
{src.x(), src.y(), src.z()},
|
{src.x(), src.y(), src.z()},
|
||||||
0.f,
|
0.f,
|
||||||
GameObject::DamageInfo::Physics,
|
mp.getAppliedImpulse()
|
||||||
mp.getAppliedImpulse()});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleInstanceResponse(InstanceObject* instance, const btManifoldPoint& mp,
|
void handleInstanceResponse(InstanceObject* instance, const btManifoldPoint& mp,
|
||||||
@ -687,16 +687,20 @@ void handleInstanceResponse(InstanceObject* instance, const btManifoldPoint& mp,
|
|||||||
auto dmg = isA ? mp.m_positionWorldOnA : mp.m_positionWorldOnB;
|
auto dmg = isA ? mp.m_positionWorldOnA : mp.m_positionWorldOnB;
|
||||||
auto impulse = mp.getAppliedImpulse();
|
auto impulse = mp.getAppliedImpulse();
|
||||||
|
|
||||||
if (impulse > 0.0f) {
|
if (impulse <= 0.0f) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
///@ todo Correctness: object damage calculation
|
///@ todo Correctness: object damage calculation
|
||||||
constexpr auto kMinimumDamageImpulse = 500.f;
|
constexpr auto kMinimumDamageImpulse = 500.f;
|
||||||
const auto hp = std::max(0.f, impulse - kMinimumDamageImpulse);
|
const auto hp = std::max(0.f, impulse - kMinimumDamageImpulse);
|
||||||
instance->takeDamage({{dmg.x(), dmg.y(), dmg.z()},
|
instance->takeDamage({
|
||||||
|
GameObject::DamageInfo::DamageType::Physics,
|
||||||
|
{dmg.x(), dmg.y(), dmg.z()},
|
||||||
{dmg.x(), dmg.y(), dmg.z()},
|
{dmg.x(), dmg.y(), dmg.z()},
|
||||||
hp,
|
hp,
|
||||||
GameObject::DamageInfo::Physics,
|
impulse
|
||||||
impulse});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -164,7 +164,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct DamageInfo {
|
struct DamageInfo {
|
||||||
enum DamageType { Explosion, Burning, Bullet, Physics, Melee };
|
enum class DamageType {
|
||||||
|
Explosion, Burning, Bullet, Physics, Melee
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* World position of damage
|
* World position of damage
|
||||||
@ -190,6 +192,11 @@ public:
|
|||||||
* Physics impulse.
|
* Physics impulse.
|
||||||
*/
|
*/
|
||||||
float impulse;
|
float impulse;
|
||||||
|
|
||||||
|
DamageInfo(DamageType type, const glm::vec3 &location,
|
||||||
|
const glm::vec3 &source, float damage, float impulse = 0.f)
|
||||||
|
: damageLocation(location), damageSource(source), hitpoints(damage),
|
||||||
|
type(type), impulse(impulse) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual bool takeDamage(const DamageInfo& damage) {
|
virtual bool takeDamage(const DamageInfo& damage) {
|
||||||
|
@ -78,8 +78,9 @@ void ProjectileObject::explode() {
|
|||||||
float d = glm::distance(getPosition(), o->getPosition());
|
float d = glm::distance(getPosition(), o->getPosition());
|
||||||
if (d > damageSize) continue;
|
if (d > damageSize) continue;
|
||||||
|
|
||||||
o->takeDamage({getPosition(), getPosition(),
|
o->takeDamage({DamageInfo::DamageType::Explosion,
|
||||||
damage / glm::max(d, 1.f), DamageInfo::Explosion,
|
getPosition(), getPosition(),
|
||||||
|
damage / glm::max(d, 1.f),
|
||||||
0.f});
|
0.f});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,9 +207,13 @@ Menu DebugState::createAIMenu() {
|
|||||||
if (pedestrianPtr->getLifetime() == GameObject::PlayerLifetime) {
|
if (pedestrianPtr->getLifetime() == GameObject::PlayerLifetime) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
pedestrianPtr->takeDamage({pedestrianPtr->getPosition(),
|
pedestrianPtr->takeDamage(
|
||||||
|
{
|
||||||
|
GameObject::DamageInfo::DamageType::Explosion,
|
||||||
|
pedestrianPtr->getPosition(),
|
||||||
pedestrianPtr->getPosition(), 100.f,
|
pedestrianPtr->getPosition(), 100.f,
|
||||||
GameObject::DamageInfo::Explosion, 0.f});
|
0.f
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -129,9 +129,11 @@ BOOST_AUTO_TEST_CASE(test_death) {
|
|||||||
BOOST_CHECK_EQUAL(character->getCurrentState().health, 100.f);
|
BOOST_CHECK_EQUAL(character->getCurrentState().health, 100.f);
|
||||||
BOOST_CHECK(character->isAlive());
|
BOOST_CHECK(character->isAlive());
|
||||||
|
|
||||||
GameObject::DamageInfo dmg;
|
GameObject::DamageInfo dmg {
|
||||||
dmg.type = GameObject::DamageInfo::Bullet;
|
GameObject::DamageInfo::DamageType::Bullet,
|
||||||
dmg.hitpoints = character->getCurrentState().health + 1.f;
|
{}, {},
|
||||||
|
character->getCurrentState().health + 1.f
|
||||||
|
};
|
||||||
|
|
||||||
// Do some damage
|
// Do some damage
|
||||||
BOOST_CHECK(character->takeDamage(dmg));
|
BOOST_CHECK(character->takeDamage(dmg));
|
||||||
|
Loading…
Reference in New Issue
Block a user