From 87a04d9119c4cab81267823a87ee868d39a5b810 Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Sat, 28 Jun 2014 03:22:53 +0100 Subject: [PATCH] Added weapon scan for HITSCAN WeaponScans contain data required to affect objects in the world with weapon damage --- rwengine/include/data/WeaponData.hpp | 32 +++++++++++++++++++++++++++ rwengine/include/engine/GameWorld.hpp | 7 ++++++ rwengine/src/engine/GameWorld.cpp | 29 ++++++++++++++++++++++++ tests/test_weapon.cpp | 25 +++++++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 tests/test_weapon.cpp diff --git a/rwengine/include/data/WeaponData.hpp b/rwengine/include/data/WeaponData.hpp index cc1ff64c..7f6155d0 100644 --- a/rwengine/include/data/WeaponData.hpp +++ b/rwengine/include/data/WeaponData.hpp @@ -38,4 +38,36 @@ struct WeaponData std::uint32_t flags; }; +/** + * @brief The WeaponScan struct + * Represents a scene query against a ray + * or shape used to determine what to damage. + */ +struct WeaponScan +{ + enum ScanType { + HITSCAN, + RADIUS, + }; + + const ScanType type; + + float damage; + + glm::vec3 center; + float radius; + + glm::vec3 end; + + // Constructor for a RADIUS hitscan + WeaponScan( float damage, const glm::vec3& center, float radius ) + : type(RADIUS), damage(damage), center(center), radius(radius) + {} + + // Constructor for a ray hitscan + WeaponScan( float damage, const glm::vec3& start, const glm::vec3& end) + : type(HITSCAN), damage(damage), center(start), end(end) + {} +}; + #endif diff --git a/rwengine/include/engine/GameWorld.hpp b/rwengine/include/engine/GameWorld.hpp index e94a39b5..071a814b 100644 --- a/rwengine/include/engine/GameWorld.hpp +++ b/rwengine/include/engine/GameWorld.hpp @@ -15,6 +15,8 @@ class CharacterObject; class InstanceObject; class VehicleObject; +class WeaponScan; + #include #include @@ -106,6 +108,11 @@ public: * Destroys an existing Object */ void destroyObject(GameObject* object); + + /** + * Performs a weapon scan against things in the world + */ + void doWeaponScan( WeaponScan& scan ); /** * Returns the current hour diff --git a/rwengine/src/engine/GameWorld.cpp b/rwengine/src/engine/GameWorld.cpp index b109cff4..43fc9408 100644 --- a/rwengine/src/engine/GameWorld.cpp +++ b/rwengine/src/engine/GameWorld.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include // 3 isn't enough to cause a factory. @@ -401,6 +402,34 @@ void GameWorld::destroyObject(GameObject* object) delete object; } +void GameWorld::doWeaponScan(WeaponScan &scan) +{ + if( scan.type == WeaponScan::RADIUS ) { + // TODO + // Requires custom ConvexResultCallback + } + else if( scan.type == WeaponScan::HITSCAN ) { + btVector3 from(scan.center.x, scan.center.y, scan.center.z), + to(scan.end.x, scan.end.y, scan.end.z); + btCollisionWorld::ClosestRayResultCallback cb(from, to); + cb.m_collisionFilterGroup = btBroadphaseProxy::AllFilter; + dynamicsWorld->rayTest(from, to, cb); + // TODO: did any weapons penetrate? + + if( cb.hasHit() ) { + GameObject* go = static_cast(cb.m_collisionObject->getUserPointer()); + GameObject::DamageInfo di; + 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); + } + } +} + int GameWorld::getHour() { const float dayseconds = (24.f * 60.f); diff --git a/tests/test_weapon.cpp b/tests/test_weapon.cpp new file mode 100644 index 00000000..cb2176d6 --- /dev/null +++ b/tests/test_weapon.cpp @@ -0,0 +1,25 @@ +#include +#include "test_globals.hpp" +#include +#include + +BOOST_AUTO_TEST_SUITE(WeaponTests) + +BOOST_AUTO_TEST_CASE(TestWeaponScan) +{ + { + // Test RADIUS scan + auto character = Global::get().e->createPedestrian(1, {0.f, 0.f, 0.f}); + BOOST_REQUIRE( character != nullptr ); + BOOST_REQUIRE( character->model != nullptr); + BOOST_REQUIRE( character->physObject != nullptr); + + WeaponScan scan( 10.f, {0.f, 0.f, 10.f}, {0.f,0.f, -10.f} ); + + Global::get().e->doWeaponScan( scan ); + + BOOST_CHECK( character->mHealth < 100.f ); + } +} + +BOOST_AUTO_TEST_SUITE_END()