1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-25 03:42:48 +01:00

Added vehicle damage flags

This commit is contained in:
Daniel Evans 2014-03-01 04:12:35 +00:00
parent 687917c2fd
commit bd96b0b190
6 changed files with 120 additions and 15 deletions

View File

@ -10,6 +10,7 @@
class GTAAIController;
class Model;
class ModelFrame;
class Animator;
class GameWorld;
@ -84,7 +85,9 @@ struct GameObject
DamageType type;
};
virtual bool takeDamage(const DamageInfo& damage) { return false; };
virtual bool takeDamage(const DamageInfo& damage) { return false; }
virtual bool isFrameVisible(ModelFrame* frame) const { return true; }
};
#endif // __GAMEOBJECTS_HPP__

View File

@ -12,11 +12,30 @@
*/
struct GTAVehicle : public GameObject
{
public:
enum /*DamageFlags*/ {
DF_Bonnet = 1,
DF_Door_lf = 2,
DF_Door_rf = 4,
DF_Door_lr = 8,
DF_Door_rr = 16,
DF_Boot = 32,
DF_Windscreen = 64,
DF_Bump_front = 128,
DF_Bump_rear = 256,
DF_Wing_lf = 512,
DF_Wing_rf = 1024,
DF_Wing_lr = 2048,
DF_Wing_rr = 4096,
};
private:
float steerAngle;
float throttle;
float brake;
bool handbrake;
unsigned int damageFlags;
public:
VehicleDataHandle vehicle;
@ -74,6 +93,10 @@ public:
void setOccupant(size_t seat, GameObject* occupant);
virtual bool takeDamage(const DamageInfo& damage);
void setPartDamaged(unsigned int flag, bool damaged);
virtual bool isFrameVisible(ModelFrame *frame) const;
};
#endif

View File

@ -5,6 +5,7 @@
#include <vector>
#include <string>
#include <memory>
#include <algorithm>
#include <GL/glew.h>
#include <loaders/rwbinarystream.h>
@ -148,6 +149,13 @@ public:
std::vector<Atomic> atomics;
int32_t rootFrameIdx;
ModelFrame* findFrame(const std::string& name) const {
auto fit = std::find_if(
frames.begin(), frames.end(),
[&](ModelFrame* f) { return f->getName() == name; });
return fit != frames.end() ? *fit : nullptr;
}
};
#endif
#endif

View File

@ -4,12 +4,13 @@
#include <BulletDynamics/Vehicle/btRaycastVehicle.h>
#include <sys/stat.h>
#include <data/CollisionModel.hpp>
#include <render/Model.hpp>
GTAVehicle::GTAVehicle(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, Model* model, VehicleDataHandle data, VehicleInfoHandle info, const glm::vec3& prim, const glm::vec3& sec)
: GameObject(engine, pos, rot, model),
steerAngle(0.f), throttle(0.f), brake(0.f), handbrake(false),
vehicle(data), info(info), colourPrimary(prim), colourSecondary(sec),
physBody(nullptr), physVehicle(nullptr)
damageFlags(0), vehicle(data), info(info), colourPrimary(prim),
colourSecondary(sec), physBody(nullptr), physVehicle(nullptr)
{
mHealth = 100.f;
if(! data->modelName.empty()) {
@ -247,3 +248,52 @@ bool GTAVehicle::takeDamage(const GameObject::DamageInfo& dmg)
mHealth -= dmg.hitpoints;
return true;
}
void GTAVehicle::setPartDamaged(unsigned int flag, bool damaged)
{
if(damaged) {
damageFlags |= flag;
}
else {
damageFlags = damageFlags & ~flag;
}
}
unsigned int nameToDamageFlag(const std::string& name)
{
if(name.find("bonnet") != name.npos) return GTAVehicle::DF_Bonnet;
if(name.find("door_lf") != name.npos) return GTAVehicle::DF_Door_lf;
if(name.find("door_rf") != name.npos) return GTAVehicle::DF_Door_rf;
if(name.find("door_lr") != name.npos) return GTAVehicle::DF_Door_lr;
if(name.find("door_rr") != name.npos) return GTAVehicle::DF_Door_rr;
if(name.find("boot") != name.npos) return GTAVehicle::DF_Boot;
if(name.find("windscreen") != name.npos) return GTAVehicle::DF_Windscreen;
if(name.find("bump_front") != name.npos) return GTAVehicle::DF_Bump_front;
if(name.find("bump_rear") != name.npos) return GTAVehicle::DF_Bump_rear;
if(name.find("wing_lf") != name.npos) return GTAVehicle::DF_Wing_lf;
if(name.find("wing_rf") != name.npos) return GTAVehicle::DF_Wing_rf;
if(name.find("wing_lr") != name.npos) return GTAVehicle::DF_Wing_lr;
if(name.find("wing_rr") != name.npos) return GTAVehicle::DF_Wing_rr;
return 0;
}
bool GTAVehicle::isFrameVisible(ModelFrame *frame) const
{
auto& name = frame->getName();
bool isDam = name.find("_dam") != name.npos;
bool isOk = name.find("_ok") != name.npos;
if(name.find("lo") != name.npos
|| name.find("_dummy") != name.npos) return false;
if(isDam || isOk) {
unsigned int dft = nameToDamageFlag(name);
if(isDam) {
return (damageFlags & dft) == dft;
}
else {
return (damageFlags & dft) == 0;
}
}
return true;
}

View File

@ -445,23 +445,15 @@ void GTARenderer::renderGeometry(Model* model, size_t g, const glm::mat4& modelM
bool GTARenderer::renderFrame(Model* m, ModelFrame* f, const glm::mat4& matrix, GameObject* object, bool queueTransparent)
{
auto localmatrix = matrix * f->getMatrix();
bool vis = object == nullptr || object->isFrameVisible(f);
for(size_t g : f->getGeometries()) {
if(!vis ) continue;
RW::BSGeometryBounds& bounds = m->geometries[g]->geometryBounds;
if(! camera.frustum.intersects(bounds.center + glm::vec3(matrix[3]), bounds.radius)) {
continue;
}
if( object && object->type() == GameObject::Vehicle ) {
auto& name = f->getName();
if(name.size() > 3) {
if(name.substr(name.size()-3) == "dam"
|| name.find("lo") != name.npos
|| name.find("dummy") != name.npos) {
continue;
}
}
}
if( (m->geometries[g]->flags & RW::BSGeometry::ModuleMaterialColor) != RW::BSGeometry::ModuleMaterialColor) {
glUniform4f(uniCol, 1.f, 1.f, 1.f, 1.f);
}

View File

@ -1,6 +1,7 @@
#include <boost/test/unit_test.hpp>
#include "test_globals.hpp"
#include <objects/GTAVehicle.hpp>
#include <render/Model.hpp>
BOOST_AUTO_TEST_SUITE(VehicleTests)
@ -21,5 +22,33 @@ BOOST_AUTO_TEST_CASE(test_create_vehicle)
BOOST_CHECK_EQUAL(vehicle->info->seats.size(), 4);
}
BOOST_AUTO_TEST_CASE(vehicle_frame_flags)
{
GTAVehicle* vehicle = Global::get().e->createVehicle(90u, glm::vec3(), glm::quat());
BOOST_REQUIRE(vehicle != nullptr);
BOOST_REQUIRE(vehicle->model != nullptr);
auto bonnet_ok = vehicle->model->findFrame("bonnet_hi_ok");
auto bonnet_dam = vehicle->model->findFrame("bonnet_hi_dam");
BOOST_REQUIRE(bonnet_ok != nullptr);
BOOST_REQUIRE(bonnet_dam != nullptr);
BOOST_CHECK(vehicle->isFrameVisible(bonnet_ok));
BOOST_CHECK(!vehicle->isFrameVisible(bonnet_dam));
vehicle->setPartDamaged(GTAVehicle::DF_Bonnet, true);
BOOST_CHECK(!vehicle->isFrameVisible(bonnet_ok));
BOOST_CHECK(vehicle->isFrameVisible(bonnet_dam));
vehicle->setPartDamaged(GTAVehicle::DF_Bonnet, false);
BOOST_CHECK(vehicle->isFrameVisible(bonnet_ok));
BOOST_CHECK(!vehicle->isFrameVisible(bonnet_dam));
}
BOOST_AUTO_TEST_SUITE_END()