WIP
This commit is contained in:
@@ -29,7 +29,7 @@ struct EntityWrapper
|
||||
EntityWrapper FirstChildByName(const std::string& name);
|
||||
EntityWrapper FirstParentWithComponent(const std::string& componentType);
|
||||
bool IsChildOf(EntityWrapper potentialParent);
|
||||
bool Valid();
|
||||
bool Valid() const;
|
||||
|
||||
ComponentWrapper operator[](const char* componentName);
|
||||
bool operator==(const EntityWrapper& e) const;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <tuple>
|
||||
#include <set>
|
||||
|
||||
#include "../Common.h"
|
||||
#include "Event.h"
|
||||
@@ -107,7 +108,7 @@ private:
|
||||
typedef std::unordered_map<ContextTypeName_t, EventRelays_t> ContextRelays_t;
|
||||
ContextRelays_t m_ContextRelays;
|
||||
std::vector<BaseEventRelay*> m_RelaysToSubscribe;
|
||||
std::vector<std::tuple<EventID, ContextTypeName_t, EventTypeName_t>> m_RelaysToUnsubscribe;
|
||||
std::unordered_map<BaseEventRelay*, std::tuple<EventID, ContextTypeName_t, EventTypeName_t>> m_RelaysToUnsubscribe;
|
||||
|
||||
typedef std::list<std::pair<EventTypeName_t, std::shared_ptr<Event>>> EventQueue_t;
|
||||
std::shared_ptr<EventQueue_t> m_EventQueueRead;
|
||||
|
||||
@@ -5,9 +5,7 @@
|
||||
|
||||
#include "../Common.h"
|
||||
#include "AABB.h"
|
||||
|
||||
//Fwd declarations.
|
||||
class Ray;
|
||||
#include "Ray.h"
|
||||
|
||||
namespace OctSpace
|
||||
{
|
||||
|
||||
@@ -68,7 +68,7 @@ protected:
|
||||
|
||||
const std::string m_ComponentType;
|
||||
|
||||
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) = 0;
|
||||
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cPlayer, double dt) = 0;
|
||||
};
|
||||
|
||||
class ImpureSystem : public virtual System
|
||||
|
||||
@@ -13,17 +13,23 @@
|
||||
#include "Input/EInputCommand.h"
|
||||
#include "Core/EntityFile.h"
|
||||
#include "Core/EntityFileParser.h"
|
||||
#include "Core/Octree.h"
|
||||
#include "Collision/EntityAABB.h"
|
||||
|
||||
class WeaponBehaviour;
|
||||
|
||||
class WeaponSystem : public PureSystem, ImpureSystem
|
||||
{
|
||||
public:
|
||||
WeaponSystem(SystemParams params, IRenderer* renderer);
|
||||
WeaponSystem(SystemParams params, IRenderer* renderer, Octree<EntityAABB>* collisionOctree);
|
||||
|
||||
virtual void Update(double dt) override;
|
||||
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) override;
|
||||
virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cPlayer, double dt) override;
|
||||
|
||||
private:
|
||||
SystemParams m_SystemParams;
|
||||
IRenderer* m_Renderer;
|
||||
Octree<EntityAABB>* m_CollisionOctree;
|
||||
|
||||
std::unordered_map<EntityWrapper, std::shared_ptr<WeaponBehaviour>> m_ActiveWeapons;
|
||||
|
||||
@@ -38,12 +44,18 @@ private:
|
||||
void selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot);
|
||||
};
|
||||
|
||||
class WeaponBehaviour
|
||||
class WeaponBehaviour : protected System
|
||||
{
|
||||
public:
|
||||
WeaponBehaviour(EntityWrapper weaponEntity)
|
||||
: m_Entity(weaponEntity)
|
||||
WeaponBehaviour(SystemParams systemParams, Octree<EntityAABB>* collisionOctree, EntityWrapper weaponEntity)
|
||||
: System(systemParams)
|
||||
, m_CollisionOctree(collisionOctree)
|
||||
, m_Entity(weaponEntity)
|
||||
{ }
|
||||
virtual ~WeaponBehaviour() = default;
|
||||
|
||||
WeaponBehaviour(const WeaponBehaviour&) = delete;
|
||||
WeaponBehaviour& operator=(const WeaponBehaviour &) = delete;
|
||||
|
||||
virtual void Fire() = 0;
|
||||
virtual void CeaseFire() { }
|
||||
@@ -51,15 +63,19 @@ public:
|
||||
virtual void Update(double dt) { }
|
||||
|
||||
protected:
|
||||
Octree<EntityAABB>* m_CollisionOctree;
|
||||
EntityWrapper m_Entity;
|
||||
};
|
||||
|
||||
class AssaultWeaponBehaviour : public WeaponBehaviour
|
||||
{
|
||||
public:
|
||||
AssaultWeaponBehaviour(EntityWrapper weaponEntity)
|
||||
: WeaponBehaviour(weaponEntity)
|
||||
{ }
|
||||
AssaultWeaponBehaviour(SystemParams systemParams, Octree<EntityAABB>* collisionOctree, EntityWrapper weaponEntity)
|
||||
: WeaponBehaviour(systemParams, collisionOctree, weaponEntity)
|
||||
{
|
||||
m_RayRed = ResourceManager::Load<EntityFile>("Schema/Entities/RayRed.xml");
|
||||
m_RayBlue = ResourceManager::Load<EntityFile>("Schema/Entities/RayBlue.xml");
|
||||
}
|
||||
|
||||
virtual void Fire() override
|
||||
{
|
||||
@@ -73,6 +89,25 @@ public:
|
||||
m_Firing = false;
|
||||
}
|
||||
|
||||
virtual void Reload() override
|
||||
{
|
||||
ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"];
|
||||
|
||||
int& magAmmo = cAssaultWeapon["MagazineAmmo"];
|
||||
int magSize = cAssaultWeapon["MagazineSize"];
|
||||
int& ammo = cAssaultWeapon["Ammo"];
|
||||
|
||||
// Don't reload if we're already fully loaded
|
||||
if (magAmmo == magSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Throw away rounds in magazine to incentivise ammo sharing
|
||||
int toLoad = glm::min(magSize, ammo);
|
||||
magAmmo = toLoad;
|
||||
ammo -= toLoad;
|
||||
}
|
||||
|
||||
virtual void Update(double dt) override
|
||||
{
|
||||
if (!m_Firing) {
|
||||
@@ -82,7 +117,7 @@ public:
|
||||
m_TimeSinceLastFire += dt;
|
||||
|
||||
ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"];
|
||||
if (m_TimeSinceLastFire > (double)cAssaultWeapon["RPM"] / 60.0) {
|
||||
if (m_TimeSinceLastFire >= 1.0 / ((double)cAssaultWeapon["RPM"] / 60.0)) {
|
||||
fireRound();
|
||||
}
|
||||
}
|
||||
@@ -90,7 +125,8 @@ public:
|
||||
private:
|
||||
bool m_Firing = false;
|
||||
double m_TimeSinceLastFire = 0.0;
|
||||
ComponentWrapper m_Component;
|
||||
EntityFile* m_RayRed = nullptr;
|
||||
EntityFile* m_RayBlue = nullptr;
|
||||
|
||||
void fireRound()
|
||||
{
|
||||
@@ -99,18 +135,85 @@ private:
|
||||
int& magAmmo = cAssaultWeapon["MagazineAmmo"];
|
||||
int ammo = cAssaultWeapon["Ammo"];
|
||||
|
||||
// Reload if our magazine is empty and we have ammo to fill it with
|
||||
if (magAmmo <= 0 && ammo > 0) {
|
||||
CeaseFire();
|
||||
// Reload if our magazine is empty
|
||||
if (magAmmo <= 0) {
|
||||
Reload();
|
||||
return;
|
||||
}
|
||||
|
||||
// Fire
|
||||
magAmmo -= 1;
|
||||
spawnTracer();
|
||||
|
||||
m_TimeSinceLastFire = 0.0;
|
||||
}
|
||||
|
||||
void spawnTracer()
|
||||
{
|
||||
ComponentWrapper cTeam = m_Entity["Team"];
|
||||
ComponentInfo::EnumType team = cTeam["Team"];
|
||||
|
||||
// Select the right color of effect
|
||||
EntityFile* rayFile = nullptr;
|
||||
if (team == cTeam["Team"].Enum("Red")) {
|
||||
rayFile = m_RayRed;
|
||||
}
|
||||
if (team == cTeam["Team"].Enum("Blue")) {
|
||||
rayFile = m_RayBlue;
|
||||
}
|
||||
if (rayFile == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the entity
|
||||
EntityFileParser parser(rayFile);
|
||||
EntityID rayID = parser.MergeEntities(m_World);
|
||||
EntityWrapper ray(m_World, rayID);
|
||||
|
||||
// Figure out where to put it
|
||||
EntityWrapper attachment;
|
||||
if (m_Entity == LocalPlayer || true) {
|
||||
// Spawn the effect from the weapon view model for the local player
|
||||
attachment = m_Entity.FirstChildByName("WeaponMuzzle");
|
||||
}
|
||||
// TODO: Spawn the effect from the weapon world model once it exists
|
||||
|
||||
glm::mat4 transformation = Transform::AbsoluteTransformation(attachment);
|
||||
glm::vec3 _scale;
|
||||
glm::vec3 translation;
|
||||
glm::quat _orientation;
|
||||
glm::vec3 _skew;
|
||||
glm::vec4 _perspective;
|
||||
glm::decompose(transformation, _scale, _orientation, translation, _skew, _perspective);
|
||||
|
||||
// Matrix to euler angles
|
||||
glm::vec3 euler;
|
||||
euler.y = glm::asin(-transformation[0][2]);
|
||||
if (cos(euler.y) != 0) {
|
||||
euler.x = atan2(transformation[1][2], transformation[2][2]);
|
||||
euler.z = atan2(transformation[0][1], transformation[0][0]);
|
||||
} else {
|
||||
euler.x = atan2(-transformation[2][0], transformation[1][1]);
|
||||
euler.z = 0;
|
||||
}
|
||||
|
||||
// TODO: Spread?
|
||||
|
||||
(glm::vec3&)ray["Transform"]["Position"] = translation;
|
||||
(glm::vec3&)ray["Transform"]["Orientation"] = euler;
|
||||
glm::vec3& scale = ray["Transform"]["Scale"];
|
||||
scale.z = traceRayDistance(translation, glm::quat(euler) * glm::vec3(0.f, 0.f, -1.f));
|
||||
}
|
||||
|
||||
float traceRayDistance(glm::vec3 origin, glm::vec3 direction)
|
||||
{
|
||||
OctSpace::Output result;
|
||||
if (m_CollisionOctree->RayCollides(Ray(origin, direction), result)) {
|
||||
return result.CollideDistance;
|
||||
} else {
|
||||
return 0.f;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user