From 5cea3bed3a578c5fd6d56bc14cfae1527d966ec0 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 9 Feb 2016 23:27:04 +0100 Subject: [PATCH] Work in progress weapon system --- include/Game/Systems/WeaponSystem.h | 93 +++++++++++++++++-- resources/DefaultInput.ini | 2 + resources/Schema/Components.xsd | 1 + resources/Schema/Components/AssaultWeapon.xml | 8 ++ resources/Schema/Components/AssaultWeapon.xsd | 27 ++++++ resources/Schema/Types/Entity.xsd | 1 + src/Game/Systems/WeaponSystem.cpp | 40 +++++++- 7 files changed, 164 insertions(+), 8 deletions(-) create mode 100755 resources/Schema/Components/AssaultWeapon.xml create mode 100755 resources/Schema/Components/AssaultWeapon.xsd diff --git a/include/Game/Systems/WeaponSystem.h b/include/Game/Systems/WeaponSystem.h index d6525377..fccb1b0b 100644 --- a/include/Game/Systems/WeaponSystem.h +++ b/include/Game/Systems/WeaponSystem.h @@ -9,29 +9,108 @@ #include "Core/System.h" #include "Core/EPlayerDamage.h" #include "Core/EShoot.h" +#include "Core/EPlayerSpawned.h" #include "Input/EInputCommand.h" #include "Core/EntityFile.h" #include "Core/EntityFileParser.h" -#include -#include - - -class WeaponSystem : public ImpureSystem +class WeaponSystem : public PureSystem, ImpureSystem { public: WeaponSystem(SystemParams params, IRenderer* renderer); virtual void Update(double dt) override; + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) override; private: IRenderer* m_Renderer; + std::unordered_map> m_ActiveWeapons; + // Events + EventRelay m_EPlayerSpawned; + bool OnPlayerSpawned(Events::PlayerSpawned& e); EventRelay m_EShoot; - bool WeaponSystem::OnShoot(Events::Shoot& e); + bool OnShoot(Events::Shoot& e); EventRelay m_EInputCommand; - bool WeaponSystem::OnInputCommand(Events::InputCommand& e); + bool OnInputCommand(Events::InputCommand& e); + + void selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot); +}; + +class WeaponBehaviour +{ +public: + WeaponBehaviour(EntityWrapper weaponEntity) + : m_Entity(weaponEntity) + { } + + virtual void Fire() = 0; + virtual void CeaseFire() { } + virtual void Reload() { } + virtual void Update(double dt) { } + +protected: + EntityWrapper m_Entity; +}; + +class AssaultWeaponBehaviour : public WeaponBehaviour +{ +public: + AssaultWeaponBehaviour(EntityWrapper weaponEntity) + : WeaponBehaviour(weaponEntity) + { } + + virtual void Fire() override + { + m_TimeSinceLastFire = 0.0; + m_Firing = true; + fireRound(); + } + + virtual void CeaseFire() override + { + m_Firing = false; + } + + virtual void Update(double dt) override + { + if (!m_Firing) { + return; + } + + m_TimeSinceLastFire += dt; + + ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; + if (m_TimeSinceLastFire > (double)cAssaultWeapon["RPM"] / 60.0) { + fireRound(); + } + } + +private: + bool m_Firing = false; + double m_TimeSinceLastFire = 0.0; + ComponentWrapper m_Component; + + void fireRound() + { + ComponentWrapper& cAssaultWeapon = m_Entity["AssaultWeapon"]; + + 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(); + return; + } + + // Fire + magAmmo -= 1; + + m_TimeSinceLastFire = 0.0; + } }; #endif \ No newline at end of file diff --git a/resources/DefaultInput.ini b/resources/DefaultInput.ini index a3f7d166..167226de 100644 --- a/resources/DefaultInput.ini +++ b/resources/DefaultInput.ini @@ -14,6 +14,8 @@ R=Reload Space=Jump LeftControl=Crouch LeftShift=Sprint +1=SelectWeapon,1 +2=SelectWeapon,2 F1=ToggleEditor C=ConnectToServer N=SwitchToServer diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 265a3cc5..1d5b05f6 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -31,4 +31,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/AssaultWeapon.xml b/resources/Schema/Components/AssaultWeapon.xml new file mode 100755 index 00000000..8dc2a50a --- /dev/null +++ b/resources/Schema/Components/AssaultWeapon.xml @@ -0,0 +1,8 @@ + + + 32 + 32 + 360 + 360 + 40 + \ No newline at end of file diff --git a/resources/Schema/Components/AssaultWeapon.xsd b/resources/Schema/Components/AssaultWeapon.xsd new file mode 100755 index 00000000..167fee18 --- /dev/null +++ b/resources/Schema/Components/AssaultWeapon.xsd @@ -0,0 +1,27 @@ + + + + + + + + + + Ammo currently loaded into the magazine + + + Max number of rounds in a magazine + + + Current ammo carried + + + Maximum ammo able to be carried + + + Rate of fire in rounds per minute + + + + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 028af9e6..3eed11f3 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -38,6 +38,7 @@ + diff --git a/src/Game/Systems/WeaponSystem.cpp b/src/Game/Systems/WeaponSystem.cpp index a650a6b7..fe0f066f 100644 --- a/src/Game/Systems/WeaponSystem.cpp +++ b/src/Game/Systems/WeaponSystem.cpp @@ -2,6 +2,7 @@ WeaponSystem::WeaponSystem(SystemParams params, IRenderer* renderer) : System(params) + , PureSystem("Player") , ImpureSystem() , m_Renderer(renderer) { @@ -14,8 +15,23 @@ void WeaponSystem::Update(double dt) } +void WeaponSystem::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cComponent, double dt) +{ + +} + bool WeaponSystem::OnInputCommand(Events::InputCommand& e) { + // Make sure player is alive + if (!e.Player.Valid()) { + return false; + } + + // Weapon selection + if (e.Command == "SelectWeapon") { + selectWeapon(e.Player, static_cast(e.Value)); + } + // Only shoot client-side! if (!IsClient) { return false; @@ -39,7 +55,29 @@ bool WeaponSystem::OnInputCommand(Events::InputCommand& e) return true; } -bool WeaponSystem::OnShoot(Events::Shoot& eShoot) +void WeaponSystem::selectWeapon(EntityWrapper player, ComponentInfo::EnumType slot) +{ + // Primary + if (slot == 1) { + // TODO: if class... + m_ActiveWeapons[player] = std::make_shared(); + } + + // Secondary + if (slot == 2) { + //m_ActiveWeapons[player] = std::make_shared(); + } +} + +bool WeaponSystem::OnPlayerSpawned(Events::PlayerSpawned& e) +{ + // Select primary weapon on player spawn + // TODO: Select the active one specified by player component + selectWeapon(e.Player, 1); + return true; +} + +bool WeaponSystem::OnShoot(Events::Shoot& eShoot) { if (!eShoot.Player.Valid()) { return false;