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:
parent
305737cc3d
commit
f2eede5301
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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__
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user