1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-22 02:12:45 +01:00

Added weapon scan for HITSCAN

WeaponScans contain data required to affect objects in the world with
weapon damage
This commit is contained in:
Daniel Evans 2014-06-28 03:22:53 +01:00
parent 3a3fb9aff4
commit 87a04d9119
4 changed files with 93 additions and 0 deletions

View File

@ -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

View File

@ -15,6 +15,8 @@ class CharacterObject;
class InstanceObject;
class VehicleObject;
class WeaponScan;
#include <glm/glm.hpp>
#include <btBulletDynamicsCommon.h>
@ -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

View File

@ -4,6 +4,7 @@
#include <ai/DefaultAIController.hpp>
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <render/Model.hpp>
#include <data/WeaponData.hpp>
#include <WorkContext.hpp>
// 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<GameObject*>(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);

25
tests/test_weapon.cpp Normal file
View File

@ -0,0 +1,25 @@
#include <boost/test/unit_test.hpp>
#include "test_globals.hpp"
#include <objects/CharacterObject.hpp>
#include <data/WeaponData.hpp>
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()