1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-22 18:32:44 +01:00

clang-format files in rwengine/src/objects

This commit is contained in:
Daniel Evans 2016-09-09 21:13:19 +01:00
parent 305737cc3d
commit f2eede5301
17 changed files with 2297 additions and 2360 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,12 @@
#pragma once
#ifndef _CHARACTEROBJECT_HPP_
#define _CHARACTEROBJECT_HPP_
#include <objects/GameObject.hpp>
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <BulletDynamics/Character/btKinematicCharacterController.h>
#include <btBulletCollisionCommon.h>
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <glm/glm.hpp>
#include <array>
#include <glm/glm.hpp>
#include <objects/GameObject.hpp>
constexpr int maxInventorySlots = 13;
@ -14,215 +14,241 @@ constexpr int maxInventorySlots = 13;
constexpr unsigned int AnimIndexMovement = 0;
constexpr unsigned int AnimIndexAction = 1;
struct CharacterWeaponSlot
{
// Assuming these match the entries in weapon.dat
uint32_t weaponId;
uint32_t bulletsClip;
uint32_t bulletsTotal;
struct CharacterWeaponSlot {
// Assuming these match the entries in weapon.dat
uint32_t weaponId;
uint32_t bulletsClip;
uint32_t bulletsTotal;
};
struct CharacterState
{
glm::vec3 position;
float rotation;
float health = 100.f;
float armour = 0.f;
std::array<CharacterWeaponSlot, maxInventorySlots> weapons;
uint16_t currentWeapon = 0;
uint32_t lastFireTimeMS = 0;
bool primaryActive = false;
bool secondaryActive = false;
uint32_t primaryStartTime = 0;
uint32_t primaryEndTime = 0;
struct CharacterState {
glm::vec3 position;
float rotation;
float health = 100.f;
float armour = 0.f;
std::array<CharacterWeaponSlot, maxInventorySlots> weapons;
uint16_t currentWeapon = 0;
uint32_t lastFireTimeMS = 0;
bool primaryActive = false;
bool secondaryActive = false;
uint32_t primaryStartTime = 0;
uint32_t primaryEndTime = 0;
};
class VehicleObject;
class GameWorld;
class InventoryItem;
struct AnimationGroup
{
Animation* idle;
Animation* walk;
Animation* walk_start;
Animation* run;
Animation* sprint;
struct AnimationGroup {
Animation* idle;
Animation* walk;
Animation* walk_start;
Animation* run;
Animation* sprint;
Animation* walk_right;
Animation* walk_right_start;
Animation* walk_left;
Animation* walk_left_start;
Animation* walk_right;
Animation* walk_right_start;
Animation* walk_left;
Animation* walk_left_start;
Animation* walk_back;
Animation* walk_back_start;
Animation* walk_back;
Animation* walk_back_start;
Animation* jump_start;
Animation* jump_glide;
Animation* jump_land;
Animation* jump_start;
Animation* jump_glide;
Animation* jump_land;
Animation* car_sit;
Animation* car_sit_low;
Animation* car_sit;
Animation* car_sit_low;
Animation* car_open_lhs;
Animation* car_getin_lhs;
Animation* car_getout_lhs;
Animation* car_jacked_lhs;
Animation* car_pullout_lhs;
Animation* car_open_lhs;
Animation* car_getin_lhs;
Animation* car_getout_lhs;
Animation* car_jacked_lhs;
Animation* car_pullout_lhs;
Animation* car_open_rhs;
Animation* car_getin_rhs;
Animation* car_getout_rhs;
Animation* car_jacked_rhs;
Animation* car_pullout_rhs;
Animation* car_open_rhs;
Animation* car_getin_rhs;
Animation* car_getout_rhs;
Animation* car_jacked_rhs;
Animation* car_pullout_rhs;
Animation* kd_front;
Animation* ko_shot_front;
Animation* kd_front;
Animation* ko_shot_front;
AnimationGroup()
: idle(nullptr), walk(nullptr), walk_start(nullptr), run(nullptr),
jump_start(nullptr), jump_glide(nullptr), jump_land(nullptr),
car_sit(nullptr), car_sit_low(nullptr), car_open_lhs(nullptr),
car_getin_lhs(nullptr), car_getout_lhs(nullptr), car_open_rhs(nullptr),
car_getin_rhs(nullptr)
, car_getout_rhs(nullptr)
, kd_front(nullptr)
, ko_shot_front(nullptr)
{}
AnimationGroup()
: idle(nullptr)
, walk(nullptr)
, walk_start(nullptr)
, run(nullptr)
, jump_start(nullptr)
, jump_glide(nullptr)
, jump_land(nullptr)
, car_sit(nullptr)
, car_sit_low(nullptr)
, car_open_lhs(nullptr)
, car_getin_lhs(nullptr)
, car_getout_lhs(nullptr)
, car_open_rhs(nullptr)
, car_getin_rhs(nullptr)
, car_getout_rhs(nullptr)
, kd_front(nullptr)
, ko_shot_front(nullptr) {
}
};
/**
* @brief The CharacterObject struct
* Implements Character object behaviours.
*/
class CharacterObject : public GameObject
{
class CharacterObject : public GameObject {
private:
CharacterState currentState;
CharacterState currentState;
VehicleObject* currentVehicle;
size_t currentSeat;
VehicleObject* currentVehicle;
size_t currentSeat;
void createActor(const glm::vec2& size = glm::vec2(0.45f, 1.2f));
void destroyActor();
void createActor(const glm::vec2& size = glm::vec2(0.45f, 1.2f));
void destroyActor();
glm::vec3 movement;
glm::vec2 m_look;
glm::vec3 movement;
glm::vec2 m_look;
bool running;
bool jumped;
float jumpSpeed;
bool running;
bool jumped;
float jumpSpeed;
bool motionBlockedByActivity;
bool motionBlockedByActivity;
glm::vec3 updateMovementAnimation(float dt);
glm::vec3 updateMovementAnimation(float dt);
public:
static const float DefaultJumpSpeed;
static const float DefaultJumpSpeed;
std::shared_ptr<CharacterData> ped;
std::shared_ptr<CharacterData> ped;
btKinematicCharacterController* physCharacter;
btPairCachingGhostObject* physObject;
btCapsuleShapeZ* physShape;
btKinematicCharacterController* physCharacter;
btPairCachingGhostObject* physObject;
btCapsuleShapeZ* physShape;
CharacterController* controller;
CharacterController* controller;
AnimationGroup animations;
AnimationGroup animations;
/**
* @param pos
* @param rot
* @param model
* @param ped PEDS_t struct to use.
*/
CharacterObject(GameWorld* engine, const glm::vec3& pos,
const glm::quat& rot, const ModelRef& model,
std::shared_ptr<CharacterData> data);
/**
* @param pos
* @param rot
* @param model
* @param ped PEDS_t struct to use.
*/
CharacterObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, const ModelRef& model, std::shared_ptr< CharacterData > data);
~CharacterObject();
~CharacterObject();
Type type() {
return Character;
}
Type type() { return Character; }
void tick(float dt);
void tick(float dt);
const CharacterState& getCurrentState() const {
return currentState;
}
CharacterState& getCurrentState() {
return currentState;
}
const CharacterState& getCurrentState() const { return currentState; }
CharacterState& getCurrentState(){ return currentState; }
/**
* @brief Loads the model and texture for a character skin.
*/
void changeCharacterModel(const std::string& name);
/**
* @brief Loads the model and texture for a character skin.
*/
void changeCharacterModel(const std::string& name);
/**
* @brief updateCharacter updates internall bullet Character.
*/
void updateCharacter(float dt);
/**
* @brief updateCharacter updates internall bullet Character.
*/
void updateCharacter(float dt);
virtual void setPosition(const glm::vec3& pos);
virtual void setPosition(const glm::vec3& pos);
bool isAlive() const;
bool takeDamage(const DamageInfo& damage) override;
bool isAlive() const;
bool takeDamage(const DamageInfo& damage) override;
bool enterVehicle(VehicleObject* vehicle, size_t seat);
bool enterVehicle(VehicleObject* vehicle, size_t seat);
bool isEnteringOrExitingVehicle() const;
bool isEnteringOrExitingVehicle() const;
/**
* @brief isStopped
* @return True if the character isn't moving
*/
bool isStopped() const;
/**
* @brief isStopped
* @return True if the character isn't moving
*/
bool isStopped() const;
VehicleObject* getCurrentVehicle() const;
size_t getCurrentSeat() const;
void setCurrentVehicle(VehicleObject* value, size_t seat);
VehicleObject *getCurrentVehicle() const;
size_t getCurrentSeat() const;
void setCurrentVehicle(VehicleObject *value, size_t seat);
void jump();
void setJumpSpeed(float speed);
float getJumpSpeed() const;
bool isOnGround() const;
bool canTurn() const;
void jump();
void setJumpSpeed(float speed);
float getJumpSpeed() const;
bool isOnGround() const;
bool canTurn() const;
void setRunning(bool run) { running = run; }
bool isRunning() const { return running; }
/**
* Resets the Actor to the nearest AI Graph node
* (taking into account the current vehicle)
*/
void resetToAINode();
void setRunning(bool run) {
running = run;
}
bool isRunning() const {
return running;
}
void setMovement(const glm::vec3& _m) { movement = _m; }
const glm::vec3& getMovement() const { return movement; }
void setLook(const glm::vec2& look) { m_look = look; }
const glm::vec2& getLook() const { return m_look; }
/**
* Resets the Actor to the nearest AI Graph node
* (taking into account the current vehicle)
*/
void resetToAINode();
/**
* @brief playActivityAnimation Plays an animation for an activity.
* @param animation The animation to play
* @param repeat
* @param blocking Wether movement is still alowed
*
* This allows controller activities to play their own animations and
* controll blending with movement.
*/
void playActivityAnimation(Animation* animation, bool repeat, bool blocking);
/**
* @brief activityFinished removes activity animation
*/
void activityFinished();
void setMovement(const glm::vec3& _m) {
movement = _m;
}
const glm::vec3& getMovement() const {
return movement;
}
void setLook(const glm::vec2& look) {
m_look = look;
}
const glm::vec2& getLook() const {
return m_look;
}
void addToInventory( InventoryItem* item );
void setActiveItem( int slot );
InventoryItem* getActiveItem();
void removeFromInventory( int slot );
/**
* @brief playActivityAnimation Plays an animation for an activity.
* @param animation The animation to play
* @param repeat
* @param blocking Wether movement is still alowed
*
* This allows controller activities to play their own animations and
* controll blending with movement.
*/
void playActivityAnimation(Animation* animation, bool repeat,
bool blocking);
/**
* @brief activityFinished removes activity animation
*/
void activityFinished();
/**
* Uses the character's active item.
* @param primary use the primary action.
*/
void useItem(bool active, bool primary = true);
void addToInventory(InventoryItem* item);
void setActiveItem(int slot);
InventoryItem* getActiveItem();
void removeFromInventory(int slot);
void cycleInventory( bool up );
/**
* Uses the character's active item.
* @param primary use the primary action.
*/
void useItem(bool active, bool primary = true);
void cycleInventory(bool up);
};
#endif

View File

@ -1,27 +1,22 @@
#include <objects/CutsceneObject.hpp>
#include <engine/Animator.hpp>
#include <data/Skeleton.hpp>
#include <engine/Animator.hpp>
#include <objects/CutsceneObject.hpp>
CutsceneObject::CutsceneObject(GameWorld *engine, const glm::vec3 &pos, const glm::quat& rot, const ModelRef& model)
: GameObject(engine, pos, rot, model)
, _parent(nullptr)
, _bone(nullptr)
{
skeleton = new Skeleton;
animator = new Animator(model->resource, skeleton);
CutsceneObject::CutsceneObject(GameWorld *engine, const glm::vec3 &pos,
const glm::quat &rot, const ModelRef &model)
: GameObject(engine, pos, rot, model), _parent(nullptr), _bone(nullptr) {
skeleton = new Skeleton;
animator = new Animator(model->resource, skeleton);
}
CutsceneObject::~CutsceneObject()
{
CutsceneObject::~CutsceneObject() {
}
void CutsceneObject::tick(float dt)
{
animator->tick(dt);
void CutsceneObject::tick(float dt) {
animator->tick(dt);
}
void CutsceneObject::setParentActor(GameObject *parent, ModelFrame *bone)
{
_parent = parent;
_bone = bone;
void CutsceneObject::setParentActor(GameObject *parent, ModelFrame *bone) {
_parent = parent;
_bone = bone;
}

View File

@ -6,31 +6,30 @@
/**
* @brief Object type used for cutscene animations.
*/
class CutsceneObject : public GameObject
{
GameObject* _parent;
ModelFrame* _bone;
class CutsceneObject : public GameObject {
GameObject* _parent;
ModelFrame* _bone;
public:
CutsceneObject(GameWorld* engine, const glm::vec3& pos,
const glm::quat& rot, const ModelRef& model);
~CutsceneObject();
CutsceneObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, const ModelRef& model);
~CutsceneObject();
Type type() {
return Cutscene;
}
Type type() { return Cutscene; }
void tick(float dt);
void tick(float dt);
void setParentActor(GameObject* parent, ModelFrame* bone);
void setParentActor(GameObject* parent, ModelFrame* bone);
GameObject* getParentActor() const {
return _parent;
}
GameObject* getParentActor() const
{
return _parent;
}
ModelFrame* getParentFrame() const
{
return _bone;
}
ModelFrame* getParentFrame() const {
return _bone;
}
};
#endif

View File

@ -1,42 +1,34 @@
#include <objects/GameObject.hpp>
#include <loaders/LoaderIFP.hpp>
#include <loaders/LoaderDFF.hpp>
#include <engine/Animator.hpp>
#include <data/Skeleton.hpp>
#include <engine/Animator.hpp>
#include <glm/gtc/quaternion.hpp>
#include <loaders/LoaderDFF.hpp>
#include <loaders/LoaderIFP.hpp>
#include <objects/GameObject.hpp>
GameObject::~GameObject()
{
if(animator)
{
delete animator;
}
if(skeleton)
{
delete skeleton;
}
GameObject::~GameObject() {
if (animator) {
delete animator;
}
if (skeleton) {
delete skeleton;
}
}
void GameObject::setPosition(const glm::vec3& pos)
{
_lastPosition = position = pos;
void GameObject::setPosition(const glm::vec3& pos) {
_lastPosition = position = pos;
}
void GameObject::setRotation(const glm::quat& orientation)
{
rotation = orientation;
void GameObject::setRotation(const glm::quat& orientation) {
rotation = orientation;
}
float GameObject::getHeading() const
{
auto hdg = glm::roll(getRotation());
return hdg / glm::pi<float>() * 180.f;
float GameObject::getHeading() const {
auto hdg = glm::roll(getRotation());
return hdg / glm::pi<float>() * 180.f;
}
void GameObject::setHeading(float heading)
{
auto hdg = (heading / 180.f) * glm::pi<float>();
auto quat = glm::normalize(glm::quat(glm::vec3(0.f, 0.f, hdg)));
setRotation(quat);
void GameObject::setHeading(float heading) {
auto hdg = (heading / 180.f) * glm::pi<float>();
auto quat = glm::normalize(glm::quat(glm::vec3(0.f, 0.f, hdg)));
setRotation(quat);
}

View File

@ -2,14 +2,14 @@
#ifndef _GAMEOBJECT_HPP_
#define _GAMEOBJECT_HPP_
#include <rw/types.hpp>
#include <objects/ObjectTypes.hpp>
#include <data/Model.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/quaternion.hpp>
#include <loaders/LoaderIDE.hpp>
#include <loaders/LoaderIPL.hpp>
#include <data/Model.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <memory>
#include <objects/ObjectTypes.hpp>
#include <rw/types.hpp>
class Skeleton;
class CharacterController;
@ -23,181 +23,195 @@ class GameWorld;
* Contains handle to the world, and other useful properties like water level
* tracking used to make tunnels work.
*/
class GameObject
{
glm::vec3 _lastPosition;
glm::quat _lastRotation;
GameObjectID objectID;
class GameObject {
glm::vec3 _lastPosition;
glm::quat _lastRotation;
GameObjectID objectID;
public:
glm::vec3 position;
glm::quat rotation;
/// Reference to Model data
ModelRef model;
/// Reference to Model data
ModelRef model;
GameWorld* engine;
Animator* animator; /// Object's animator.
Skeleton* skeleton;
Animator* animator; /// Object's animator.
Skeleton* skeleton;
bool inWater;
bool inWater;
/**
* @brief stores the height of water at the last tick
*/
float _lastHeight;
/**
* Should object be rendered?
*/
bool visible;
/**
* @brief stores the height of water at the last tick
*/
float _lastHeight;
GameObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, ModelRef model)
: _lastPosition(pos)
, _lastRotation(rot)
, objectID(0)
, position(pos)
, rotation(rot)
, model(model)
, engine(engine)
, animator(nullptr)
, skeleton(nullptr)
, inWater(false)
, _lastHeight(std::numeric_limits<float>::max())
, visible(true)
, lifetime(GameObject::UnknownLifetime)
{}
virtual ~GameObject();
/**
* Should object be rendered?
*/
bool visible;
GameObjectID getGameObjectID() const { return objectID; }
/**
* Do not call this, use GameWorld::insertObject
*/
void setGameObjectID(GameObjectID id) { objectID = id; }
GameObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot,
ModelRef model)
: _lastPosition(pos)
, _lastRotation(rot)
, objectID(0)
, position(pos)
, rotation(rot)
, model(model)
, engine(engine)
, animator(nullptr)
, skeleton(nullptr)
, inWater(false)
, _lastHeight(std::numeric_limits<float>::max())
, visible(true)
, lifetime(GameObject::UnknownLifetime) {
}
int getScriptObjectID() const { return getGameObjectID(); }
virtual ~GameObject();
/**
* @brief Enumeration of possible object types.
*/
enum Type
{
Instance,
Character,
Vehicle,
Pickup,
Projectile,
Cutscene,
Unknown
GameObjectID getGameObjectID() const {
return objectID;
}
/**
* Do not call this, use GameWorld::insertObject
*/
void setGameObjectID(GameObjectID id) {
objectID = id;
}
int getScriptObjectID() const {
return getGameObjectID();
}
/**
* @brief Enumeration of possible object types.
*/
enum Type {
Instance,
Character,
Vehicle,
Pickup,
Projectile,
Cutscene,
Unknown
};
/**
* @brief determines what type of object this is.
* @return one of Type
*/
virtual Type type() { return Unknown; }
virtual void setPosition(const glm::vec3& pos);
/**
* @brief determines what type of object this is.
* @return one of Type
*/
virtual Type type() {
return Unknown;
}
const glm::vec3& getPosition() const { return position; }
const glm::vec3& getLastPosition() const { return _lastPosition; }
virtual void setPosition(const glm::vec3& pos);
const glm::quat& getRotation() const { return rotation; }
virtual void setRotation(const glm::quat &orientation);
const glm::vec3& getPosition() const {
return position;
}
const glm::vec3& getLastPosition() const {
return _lastPosition;
}
float getHeading() const;
/**
* @brief setHeading Rotates the object to face heading, in degrees.
*/
void setHeading(float heading);
const glm::quat& getRotation() const {
return rotation;
}
virtual void setRotation(const glm::quat& orientation);
struct DamageInfo
{
enum DamageType
{
Explosion,
Burning,
Bullet,
Physics
};
/**
* World position of damage
*/
glm::vec3 damageLocation;
/**
* World position of the source (used for direction)
*/
glm::vec3 damageSource;
/**
* Magnitude of destruction
*/
float hitpoints;
/**
* Type of the damage
*/
DamageType type;
float getHeading() const;
/**
* @brief setHeading Rotates the object to face heading, in degrees.
*/
void setHeading(float heading);
/**
* Physics impulse.
*/
float impulse;
};
virtual bool takeDamage(const DamageInfo& /*damage*/) { return false; }
struct DamageInfo {
enum DamageType { Explosion, Burning, Bullet, Physics };
virtual bool isAnimationFixed() const { return true; }
/**
* World position of damage
*/
glm::vec3 damageLocation;
virtual bool isInWater() const { return inWater; }
/**
* World position of the source (used for direction)
*/
glm::vec3 damageSource;
virtual void tick(float dt) = 0;
/**
* Magnitude of destruction
*/
float hitpoints;
/**
* @brief Function used to modify the last transform
* @param newPos
*/
void _updateLastTransform()
{
_lastPosition = getPosition();
_lastRotation = getRotation();
}
/**
* Type of the damage
*/
DamageType type;
glm::mat4 getTimeAdjustedTransform(float alpha) const {
glm::mat4 t;
t = glm::translate(t, glm::mix(_lastPosition, getPosition(), alpha));
t = t * glm::mat4_cast(glm::slerp(_lastRotation, getRotation(), alpha));
return t;
}
enum ObjectLifetime
{
/// lifetime has not been set
UnknownLifetime,
/// Generic background pedestrians
TrafficLifetime,
/// Part of a mission
MissionLifetime,
/// Is owned by the player (or is the player)
PlayerLifetime
};
void setLifetime(ObjectLifetime ol) { lifetime = ol; }
ObjectLifetime getLifetime() const { return lifetime; }
/**
* Physics impulse.
*/
float impulse;
};
void updateTransform(const glm::vec3& pos, const glm::quat& rot)
{
_lastPosition = position;
_lastRotation = rotation;
position = pos;
rotation = rot;
}
virtual bool takeDamage(const DamageInfo& /*damage*/) {
return false;
}
virtual bool isAnimationFixed() const {
return true;
}
virtual bool isInWater() const {
return inWater;
}
virtual void tick(float dt) = 0;
/**
* @brief Function used to modify the last transform
* @param newPos
*/
void _updateLastTransform() {
_lastPosition = getPosition();
_lastRotation = getRotation();
}
glm::mat4 getTimeAdjustedTransform(float alpha) const {
glm::mat4 t;
t = glm::translate(t, glm::mix(_lastPosition, getPosition(), alpha));
t = t * glm::mat4_cast(glm::slerp(_lastRotation, getRotation(), alpha));
return t;
}
enum ObjectLifetime {
/// lifetime has not been set
UnknownLifetime,
/// Generic background pedestrians
TrafficLifetime,
/// Part of a mission
MissionLifetime,
/// Is owned by the player (or is the player)
PlayerLifetime
};
void setLifetime(ObjectLifetime ol) {
lifetime = ol;
}
ObjectLifetime getLifetime() const {
return lifetime;
}
void updateTransform(const glm::vec3& pos, const glm::quat& rot) {
_lastPosition = position;
_lastRotation = rotation;
position = pos;
rotation = rot;
}
private:
ObjectLifetime lifetime;
ObjectLifetime lifetime;
};
#endif // __GAMEOBJECTS_HPP__
#endif // __GAMEOBJECTS_HPP__

View File

@ -1,177 +1,180 @@
#include <objects/InstanceObject.hpp>
#include <engine/GameWorld.hpp>
#include <data/CollisionModel.hpp>
#include <dynamics/CollisionInstance.hpp>
#include <engine/Animator.hpp>
#include <engine/GameData.hpp>
#include <engine/GameWorld.hpp>
#include <objects/InstanceObject.hpp>
InstanceObject::InstanceObject(GameWorld* engine,
const glm::vec3& pos,
const glm::quat& rot,
const ModelRef& model,
const glm::vec3& scale,
std::shared_ptr<ObjectData> obj,
InstanceObject* lod,
std::shared_ptr<DynamicObjectData> dyn)
: GameObject(engine, pos, rot, model)
, health(100.f)
, scale(scale)
, body(nullptr)
, object(obj)
, LODinstance(lod)
, dynamics(dyn)
, _enablePhysics(false)
{
if( obj ) {
changeModel(obj);
for( auto& path : obj->paths )
{
engine->aigraph.createPathNodes(position, rot, path);
}
}
InstanceObject::InstanceObject(GameWorld* engine, const glm::vec3& pos,
const glm::quat& rot, const ModelRef& model,
const glm::vec3& scale,
std::shared_ptr<ObjectData> obj,
InstanceObject* lod,
std::shared_ptr<DynamicObjectData> dyn)
: GameObject(engine, pos, rot, model)
, health(100.f)
, scale(scale)
, body(nullptr)
, object(obj)
, LODinstance(lod)
, dynamics(dyn)
, _enablePhysics(false) {
if (obj) {
changeModel(obj);
for (auto& path : obj->paths) {
engine->aigraph.createPathNodes(position, rot, path);
}
}
}
InstanceObject::~InstanceObject()
{
if( body ) {
delete body;
}
InstanceObject::~InstanceObject() {
if (body) {
delete body;
}
}
void InstanceObject::tick(float dt)
{
if( dynamics && body ) {
if( _enablePhysics ) {
if( body->getBulletBody()->isStaticObject() ) {
// Apparently bodies must be removed and re-added if their mass changes.
body->changeMass(dynamics->mass);
}
}
void InstanceObject::tick(float dt) {
if (dynamics && body) {
if (_enablePhysics) {
if (body->getBulletBody()->isStaticObject()) {
// Apparently bodies must be removed and re-added if their mass
// changes.
body->changeMass(dynamics->mass);
}
}
const glm::vec3& ws = getPosition();
auto wX = (int) ((ws.x + WATER_WORLD_SIZE/2.f) / (WATER_WORLD_SIZE/WATER_HQ_DATA_SIZE));
auto wY = (int) ((ws.y + WATER_WORLD_SIZE/2.f) / (WATER_WORLD_SIZE/WATER_HQ_DATA_SIZE));
float vH = ws.z;// - _collisionHeight/2.f;
float wH = 0.f;
const glm::vec3& ws = getPosition();
auto wX = (int)((ws.x + WATER_WORLD_SIZE / 2.f) /
(WATER_WORLD_SIZE / WATER_HQ_DATA_SIZE));
auto wY = (int)((ws.y + WATER_WORLD_SIZE / 2.f) /
(WATER_WORLD_SIZE / WATER_HQ_DATA_SIZE));
float vH = ws.z; // - _collisionHeight/2.f;
float wH = 0.f;
if( wX >= 0 && wX < WATER_HQ_DATA_SIZE && wY >= 0 && wY < WATER_HQ_DATA_SIZE ) {
int i = (wX*WATER_HQ_DATA_SIZE) + wY;
int hI = engine->data->realWater[i];
if( hI < NO_WATER_INDEX ) {
wH = engine->data->waterHeights[hI];
wH += engine->data->getWaveHeightAt(ws);
if( vH <= wH ) {
inWater = true;
}
else {
inWater = false;
}
}
else {
inWater = false;
}
}
_lastHeight = ws.z;
if (wX >= 0 && wX < WATER_HQ_DATA_SIZE && wY >= 0 &&
wY < WATER_HQ_DATA_SIZE) {
int i = (wX * WATER_HQ_DATA_SIZE) + wY;
int hI = engine->data->realWater[i];
if (hI < NO_WATER_INDEX) {
wH = engine->data->waterHeights[hI];
wH += engine->data->getWaveHeightAt(ws);
if (vH <= wH) {
inWater = true;
} else {
inWater = false;
}
} else {
inWater = false;
}
}
_lastHeight = ws.z;
if( inWater ) {
float oZ = -(body->getBoundingHeight() * (dynamics->bouancy/100.f));
body->getBulletBody()->activate(true);
// Damper motion
body->getBulletBody()->setDamping(0.95f, 0.9f);
if (inWater) {
float oZ =
-(body->getBoundingHeight() * (dynamics->bouancy / 100.f));
body->getBulletBody()->activate(true);
// Damper motion
body->getBulletBody()->setDamping(0.95f, 0.9f);
auto wi = engine->data->getWaterIndexAt(ws);
if(wi != NO_WATER_INDEX) {
float h = engine->data->waterHeights[wi] + oZ;
auto wi = engine->data->getWaterIndexAt(ws);
if (wi != NO_WATER_INDEX) {
float h = engine->data->waterHeights[wi] + oZ;
// Calculate wave height
h += engine->data->getWaveHeightAt(ws);
// Calculate wave height
h += engine->data->getWaveHeightAt(ws);
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);
}*/
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 F = WATER_BUOYANCY_K * x + -WATER_BUOYANCY_C * body->getBulletBody()->getLinearVelocity().z();
btVector3 forcePos = btVector3(0.f, 0.f, 2.f).rotate(
body->getBulletBody()->getOrientation().getAxis(), body->getBulletBody()->getOrientation().getAngle());
body->getBulletBody()->applyForce(btVector3(0.f, 0.f, F),
forcePos);
}
}
}
}
float x = (h - ws.z);
float F =
WATER_BUOYANCY_K * x +
-WATER_BUOYANCY_C *
body->getBulletBody()->getLinearVelocity().z();
btVector3 forcePos = btVector3(0.f, 0.f, 2.f)
.rotate(body->getBulletBody()
->getOrientation()
.getAxis(),
body->getBulletBody()
->getOrientation()
.getAngle());
body->getBulletBody()->applyForce(btVector3(0.f, 0.f, F),
forcePos);
}
}
}
}
if( animator ) animator->tick(dt);
if (animator) animator->tick(dt);
}
void InstanceObject::changeModel(std::shared_ptr<ObjectData> incoming)
{
if( body ) {
delete body;
body = nullptr;
}
void InstanceObject::changeModel(std::shared_ptr<ObjectData> incoming) {
if (body) {
delete body;
body = nullptr;
}
object = incoming;
object = incoming;
if( incoming ) {
auto bod = new CollisionInstance;
if (incoming) {
auto bod = new CollisionInstance;
if( bod->createPhysicsBody(this, object->modelName, dynamics.get()) )
{
bod->getBulletBody()->setActivationState(ISLAND_SLEEPING);
body = bod;
}
}
if (bod->createPhysicsBody(this, object->modelName, dynamics.get())) {
bod->getBulletBody()->setActivationState(ISLAND_SLEEPING);
body = bod;
}
}
}
void InstanceObject::setRotation(const glm::quat &r)
{
if( body ) {
auto& wtr = body->getBulletBody()->getWorldTransform();
wtr.setRotation(btQuaternion(r.x, r.y, r.z, r.w));
}
GameObject::setRotation(r);
void InstanceObject::setRotation(const glm::quat& r) {
if (body) {
auto& wtr = body->getBulletBody()->getWorldTransform();
wtr.setRotation(btQuaternion(r.x, r.y, r.z, r.w));
}
GameObject::setRotation(r);
}
bool InstanceObject::takeDamage(const GameObject::DamageInfo& dmg)
{
bool smash = false;
if( dynamics ) {
smash = dynamics->collDamageFlags == 80;
bool InstanceObject::takeDamage(const GameObject::DamageInfo& dmg) {
bool smash = false;
if (dynamics) {
smash = dynamics->collDamageFlags == 80;
if( dmg.impulse >= dynamics->uprootForce && (body->getBulletBody()->getCollisionFlags() & btRigidBody::CF_STATIC_OBJECT) != 0 ) {
_enablePhysics = true;
}
}
if(smash) {
health -= dmg.hitpoints;
return true;
}
return false;
if (dmg.impulse >= dynamics->uprootForce &&
(body->getBulletBody()->getCollisionFlags() &
btRigidBody::CF_STATIC_OBJECT) != 0) {
_enablePhysics = true;
}
}
if (smash) {
health -= dmg.hitpoints;
return true;
}
return false;
}
void InstanceObject::setSolid(bool solid)
{
// Early out in case we don't have a collision body
if (body == nullptr || body->getBulletBody() == nullptr) {
return;
}
void InstanceObject::setSolid(bool solid) {
// Early out in case we don't have a collision body
if (body == nullptr || body->getBulletBody() == nullptr) {
return;
}
int flags = body->getBulletBody()->getCollisionFlags();
if (solid) {
flags &= ~btCollisionObject::CF_NO_CONTACT_RESPONSE;
} else {
flags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
}
body->getBulletBody()->setCollisionFlags(flags);
int flags = body->getBulletBody()->getCollisionFlags();
if (solid) {
flags &= ~btCollisionObject::CF_NO_CONTACT_RESPONSE;
} else {
flags |= btCollisionObject::CF_NO_CONTACT_RESPONSE;
}
body->getBulletBody()->setCollisionFlags(flags);
}

View File

@ -1,8 +1,8 @@
#pragma once
#ifndef _OBJECTINSTANCE_HPP_
#define _OBJECTINSTANCE_HPP_
#include <objects/GameObject.hpp>
#include <btBulletDynamicsCommon.h>
#include <objects/GameObject.hpp>
class CollisionInstance;
@ -10,41 +10,48 @@ class CollisionInstance;
* @struct InstanceObject
* A simple object instance
*/
class InstanceObject : public GameObject
{
float health;
bool visible = true;
class InstanceObject : public GameObject {
float health;
bool visible = true;
public:
glm::vec3 scale;
CollisionInstance* body;
std::shared_ptr<ObjectData> object;
InstanceObject* LODinstance;
std::shared_ptr<DynamicObjectData> dynamics;
bool _enablePhysics;
glm::vec3 scale;
CollisionInstance* body;
std::shared_ptr<ObjectData> object;
InstanceObject* LODinstance;
std::shared_ptr<DynamicObjectData> dynamics;
bool _enablePhysics;
InstanceObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, const ModelRef& model, const glm::vec3& scale, std::shared_ptr< ObjectData > obj, InstanceObject* lod, std::shared_ptr< DynamicObjectData > dyn
);
~InstanceObject();
InstanceObject(GameWorld* engine, const glm::vec3& pos,
const glm::quat& rot, const ModelRef& model,
const glm::vec3& scale, std::shared_ptr<ObjectData> obj,
InstanceObject* lod, std::shared_ptr<DynamicObjectData> dyn);
~InstanceObject();
Type type() { return Instance; }
Type type() {
return Instance;
}
void tick(float dt);
void tick(float dt);
void changeModel(std::shared_ptr<ObjectData> incoming);
void changeModel(std::shared_ptr<ObjectData> incoming);
virtual void setRotation(const glm::quat& r);
virtual bool takeDamage(const DamageInfo& damage);
virtual void setRotation(const glm::quat& r);
void setSolid(bool solid);
virtual bool takeDamage(const DamageInfo& damage);
void setVisible(bool visible) {
this->visible = visible;
}
float getVisible() const { return visible; }
void setSolid(bool solid);
float getHealth() const { return health; }
void setVisible(bool visible) {
this->visible = visible;
}
float getVisible() const {
return visible;
}
float getHealth() const {
return health;
}
};
#endif

View File

@ -1,59 +1,56 @@
#include <objects/ItemPickup.hpp>
#include <objects/CharacterObject.hpp>
#include <engine/GameWorld.hpp>
#include <items/WeaponItem.hpp>
#include <objects/CharacterObject.hpp>
#include <objects/ItemPickup.hpp>
#include <rw/defines.hpp>
ItemPickup::ItemPickup(GameWorld *world, const glm::vec3 &position, PickupType type, InventoryItem* item)
: PickupObject(world, position, item->getModelID(), type)
, item(item)
{
RW_CHECK(item != nullptr, "Pickup created with null item");
ItemPickup::ItemPickup(GameWorld *world, const glm::vec3 &position,
PickupType type, InventoryItem *item)
: PickupObject(world, position, item->getModelID(), type), item(item) {
RW_CHECK(item != nullptr, "Pickup created with null item");
}
bool ItemPickup::onCharacterTouch(CharacterObject *character)
{
character->addToInventory(item);
auto& wep = character->getCurrentState().weapons[item->getInventorySlot()];
auto totalRounds = 0, clipRounds = 0;
bool ItemPickup::onCharacterTouch(CharacterObject *character) {
character->addToInventory(item);
auto &wep = character->getCurrentState().weapons[item->getInventorySlot()];
auto totalRounds = 0, clipRounds = 0;
switch (item->getModelID()) {
case 173: /* Pistol */
totalRounds = 45;
break;
case 178: /* Uzi */
totalRounds = 125;
break;
case 176: /* Shotgun */
totalRounds = 25;
break;
case 170: /* Grenade */
totalRounds = 5;
break;
case 174: /* Molotov */
totalRounds = 5;
break;
case 181: /* Flame thrower */
totalRounds = 25;
break;
case 171: /* AK */
totalRounds = 150;
break;
case 180: /* M16 */
totalRounds = 300;
break;
case 177: /* Sniper Rifle */
totalRounds = 25;
break;
}
switch (item->getModelID()) {
case 173: /* Pistol */
totalRounds = 45;
break;
case 178: /* Uzi */
totalRounds = 125;
break;
case 176: /* Shotgun */
totalRounds = 25;
break;
case 170: /* Grenade */
totalRounds = 5;
break;
case 174: /* Molotov */
totalRounds = 5;
break;
case 181: /* Flame thrower */
totalRounds = 25;
break;
case 171: /* AK */
totalRounds = 150;
break;
case 180: /* M16 */
totalRounds = 300;
break;
case 177: /* Sniper Rifle */
totalRounds = 25;
break;
}
if (getPickupType() == OnStreet || getPickupType() == OnStreetSlow)
{
totalRounds /= 5;
}
if (getPickupType() == OnStreet || getPickupType() == OnStreetSlow) {
totalRounds /= 5;
}
wep.bulletsTotal = totalRounds;
wep.bulletsClip = clipRounds;
wep.bulletsTotal = totalRounds;
wep.bulletsClip = clipRounds;
return true;
return true;
}

View File

@ -1,8 +1,8 @@
#pragma once
#ifndef _ITEMPICKUP_HPP_
#define _ITEMPICKUP_HPP_
#include <objects/PickupObject.hpp>
#include <glm/glm.hpp>
#include <objects/PickupObject.hpp>
class InventoryItem;
@ -10,14 +10,14 @@ class InventoryItem;
* @brief The ItemPickup class
* Inserts an item into a characters inventory on pickup.
*/
class ItemPickup : public PickupObject
{
InventoryItem* item;
class ItemPickup : public PickupObject {
InventoryItem* item;
public:
ItemPickup(GameWorld* world, const glm::vec3& position, PickupType type,
InventoryItem* item);
ItemPickup(GameWorld* world, const glm::vec3& position, PickupType type, InventoryItem* item);
bool onCharacterTouch(CharacterObject* character);
bool onCharacterTouch(CharacterObject* character);
};
#endif

View File

@ -1,166 +1,165 @@
#include <objects/PickupObject.hpp>
#include <objects/CharacterObject.hpp>
#include <engine/GameWorld.hpp>
#include <engine/GameData.hpp>
#include <engine/GameWorld.hpp>
#include <objects/CharacterObject.hpp>
#include <objects/PickupObject.hpp>
bool PickupObject::doesRespawn(PickupType type)
{
switch(type) {
case Once:
case OnceTimeout:
case Collectable:
case OutOfStock:
case Money:
case MineInactive:
case MineArmed:
case NauticalMineInactive:
case NauticalMineArmed:
case FloatingPackage:
case FloatingPackageFloating:
return false;
default:
return true;
}
bool PickupObject::doesRespawn(PickupType type) {
switch (type) {
case Once:
case OnceTimeout:
case Collectable:
case OutOfStock:
case Money:
case MineInactive:
case MineArmed:
case NauticalMineInactive:
case NauticalMineArmed:
case FloatingPackage:
case FloatingPackageFloating:
return false;
default:
return true;
}
}
float PickupObject::respawnTime(PickupType type)
{
switch(type) {
case InShop:
return 5.f;
case OnStreet:
case OnStreetSlow:
return 30.f;
default:
return 30.f;
}
float PickupObject::respawnTime(PickupType type) {
switch (type) {
case InShop:
return 5.f;
case OnStreet:
case OnStreetSlow:
return 30.f;
default:
return 30.f;
}
}
uint32_t PickupObject::behaviourFlags(PickupType type)
{
switch(type) {
case InShop:
case OnStreet:
case Once:
case OnceTimeout:
case Collectable:
case Money:
case OnStreetSlow:
return PickupOnFoot;
case OutOfStock:
case MineInactive:
case MineArmed:
case NauticalMineInactive:
case NauticalMineArmed:
return 0;
case FloatingPackage:
case FloatingPackageFloating:
return PickupInVehicle;
default:
return 0;
}
uint32_t PickupObject::behaviourFlags(PickupType type) {
switch (type) {
case InShop:
case OnStreet:
case Once:
case OnceTimeout:
case Collectable:
case Money:
case OnStreetSlow:
return PickupOnFoot;
case OutOfStock:
case MineInactive:
case MineArmed:
case NauticalMineInactive:
case NauticalMineArmed:
return 0;
case FloatingPackage:
case FloatingPackageFloating:
return PickupInVehicle;
default:
return 0;
}
}
PickupObject::PickupObject(GameWorld *world, const glm::vec3 &position, int modelID, PickupType type)
: GameObject(world, position, glm::quat(), nullptr)
, m_ghost(nullptr)
, m_shape(nullptr)
, m_enabled(false)
, m_collected(false)
, m_model(modelID)
, m_type(type)
{
btTransform tf;
tf.setIdentity();
tf.setOrigin(btVector3(position.x, position.y, position.z));
PickupObject::PickupObject(GameWorld* world, const glm::vec3& position,
int modelID, PickupType type)
: GameObject(world, position, glm::quat(), nullptr)
, m_ghost(nullptr)
, m_shape(nullptr)
, m_enabled(false)
, m_collected(false)
, m_model(modelID)
, m_type(type) {
btTransform tf;
tf.setIdentity();
tf.setOrigin(btVector3(position.x, position.y, position.z));
m_ghost = new btPairCachingGhostObject;
m_ghost->setUserPointer(this);
m_ghost->setWorldTransform(tf);
m_shape = new btSphereShape(0.5f);
m_ghost->setCollisionShape(m_shape);
m_ghost->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT|btCollisionObject::CF_NO_CONTACT_RESPONSE);
m_ghost = new btPairCachingGhostObject;
m_ghost->setUserPointer(this);
m_ghost->setWorldTransform(tf);
m_shape = new btSphereShape(0.5f);
m_ghost->setCollisionShape(m_shape);
m_ghost->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT |
btCollisionObject::CF_NO_CONTACT_RESPONSE);
m_corona = world->createEffect(VisualFX::Particle);
m_corona->particle.position = getPosition();
m_corona->particle.direction = glm::vec3(0.f, 0.f, 1.f);
m_corona->particle.orientation = VisualFX::ParticleData::Camera;
m_corona->particle.colour = glm::vec4(1.0f, 0.3f, 0.3f, 0.3f);
m_corona->particle.texture = engine->data->findTexture("coronacircle");
m_corona = world->createEffect(VisualFX::Particle);
m_corona->particle.position = getPosition();
m_corona->particle.direction = glm::vec3(0.f, 0.f, 1.f);
m_corona->particle.orientation = VisualFX::ParticleData::Camera;
m_corona->particle.colour = glm::vec4(1.0f, 0.3f, 0.3f, 0.3f);
m_corona->particle.texture = engine->data->findTexture("coronacircle");
auto flags = behaviourFlags(m_type);
RW_UNUSED(flags);
RW_CHECK((flags & PickupInVehicle)==0, "In Vehicle pickup not implemented yet");
auto flags = behaviourFlags(m_type);
RW_UNUSED(flags);
setEnabled(true);
RW_CHECK((flags & PickupInVehicle) == 0,
"In Vehicle pickup not implemented yet");
setEnabled(true);
}
PickupObject::~PickupObject()
{
if(m_ghost) {
setEnabled(false);
engine->destroyEffect(m_corona);
delete m_ghost;
delete m_shape;
}
PickupObject::~PickupObject() {
if (m_ghost) {
setEnabled(false);
engine->destroyEffect(m_corona);
delete m_ghost;
delete m_shape;
}
}
void PickupObject::tick(float dt)
{
if(! m_enabled) {
// Check if our type of pickup respawns
if (doesRespawn(m_type)) {
m_enableTimer -= dt;
if( m_enableTimer <= 0.f ) {
setEnabled(true);
m_collected = false;
}
}
}
void PickupObject::tick(float dt) {
if (!m_enabled) {
// Check if our type of pickup respawns
if (doesRespawn(m_type)) {
m_enableTimer -= dt;
if (m_enableTimer <= 0.f) {
setEnabled(true);
m_collected = false;
}
}
}
if(m_enabled) {
// Sort out interactions with things that may or may not be players.
btManifoldArray manifoldArray;
btBroadphasePairArray& pairArray = m_ghost->getOverlappingPairCache()->getOverlappingPairArray();
int numPairs = pairArray.size();
auto flags = behaviourFlags(m_type);
if (m_enabled) {
// Sort out interactions with things that may or may not be players.
btManifoldArray manifoldArray;
btBroadphasePairArray& pairArray =
m_ghost->getOverlappingPairCache()->getOverlappingPairArray();
int numPairs = pairArray.size();
auto flags = behaviourFlags(m_type);
for (int i=0;i<numPairs;i++)
{
manifoldArray.clear();
for (int i = 0; i < numPairs; i++) {
manifoldArray.clear();
const btBroadphasePair& pair = pairArray[i];
auto otherObject = static_cast<const btCollisionObject*>(
pair.m_pProxy0->m_clientObject == m_ghost ? pair.m_pProxy1->m_clientObject : pair.m_pProxy0->m_clientObject);
if(otherObject->getUserPointer()) {
GameObject* object = static_cast<GameObject*>(otherObject->getUserPointer());
if((flags & PickupOnFoot) == PickupOnFoot
&& object->type() == Character)
{
CharacterObject* character = static_cast<CharacterObject*>(object);
m_collected = onCharacterTouch(character);
setEnabled( !m_collected );
const btBroadphasePair& pair = pairArray[i];
auto otherObject = static_cast<const btCollisionObject*>(
pair.m_pProxy0->m_clientObject == m_ghost
? pair.m_pProxy1->m_clientObject
: pair.m_pProxy0->m_clientObject);
if (otherObject->getUserPointer()) {
GameObject* object =
static_cast<GameObject*>(otherObject->getUserPointer());
if ((flags & PickupOnFoot) == PickupOnFoot &&
object->type() == Character) {
CharacterObject* character =
static_cast<CharacterObject*>(object);
m_collected = onCharacterTouch(character);
setEnabled(!m_collected);
if( ! m_enabled ) {
m_enableTimer = respawnTime(m_type);
}
}
}
}
}
if (!m_enabled) {
m_enableTimer = respawnTime(m_type);
}
}
}
}
}
}
void PickupObject::setEnabled(bool enabled)
{
if( ! m_enabled && enabled ) {
engine->dynamicsWorld->addCollisionObject(m_ghost, btBroadphaseProxy::SensorTrigger);
m_corona->particle.size = glm::vec2(1.5f, 1.5f);
}
else if( m_enabled && ! enabled ) {
engine->dynamicsWorld->removeCollisionObject(m_ghost);
m_corona->particle.size = glm::vec2(0.f, 0.f);
}
void PickupObject::setEnabled(bool enabled) {
if (!m_enabled && enabled) {
engine->dynamicsWorld->addCollisionObject(
m_ghost, btBroadphaseProxy::SensorTrigger);
m_corona->particle.size = glm::vec2(1.5f, 1.5f);
} else if (m_enabled && !enabled) {
engine->dynamicsWorld->removeCollisionObject(m_ghost);
m_corona->particle.size = glm::vec2(0.f, 0.f);
}
m_enabled = enabled;
m_enabled = enabled;
}

View File

@ -1,10 +1,10 @@
#pragma once
#ifndef _PICKUPOBJECT_HPP_
#define _PICKUPOBJECT_HPP_
#include <objects/GameObject.hpp>
#include <btBulletCollisionCommon.h>
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <btBulletCollisionCommon.h>
#include <glm/glm.hpp>
#include <objects/GameObject.hpp>
class VisualFX;
class CharacterObject;
@ -13,67 +13,73 @@ class CharacterObject;
* @brief The PickupObject class
* Implements interface and base behaviour for pickups
*/
class PickupObject : public GameObject
{
class PickupObject : public GameObject {
public:
enum PickupType {
InShop = 1,
OnStreet = 2,
Once = 3,
OnceTimeout = 4,
Collectable = 5,
OutOfStock = 6,
Money = 7,
MineInactive= 8,
MineArmed = 9,
NauticalMineInactive=10,
NauticalMineArmed=11,
FloatingPackage=12,
FloatingPackageFloating=13,
OnStreetSlow=14
};
enum /*BehaviourFlags*/ {
PickupOnFoot = 1,
PickupInVehicle = 2
};
enum PickupType {
InShop = 1,
OnStreet = 2,
Once = 3,
OnceTimeout = 4,
Collectable = 5,
OutOfStock = 6,
Money = 7,
MineInactive = 8,
MineArmed = 9,
NauticalMineInactive = 10,
NauticalMineArmed = 11,
FloatingPackage = 12,
FloatingPackageFloating = 13,
OnStreetSlow = 14
};
enum /*BehaviourFlags*/ { PickupOnFoot = 1, PickupInVehicle = 2 };
static bool doesRespawn(PickupType type);
static float respawnTime(PickupType type);
static uint32_t behaviourFlags(PickupType type);
static bool doesRespawn(PickupType type);
static float respawnTime(PickupType type);
static uint32_t behaviourFlags(PickupType type);
PickupObject(GameWorld* world, const glm::vec3& position, int modelID, PickupType type);
PickupObject(GameWorld* world, const glm::vec3& position, int modelID,
PickupType type);
~PickupObject();
~PickupObject();
int getModelID() const { return m_model; }
int getModelID() const {
return m_model;
}
Type type() { return Pickup; }
Type type() {
return Pickup;
}
void tick(float dt);
void tick(float dt);
virtual bool onCharacterTouch(CharacterObject* character)
{
RW_UNUSED(character);
return false;
}
virtual bool onCharacterTouch(CharacterObject* character) {
RW_UNUSED(character);
return false;
}
bool isEnabled() const { return m_enabled; }
void setEnabled(bool enabled);
bool isCollected() const { return m_collected; }
bool isEnabled() const {
return m_enabled;
}
void setEnabled(bool enabled);
PickupType getPickupType() const { return m_type; }
bool isCollected() const {
return m_collected;
}
PickupType getPickupType() const {
return m_type;
}
private:
btPairCachingGhostObject* m_ghost;
btSphereShape* m_shape;
bool m_enabled;
float m_enableTimer;
bool m_collected;
int m_model;
VisualFX* m_corona;
btPairCachingGhostObject* m_ghost;
btSphereShape* m_shape;
bool m_enabled;
float m_enableTimer;
bool m_collected;
int m_model;
VisualFX* m_corona;
PickupType m_type;
PickupType m_type;
};
#endif

View File

@ -1,171 +1,179 @@
#include <objects/ProjectileObject.hpp>
#include <engine/GameWorld.hpp>
#include <engine/GameData.hpp>
#include <data/WeaponData.hpp>
#include <engine/GameData.hpp>
#include <engine/GameWorld.hpp>
#include <objects/ProjectileObject.hpp>
void ProjectileObject::checkPhysicsContact()
{
btManifoldArray manifoldArray;
btBroadphasePairArray& pairArray = _ghostBody->getOverlappingPairCache()->getOverlappingPairArray();
int numPairs = pairArray.size();
void ProjectileObject::checkPhysicsContact() {
btManifoldArray manifoldArray;
btBroadphasePairArray& pairArray =
_ghostBody->getOverlappingPairCache()->getOverlappingPairArray();
int numPairs = pairArray.size();
for (int i=0;i<numPairs;i++) {
manifoldArray.clear();
for (int i = 0; i < numPairs; i++) {
manifoldArray.clear();
const btBroadphasePair& pair = pairArray[i];
const btBroadphasePair& pair = pairArray[i];
//unless we manually perform collision detection on this pair, the contacts are in the dynamics world paircache:
btBroadphasePair* collisionPair = engine->dynamicsWorld->getPairCache()->findPair(pair.m_pProxy0,pair.m_pProxy1);
if (!collisionPair) {
continue;
}
// unless we manually perform collision detection on this pair, the
// contacts are in the dynamics world paircache:
btBroadphasePair* collisionPair =
engine->dynamicsWorld->getPairCache()->findPair(pair.m_pProxy0,
pair.m_pProxy1);
if (!collisionPair) {
continue;
}
if (collisionPair->m_algorithm) {
collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
}
if (collisionPair->m_algorithm) {
collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
}
for (int j=0;j<manifoldArray.size();j++) {
//btPersistentManifold* manifold = manifoldArray[j];
//const btCollisionObject* B = manifold->getBody0() == _ghostBody ? manifold->getBody1() : manifold->getBody0();
//GameObject* go = static_cast<GameObject*>(B->getUserPointer());
for (int j = 0; j < manifoldArray.size(); j++) {
// btPersistentManifold* manifold = manifoldArray[j];
// const btCollisionObject* B = manifold->getBody0() == _ghostBody ?
// manifold->getBody1() : manifold->getBody0();
// GameObject* go = static_cast<GameObject*>(B->getUserPointer());
/// @todo check if this is a suitable level to check c.f btManifoldPoint
// It's happening
explode();
/// @todo check if this is a suitable level to check c.f
/// btManifoldPoint
// It's happening
explode();
return;
}
}
return;
}
}
}
void ProjectileObject::explode()
{
if( ! _exploded ) {
// Remove our physics objects
cleanup();
void ProjectileObject::explode() {
if (!_exploded) {
// Remove our physics objects
cleanup();
const float exp_size = 10.f;
const float damageSize = 5.f;
const float damage = _info.weapon->damage;
const float exp_size = 10.f;
const float damageSize = 5.f;
const float damage = _info.weapon->damage;
for(auto& o : engine->allObjects) {
if( o == this ) continue;
switch( o->type() ) {
case GameObject::Instance:
case GameObject::Vehicle:
case GameObject::Character:
break;
default:
continue;
}
for (auto& o : engine->allObjects) {
if (o == this) continue;
switch (o->type()) {
case GameObject::Instance:
case GameObject::Vehicle:
case GameObject::Character:
break;
default:
continue;
}
float d = glm::distance(getPosition(), o->getPosition());
if( d > damageSize ) continue;
float d = glm::distance(getPosition(), o->getPosition());
if (d > damageSize) continue;
o->takeDamage({
getPosition(),
getPosition(),
damage / glm::max(d, 1.f),
DamageInfo::Explosion,
0.f
});
}
o->takeDamage({getPosition(), getPosition(),
damage / glm::max(d, 1.f), DamageInfo::Explosion,
0.f});
}
auto tex = engine->data->findTexture("explo02");
auto explosion = engine->createEffect(VisualFX::Particle);
explosion->particle.size = glm::vec2(exp_size);
explosion->particle.texture = tex;
explosion->particle.starttime = engine->getGameTime();
explosion->particle.lifetime = 0.5f;
explosion->particle.orientation = VisualFX::ParticleData::Camera;
explosion->particle.colour = glm::vec4(1.0f);
explosion->particle.position = getPosition();
explosion->particle.direction = glm::vec3(0.f, 0.f, 1.f);
auto tex = engine->data->findTexture("explo02");
_exploded = true;
engine->destroyObjectQueued(this);
}
auto explosion = engine->createEffect(VisualFX::Particle);
explosion->particle.size = glm::vec2(exp_size);
explosion->particle.texture = tex;
explosion->particle.starttime = engine->getGameTime();
explosion->particle.lifetime = 0.5f;
explosion->particle.orientation = VisualFX::ParticleData::Camera;
explosion->particle.colour = glm::vec4(1.0f);
explosion->particle.position = getPosition();
explosion->particle.direction = glm::vec3(0.f, 0.f, 1.f);
_exploded = true;
engine->destroyObjectQueued(this);
}
}
void ProjectileObject::cleanup()
{
if( _body ) {
engine->dynamicsWorld->removeRigidBody(_body);
delete _body;
_body = nullptr;
}
if( _ghostBody ) {
engine->dynamicsWorld->removeCollisionObject(_ghostBody);
delete _ghostBody;
_ghostBody = nullptr;
}
if( _shape ) {
delete _shape;
_shape = nullptr;
}
void ProjectileObject::cleanup() {
if (_body) {
engine->dynamicsWorld->removeRigidBody(_body);
delete _body;
_body = nullptr;
}
if (_ghostBody) {
engine->dynamicsWorld->removeCollisionObject(_ghostBody);
delete _ghostBody;
_ghostBody = nullptr;
}
if (_shape) {
delete _shape;
_shape = nullptr;
}
}
ProjectileObject::ProjectileObject(GameWorld *world, const glm::vec3 &position, const ProjectileObject::ProjectileInfo &info)
: GameObject(world, position, glm::quat(), nullptr),
_info(info), _body(nullptr), _ghostBody(nullptr),
_exploded(false)
{
_shape = new btSphereShape(0.45f);
btVector3 inertia(0.f, 0.f, 0.f);
_shape->calculateLocalInertia(1.f, inertia);
btRigidBody::btRigidBodyConstructionInfo riginfo(1.f, nullptr, _shape, inertia);
ProjectileObject::ProjectileObject(GameWorld* world, const glm::vec3& position,
const ProjectileObject::ProjectileInfo& info)
: GameObject(world, position, glm::quat(), nullptr)
, _info(info)
, _body(nullptr)
, _ghostBody(nullptr)
, _exploded(false) {
_shape = new btSphereShape(0.45f);
btVector3 inertia(0.f, 0.f, 0.f);
_shape->calculateLocalInertia(1.f, inertia);
btRigidBody::btRigidBodyConstructionInfo riginfo(1.f, nullptr, _shape,
inertia);
btTransform ws;
ws.setIdentity();
ws.setOrigin(btVector3(position.x, position.y, position.z));
riginfo.m_startWorldTransform = ws;
riginfo.m_mass = 1.f;
btTransform ws;
ws.setIdentity();
ws.setOrigin(btVector3(position.x, position.y, position.z));
riginfo.m_startWorldTransform = ws;
riginfo.m_mass = 1.f;
_body = new btRigidBody(riginfo);
_body->setUserPointer(this);
_body->setLinearVelocity(btVector3(_info.direction.x, _info.direction.y, _info.direction.z) * _info.velocity);
engine->dynamicsWorld->addRigidBody(_body, btBroadphaseProxy::DefaultFilter,
btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter );
_body = new btRigidBody(riginfo);
_body->setUserPointer(this);
_body->setLinearVelocity(
btVector3(_info.direction.x, _info.direction.y, _info.direction.z) *
_info.velocity);
engine->dynamicsWorld->addRigidBody(
_body, btBroadphaseProxy::DefaultFilter,
btBroadphaseProxy::StaticFilter | btBroadphaseProxy::DefaultFilter);
if( _info.type == RPG ) {
// RPGs aren't affected by gravity
_body->setGravity( { 0.f, 0.f, 0.f } );
}
if (_info.type == RPG) {
// RPGs aren't affected by gravity
_body->setGravity({0.f, 0.f, 0.f});
}
if( _info.type != Grenade ) {
// Projectiles that aren't grenades explode on contact.
_ghostBody = new btPairCachingGhostObject();
_ghostBody->setWorldTransform(_body->getWorldTransform());
_ghostBody->setCollisionShape(_shape);
_ghostBody->setUserPointer(this);
_ghostBody->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT|btCollisionObject::CF_NO_CONTACT_RESPONSE);
engine->dynamicsWorld->addCollisionObject(_ghostBody, btBroadphaseProxy::SensorTrigger, btBroadphaseProxy::AllFilter);
}
if (_info.type != Grenade) {
// Projectiles that aren't grenades explode on contact.
_ghostBody = new btPairCachingGhostObject();
_ghostBody->setWorldTransform(_body->getWorldTransform());
_ghostBody->setCollisionShape(_shape);
_ghostBody->setUserPointer(this);
_ghostBody->setCollisionFlags(
btCollisionObject::CF_KINEMATIC_OBJECT |
btCollisionObject::CF_NO_CONTACT_RESPONSE);
engine->dynamicsWorld->addCollisionObject(
_ghostBody, btBroadphaseProxy::SensorTrigger,
btBroadphaseProxy::AllFilter);
}
}
ProjectileObject::~ProjectileObject()
{
cleanup();
ProjectileObject::~ProjectileObject() {
cleanup();
}
void ProjectileObject::tick(float dt)
{
if( _body == nullptr ) return;
void ProjectileObject::tick(float dt) {
if (_body == nullptr) return;
auto& bttr = _body->getWorldTransform();
position = { bttr.getOrigin().x(), bttr.getOrigin().y(), bttr.getOrigin().z() };
auto r = bttr.getRotation();
rotation = { r.x(), r.y(), r.z(), r.w() };
auto& bttr = _body->getWorldTransform();
position = {bttr.getOrigin().x(), bttr.getOrigin().y(),
bttr.getOrigin().z()};
auto r = bttr.getRotation();
rotation = {r.x(), r.y(), r.z(), r.w()};
_info.time -= dt;
_info.time -= dt;
if( _ghostBody ) {
_ghostBody->setWorldTransform(_body->getWorldTransform());
checkPhysicsContact();
}
if (_ghostBody) {
_ghostBody->setWorldTransform(_body->getWorldTransform());
checkPhysicsContact();
}
if( _info.time <= 0.f ) {
explode();
}
if (_info.time <= 0.f) {
explode();
}
}

View File

@ -1,66 +1,67 @@
#pragma once
#ifndef _PROJECTILEOBJECT_HPP_
#define _PROJECTILEOBJECT_HPP_
#include <objects/GameObject.hpp>
#include <data/WeaponData.hpp>
#include <btBulletDynamicsCommon.h>
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <btBulletDynamicsCommon.h>
#include <data/WeaponData.hpp>
#include <objects/GameObject.hpp>
/**
* @brief Implements weapon projectile (e.g. molotovs, RPGs etc.)
*/
class ProjectileObject : public GameObject
{
class ProjectileObject : public GameObject {
public:
enum ProjectileType {
Grenade,
Molotov,
RPG,
};
enum ProjectileType {
Grenade,
Molotov,
RPG,
};
struct ProjectileInfo {
ProjectileType type;
glm::vec3 direction;
float velocity;
struct ProjectileInfo {
ProjectileType type;
glm::vec3 direction;
float velocity;
/** Time to dentonation or removal */
float time;
/** Time to dentonation or removal */
float time;
std::shared_ptr<WeaponData> weapon;
};
std::shared_ptr<WeaponData> weapon;
};
private:
ProjectileInfo _info;
ProjectileInfo _info;
btSphereShape* _shape;
btSphereShape* _shape;
btRigidBody* _body;
btRigidBody* _body;
/** Used for RPGs and Molotov collision detection */
btPairCachingGhostObject* _ghostBody;
/** Used for RPGs and Molotov collision detection */
btPairCachingGhostObject* _ghostBody;
bool _exploded;
bool _exploded;
void checkPhysicsContact();
void explode();
void cleanup();
void checkPhysicsContact();
void explode();
void cleanup();
public:
/**
* @brief ProjectileObject constructor
*/
ProjectileObject(GameWorld* world, const glm::vec3& position,
const ProjectileInfo& info);
/**
* @brief ProjectileObject constructor
*/
ProjectileObject(GameWorld* world, const glm::vec3& position, const ProjectileInfo& info);
~ProjectileObject();
~ProjectileObject();
void tick(float dt);
void tick(float dt);
Type type() {
return Projectile;
}
Type type() { return Projectile; }
const ProjectileInfo& getProjectileInfo() const { return _info; }
const ProjectileInfo& getProjectileInfo() const {
return _info;
}
};
#endif

View File

@ -1,116 +1,105 @@
#pragma once
#ifndef _VEHICLE_INFO_HPP_
#define _VEHICLE_INFO_HPP_
#include <glm/glm.hpp>
#include <memory>
#include <string>
#include <vector>
#include <memory>
#include <glm/glm.hpp>
struct VehicleData;
/**
* @brief Stores data loaded from handling.cfg
*/
struct VehicleHandlingInfo
{
enum EngineType
{
Diesel = 'D',
Petrol = 'P',
Electric = 'E'
};
struct VehicleHandlingInfo {
enum EngineType { Diesel = 'D', Petrol = 'P', Electric = 'E' };
enum DriveType
{
Forward = 'F',
Rear = 'R',
All = '4'
};
enum DriveType { Forward = 'F', Rear = 'R', All = '4' };
std::string ID;
float mass;
glm::vec3 dimensions;
glm::vec3 centerOfMass;
float percentSubmerged;
float tractionMulti;
float tractionLoss;
float tractionBias;
size_t numGears;
float maxVelocity;
float acceleration;
DriveType driveType;
EngineType engineType;
float brakeDeceleration;
float brakeBias;
bool ABS;
float steeringLock;
float suspensionForce;
float suspensionDamping;
float seatOffset;
float damageMulti;
size_t value;
float suspensionUpperLimit;
float suspensionLowerLimit;
float suspensionBias;
uint32_t flags;
enum /*VehicleFlags*/ {
VF_1G_BOOST = 1 << 0,
VF_2G_BOOST = 2 << 0,
VF_REV_BONNET = 4 << 0,
VF_HANGING_BOOT = 8 << 0,
VF_NO_DOORS = 1 << 8,
VF_IS_VAN = 2 << 8,
VF_IS_BUS = 4 << 8,
VF_IS_LOW = 8 << 8,
VF_DBL_EXHAUST = 1 << 16,
VF_TAILGATE_BOOT= 2 << 16,
VF_NOSWING_BOOT = 4 << 16,
VF_NONPLAYER_STABILIZER = 8 << 16,
VF_NEUTRALHANDLING = 1 << 16,
VF_HAS_NO_ROOF = 2 << 16,
VF_IS_BIG = 4 << 16,
VF_HALOGEN_LIGHTS = 8 << 16
};
std::string ID;
float mass;
glm::vec3 dimensions;
glm::vec3 centerOfMass;
float percentSubmerged;
float tractionMulti;
float tractionLoss;
float tractionBias;
size_t numGears;
float maxVelocity;
float acceleration;
DriveType driveType;
EngineType engineType;
float brakeDeceleration;
float brakeBias;
bool ABS;
float steeringLock;
float suspensionForce;
float suspensionDamping;
float seatOffset;
float damageMulti;
size_t value;
float suspensionUpperLimit;
float suspensionLowerLimit;
float suspensionBias;
uint32_t flags;
enum /*VehicleFlags*/ {
VF_1G_BOOST = 1 << 0,
VF_2G_BOOST = 2 << 0,
VF_REV_BONNET = 4 << 0,
VF_HANGING_BOOT = 8 << 0,
VF_NO_DOORS = 1 << 8,
VF_IS_VAN = 2 << 8,
VF_IS_BUS = 4 << 8,
VF_IS_LOW = 8 << 8,
VF_DBL_EXHAUST = 1 << 16,
VF_TAILGATE_BOOT = 2 << 16,
VF_NOSWING_BOOT = 4 << 16,
VF_NONPLAYER_STABILIZER = 8 << 16,
VF_NEUTRALHANDLING = 1 << 16,
VF_HAS_NO_ROOF = 2 << 16,
VF_IS_BIG = 4 << 16,
VF_HALOGEN_LIGHTS = 8 << 16
};
};
struct WheelInfo
{
glm::vec3 position;
struct WheelInfo {
glm::vec3 position;
};
struct SeatInfo {
glm::vec3 offset;
glm::vec3 offset;
};
/**
* @brief Vehicle Handling and runtime-derrived information about wheel and seat positions.
* @brief Vehicle Handling and runtime-derrived information about wheel and seat
* positions.
*/
struct VehicleInfo {
/** Handling data */
VehicleHandlingInfo handling;
/** Handling data */
VehicleHandlingInfo handling;
/** Value for caching wheel information */
std::vector<WheelInfo> wheels;
/** Struct for caching seat information */
struct {
std::vector<SeatInfo> front;
std::vector<SeatInfo> back;
/** Value for caching wheel information */
std::vector<WheelInfo> wheels;
/** Struct for caching seat information */
struct {
std::vector<SeatInfo> front;
std::vector<SeatInfo> back;
SeatInfo operator[](size_t index) const {
// Try front seats first
if (index < front.size()) {
return front[index];
}
index -= front.size();
SeatInfo operator[](size_t index) const {
// Try front seats first
if (index < front.size()) {
return front[index];
}
index -= front.size();
// Get back seat
return back[index];
}
size_t size() const {
return front.size() + back.size();
}
} seats;
// Get back seat
return back[index];
}
size_t size() const {
return front.size() + back.size();
}
} seats;
};
typedef std::shared_ptr<VehicleInfo> VehicleInfoHandle;

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
#pragma once
#ifndef _VEHICLEOBJECT_HPP_
#define _VEHICLEOBJECT_HPP_
#include <objects/GameObject.hpp>
#include <map>
#include <objects/GameObject.hpp>
#include <objects/VehicleInfo.hpp>
class CollisionInstance;
@ -16,137 +16,136 @@ class btTransform;
* @class VehicleObject
* Implements Vehicle behaviours.
*/
class VehicleObject : public GameObject
{
class VehicleObject : public GameObject {
private:
float steerAngle;
float throttle;
float brake;
bool handbrake;
float steerAngle;
float throttle;
float brake;
bool handbrake;
public:
VehicleDataHandle vehicle;
VehicleInfoHandle info;
glm::u8vec3 colourPrimary;
glm::u8vec3 colourSecondary;
VehicleDataHandle vehicle;
VehicleInfoHandle info;
glm::u8vec3 colourPrimary;
glm::u8vec3 colourSecondary;
std::map<size_t, GameObject*> seatOccupants;
std::map<size_t, GameObject*> seatOccupants;
CollisionInstance* collision;
btVehicleRaycaster* physRaycaster;
btRaycastVehicle* physVehicle;
struct Part
{
ModelFrame* dummy;
ModelFrame* normal;
ModelFrame* damaged;
btRigidBody* body;
btHingeConstraint* constraint;
bool moveToAngle;
float targetAngle;
float openAngle;
float closedAngle;
};
std::map<std::string, Part> dynamicParts;
CollisionInstance* collision;
btVehicleRaycaster* physRaycaster;
btRaycastVehicle* physVehicle;
VehicleObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, const ModelRef& model, VehicleDataHandle data, VehicleInfoHandle info, const glm::u8vec3& prim, const glm::u8vec3& sec);
virtual ~VehicleObject();
void setPosition(const glm::vec3& pos);
struct Part {
ModelFrame* dummy;
ModelFrame* normal;
ModelFrame* damaged;
btRigidBody* body;
btHingeConstraint* constraint;
bool moveToAngle;
float targetAngle;
float openAngle;
float closedAngle;
};
void setRotation(const glm::quat &orientation);
std::map<std::string, Part> dynamicParts;
Type type() { return Vehicle; }
VehicleObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot,
const ModelRef& model, VehicleDataHandle data,
VehicleInfoHandle info, const glm::u8vec3& prim,
const glm::u8vec3& sec);
void setSteeringAngle(float);
virtual ~VehicleObject();
float getSteeringAngle() const;
void setPosition(const glm::vec3& pos);
void setThrottle(float);
void setRotation(const glm::quat& orientation);
float getThrottle() const;
Type type() {
return Vehicle;
}
void setBraking(float);
void setSteeringAngle(float);
float getBraking() const;
float getSteeringAngle() const;
void setHandbraking(bool);
void setThrottle(float);
bool getHandbraking() const;
float getThrottle() const;
void tick(float dt);
void setBraking(float);
void tickPhysics(float dt);
bool isFlipped() const;
float getBraking() const;
float getVelocity() const;
void ejectAll();
GameObject* getOccupant(size_t seat);
void setOccupant(size_t seat, GameObject* occupant);
void setHandbraking(bool);
/**
* @brief canOccupantExit
* @return true if the vehicle is currently exitable
*/
bool canOccupantExit() const;
bool getHandbraking() const;
/**
* @brief isOccupantDriver
* @param seat
* @return True if the given seat is the driver's seat.
*/
bool isOccupantDriver(size_t seat) const;
void tick(float dt);
void tickPhysics(float dt);
bool isFlipped() const;
float getVelocity() const;
void ejectAll();
GameObject* getOccupant(size_t seat);
void setOccupant(size_t seat, GameObject* occupant);
/**
* @brief canOccupantExit
* @return true if the vehicle is currently exitable
*/
bool canOccupantExit() const;
/**
* @brief isOccupantDriver
* @param seat
* @return True if the given seat is the driver's seat.
*/
bool isOccupantDriver(size_t seat) const;
glm::vec3 getSeatEntryPosition(size_t seat) const {
auto pos = info->seats[seat].offset;
pos -= glm::vec3(glm::sign(pos.x) * -0.81756252f, 0.34800607f,
-0.486281008f);
return pos;
}
glm::vec3 getSeatEntryPositionWorld(size_t seat) const {
return getPosition() + getRotation() * getSeatEntryPosition(seat);
}
Part* getSeatEntryDoor(size_t seat);
glm::vec3 getSeatEntryPosition(size_t seat) const {
auto pos = info->seats[seat].offset;
pos -= glm::vec3(glm::sign(pos.x) * -0.81756252f, 0.34800607f, -0.486281008f);
return pos;
}
glm::vec3 getSeatEntryPositionWorld(size_t seat) const {
return getPosition() + getRotation() * getSeatEntryPosition(seat);
}
Part* getSeatEntryDoor(size_t seat);
virtual bool takeDamage(const DamageInfo& damage);
enum FrameState {
OK,
DAM,
BROKEN
};
enum FrameState { OK, DAM, BROKEN };
void setPartState(Part* part, FrameState state);
void setPartState(Part* part, FrameState state);
void setPartLocked(Part* part, bool locked);
void setPartTarget(Part* part, bool enable, float target);
void setPartLocked(Part* part, bool locked);
Part* getPart(const std::string& name);
void setPartTarget(Part* part, bool enable, float target);
void applyWaterFloat(const glm::vec3& relPt);
Part* getPart(const std::string& name);
void setPrimaryColour(uint8_t color);
void setSecondaryColour(uint8_t color);
void applyWaterFloat(const glm::vec3& relPt);
/**
* @brief isStopped
* @return True if the vehicle isn't moving
*/
bool isStopped() const;
void setPrimaryColour(uint8_t color);
void setSecondaryColour(uint8_t color);
/**
* @brief isStopped
* @return True if the vehicle isn't moving
*/
bool isStopped() const;
private:
void registerPart(ModelFrame* mf);
void createObjectHinge(Part* part);
void destroyObjectHinge(Part* part);
void registerPart(ModelFrame* mf);
void createObjectHinge(Part* part);
void destroyObjectHinge(Part* part);
};
#endif