From b431a875f75c741b0ecd5576b1819a2331ae5a85 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 1 Mar 2016 13:26:50 +0100 Subject: [PATCH 1/5] New weapon behaviours --- .../Systems/Weapon/DefenderWeaponBehaviour.h | 12 +-- .../Systems/Weapon/SidearmWeaponBehaviour.h | 32 ++++++++ include/Game/Systems/Weapon/WeaponBehaviour.h | 74 ++++++++++++------- resources/Schema/Components.xsd | 1 + .../Schema/Components/DefenderWeapon.xsd | 12 +++ resources/Schema/Components/SidearmWeapon.xml | 14 ++++ resources/Schema/Components/SidearmWeapon.xsd | 48 ++++++++++++ resources/Schema/Entities/Player.xml | 8 +- resources/Schema/Types/Entity.xsd | 1 + src/Engine/Rendering/Renderer.cpp | 2 +- .../Weapon/DefenderWeaponBehaviour.cpp | 24 +++--- .../Systems/Weapon/SidearmWeaponBehaviour.cpp | 58 +++++++++++++++ 12 files changed, 232 insertions(+), 54 deletions(-) create mode 100644 include/Game/Systems/Weapon/SidearmWeaponBehaviour.h create mode 100644 resources/Schema/Components/SidearmWeapon.xml create mode 100644 resources/Schema/Components/SidearmWeapon.xsd create mode 100644 src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp diff --git a/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h b/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h index 5ca13d3e..986d8586 100644 --- a/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h +++ b/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h @@ -15,10 +15,10 @@ public: } void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt) override; - void UpdateWeapon(WeaponInfo& wi, double dt) override; - void OnPrimaryFire(WeaponInfo& wi) override; - void OnCeasePrimaryFire(WeaponInfo& wi) override; - bool OnInputCommand(WeaponInfo& wi, const Events::InputCommand& e) override; + void UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) override; + void OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override; + void OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override; + bool OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e) override; private: std::random_device m_RandomDevice; @@ -29,8 +29,8 @@ private: bool OnSetCamera(const Events::SetCamera& e); // Weapon functions - void fireShell(WeaponInfo& wi); - void dealDamage(WeaponInfo& wi, glm::vec3 direction, double damage); + void fireShell(ComponentWrapper cWeapon, WeaponInfo& wi); + void dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi, glm::vec3 direction, double damage); // Utility float traceRayDistance(glm::vec3 origin, glm::vec3 direction); diff --git a/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h b/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h new file mode 100644 index 00000000..787c3c61 --- /dev/null +++ b/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h @@ -0,0 +1,32 @@ +#include "WeaponBehaviour.h" +#include "Collision/Collision.h" +#include "Core/EPlayerDamage.h" + +class SidearmWeaponBehaviour : public WeaponBehaviour +{ +public: + SidearmWeaponBehaviour(SystemParams systemParams, IRenderer* renderer, Octree* collisionOctree) + : System(systemParams) + , WeaponBehaviour(systemParams, "SidearmWeapon", renderer, collisionOctree) + , m_RandomEngine(m_RandomDevice()) + { } + + void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt) override; + void UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) override; + void OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override; + void OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override; + void OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) override; + +private: + std::random_device m_RandomDevice; + std::mt19937 m_RandomEngine; + EntityWrapper m_CurrentCamera; + + // Weapon functions + void fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi); + //void dealDamage(WeaponInfo& wi, glm::vec3 direction, double damage); + + // Utility + bool canFire(ComponentWrapper cWeapon); + //float traceRayDistance(glm::vec3 origin, glm::vec3 direction); +}; \ No newline at end of file diff --git a/include/Game/Systems/Weapon/WeaponBehaviour.h b/include/Game/Systems/Weapon/WeaponBehaviour.h index f23269df..2ab53e0e 100644 --- a/include/Game/Systems/Weapon/WeaponBehaviour.h +++ b/include/Game/Systems/Weapon/WeaponBehaviour.h @@ -24,36 +24,35 @@ public: } virtual ~WeaponBehaviour() = default; - virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& component, double dt) override + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt) override { auto weapon = getActiveWeapon(entity); if (!weapon) { return; } else { - UpdateWeapon(*weapon, dt); + UpdateWeapon(cWeapon, *weapon, dt); } } protected: struct WeaponInfo { - std::string WeaponComponent; EntityWrapper Player; EntityWrapper WeaponEntity; EntityWrapper FirstPersonEntity; EntityWrapper ThirdPersonEntity; - ComponentWrapper GetComponent() { return WeaponEntity[WeaponComponent]; } }; IRenderer* m_Renderer; Octree* m_CollisionOctree; std::unordered_map m_ActiveWeapons; - virtual void UpdateWeapon(WeaponInfo& wi, double dt) { } - virtual void OnPrimaryFire(WeaponInfo& wi) { } - virtual void OnCeasePrimaryFire(WeaponInfo& wi) { } - virtual void OnReload(WeaponInfo& wi) { } - virtual bool OnInputCommand(WeaponInfo& wi, const Events::InputCommand& e) { return false; } + virtual void UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) { } + virtual void OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) { } + virtual void OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) { } + virtual void OnReload(ComponentWrapper cWeapon, WeaponInfo& wi) { } + virtual void OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) { } + virtual bool OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e) { return false; } private: EventRelay m_EInputCommand; @@ -70,15 +69,19 @@ private: } // Make sure the player has this weapon - auto weapon = getWeaponComponent(player); - if (!weapon) { + auto cWeapon = getWeaponComponent(player); + if (!cWeapon) { return false; } // Weapon selection if (e.Command == "SelectWeapon") { - if (static_cast(e.Value) == static_cast((*weapon)["Slot"])) { - selectWeapon(player); + if (e.Value > 0) { + if (static_cast(e.Value) == static_cast((*cWeapon)["Slot"])) { + selectWeapon(player); + } else { + holsterWeapon(*cWeapon, player); + } } } @@ -91,18 +94,18 @@ private: // Fire if (e.Command == "PrimaryFire") { if (e.Value > 0) { - OnPrimaryFire(*activeWeapon); + OnPrimaryFire(*cWeapon, *activeWeapon); } else { - OnCeasePrimaryFire(*activeWeapon); + OnCeasePrimaryFire(*cWeapon, *activeWeapon); } } // Reload if (e.Command == "Reload" && e.Value != 0) { - OnReload(*activeWeapon); + OnReload(*cWeapon, *activeWeapon); } - return OnInputCommand(*activeWeapon, e); + return OnInputCommand(*cWeapon, *activeWeapon, e); } boost::optional getWeaponComponent(EntityWrapper player) @@ -131,6 +134,11 @@ private: void selectWeapon(EntityWrapper player) { + // Don't reselect weapon if it's already active + if (getActiveWeapon(player)) { + return; + } + // Find the weapon attachments matching the weapon type std::vector weaponAttachments = player.ChildrenWithComponent("WeaponAttachment"); EntityWrapper firstPersonAttachment; @@ -152,14 +160,6 @@ private: return; } - // Purge other weapon entities - for (auto& attachment : weaponAttachments) { - //if (attachment == firstPersonAttachment || attachment == thirdPersonAttachment) { - // continue; - //} - attachment.DeleteChildren(); - } - // Spawn the weapon(s) EntityWrapper firstPersonWeapon; EntityWrapper thirdPersonWeapon; @@ -170,12 +170,34 @@ private: thirdPersonWeapon = SpawnerSystem::Spawn(thirdPersonAttachment, thirdPersonAttachment); } - m_ActiveWeapons[player].WeaponComponent = m_ComponentType; m_ActiveWeapons[player].Player = player; m_ActiveWeapons[player].WeaponEntity = player; m_ActiveWeapons[player].FirstPersonEntity = firstPersonWeapon; m_ActiveWeapons[player].ThirdPersonEntity = thirdPersonWeapon; } + + void holsterWeapon(ComponentWrapper cWeapon, EntityWrapper player) + { + auto activeWeapon = getActiveWeapon(player); + if (!activeWeapon) { + return; + } + WeaponInfo& wi = *activeWeapon; + + // Send holster event + OnHolster(cWeapon, wi); + + // Delete weapon entities + if (wi.FirstPersonEntity.Valid()) { + m_World->DeleteEntity(wi.FirstPersonEntity.ID); + } + if (wi.ThirdPersonEntity.Valid()) { + m_World->DeleteEntity(wi.ThirdPersonEntity.ID); + } + + // Make weapon inactive + m_ActiveWeapons.erase(player); + } }; #endif diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 0c8886f3..711f4999 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -54,6 +54,7 @@ + diff --git a/resources/Schema/Components/DefenderWeapon.xsd b/resources/Schema/Components/DefenderWeapon.xsd index 3fe5a64a..0ec61964 100755 --- a/resources/Schema/Components/DefenderWeapon.xsd +++ b/resources/Schema/Components/DefenderWeapon.xsd @@ -4,6 +4,18 @@ + + + + + + + + + + + + diff --git a/resources/Schema/Components/SidearmWeapon.xml b/resources/Schema/Components/SidearmWeapon.xml new file mode 100644 index 00000000..b63706b6 --- /dev/null +++ b/resources/Schema/Components/SidearmWeapon.xml @@ -0,0 +1,14 @@ + + + 16 + 16 + 20 + 120 + 0.01 + 0.5 + + false + 0 + false + 0 + \ No newline at end of file diff --git a/resources/Schema/Components/SidearmWeapon.xsd b/resources/Schema/Components/SidearmWeapon.xsd new file mode 100644 index 00000000..844b449f --- /dev/null +++ b/resources/Schema/Components/SidearmWeapon.xsd @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + Ammo currently loaded into the magazine + + + Max number of rounds in a magazine + + + Damage dealt if all shotgun pellets hit + + + Rate of fire in rounds per minute + + + View punch in radians for each shell fired + + + Time it takes to load ONE SHELL into the weapon in seconds + + + + + + + + + + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 34692605..d157c99e 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -6,11 +6,6 @@ - - - - - 52.867678870419283 @@ -488,9 +483,10 @@ AssaultWeapon - Schema/Entities/AssaultWeaponView.xml + Schema/Entities/SidearmWeaponView.xml + SidearmWeapon diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 57445a15..f9870a51 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -52,6 +52,7 @@ + diff --git a/src/Engine/Rendering/Renderer.cpp b/src/Engine/Rendering/Renderer.cpp index 3ce985b6..7e11f3b2 100644 --- a/src/Engine/Rendering/Renderer.cpp +++ b/src/Engine/Rendering/Renderer.cpp @@ -17,7 +17,7 @@ void Renderer::Initialize() m_TextPass->Initialize(); /* m_ScreenQuad = ResourceManager::Load("Models/Core/ScreenQuad.obj"); - m_UnitQuad = ResourceManager::Load("Models/Core/UnitQuad.obj"); + m_UnitQuad = ResourceManager::Load(sModels/Core/UnitQuad.obj"); m_UnitSphere = ResourceManager::Load("Models/Core/UnitSphere.obj");*/ m_ImGuiRenderPass = new ImGuiRenderPass(this, m_EventBroker); diff --git a/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp b/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp index 028bd10c..0a179b4c 100644 --- a/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp @@ -6,36 +6,32 @@ void DefenderWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWr WeaponBehaviour::UpdateComponent(entity, cWeapon, dt); } -void DefenderWeaponBehaviour::UpdateWeapon(WeaponInfo& wi, double dt) +void DefenderWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) { - ComponentWrapper cWeapon = wi.GetComponent(); - bool isFiring = cWeapon["IsFiring"]; bool cooldownPassed = (double)cWeapon["TimeSinceLastFire"] >= (60.0 / (double)cWeapon["RPM"]); bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0; if (isFiring && cooldownPassed && isNotShielding) { - fireShell(wi); + fireShell(cWeapon, wi); } } -void DefenderWeaponBehaviour::OnPrimaryFire(WeaponInfo& wi) +void DefenderWeaponBehaviour::OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) { - ComponentWrapper cWeapon = wi.GetComponent(); cWeapon["IsFiring"] = true; bool cooldownPassed = (double)cWeapon["TimeSinceLastFire"] >= (60.0 / (double)cWeapon["RPM"]); bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0; if (cooldownPassed && isNotShielding) { - fireShell(wi); + fireShell(cWeapon, wi); } } -void DefenderWeaponBehaviour::OnCeasePrimaryFire(WeaponInfo& wi) +void DefenderWeaponBehaviour::OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) { - ComponentWrapper cWeapon = wi.GetComponent(); cWeapon["IsFiring"] = false; } -bool DefenderWeaponBehaviour::OnInputCommand(WeaponInfo& wi, const Events::InputCommand& e) +bool DefenderWeaponBehaviour::OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e) { if (e.Command == "SpecialAbility" && IsServer) { EntityWrapper attachment = wi.Player.FirstChildByName("ShieldAttachment"); @@ -57,10 +53,8 @@ bool DefenderWeaponBehaviour::OnSetCamera(const Events::SetCamera& e) return true; } -void DefenderWeaponBehaviour::fireShell(WeaponInfo& wi) +void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi) { - ComponentWrapper cWeapon = wi.GetComponent(); - cWeapon["TimeSinceLastFire"] = 0.0; int numPellets = cWeapon["NumPellets"]; float spreadAngle = cWeapon["SpreadAngle"]; @@ -95,13 +89,13 @@ void DefenderWeaponBehaviour::fireShell(WeaponInfo& wi) orientation.x += angles.x; orientation.y += angles.y; glm::vec3 trajectory = direction * distance; - dealDamage(wi, direction, pelletDamage); + dealDamage(cWeapon, wi, direction, pelletDamage); } } } -void DefenderWeaponBehaviour::dealDamage(WeaponInfo& wi, glm::vec3 direction, double damage) +void DefenderWeaponBehaviour::dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi, glm::vec3 direction, double damage) { // Only deal damage client side if (!IsClient) { diff --git a/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp b/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp new file mode 100644 index 00000000..8c3906af --- /dev/null +++ b/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp @@ -0,0 +1,58 @@ +#include "Systems/Weapon/SidearmWeaponBehaviour.h" + +void SidearmWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt) +{ + double& cooldown = cWeapon["FireCooldown"]; + if (cooldown > 0) { + cooldown -= dt; + if (cooldown < 0) { + cooldown = 0; + } + } + WeaponBehaviour::UpdateComponent(entity, cWeapon, dt); +} + +void SidearmWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) +{ + if (canFire(cWeapon)) { + fireBullet(cWeapon, wi); + } +} + +void SidearmWeaponBehaviour::OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + cWeapon["TriggerHeld"] = true; + if (canFire(cWeapon)) { + fireBullet(cWeapon, wi); + } +} + +void SidearmWeaponBehaviour::OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + cWeapon["TriggerHeld"] = false; +} + +void SidearmWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + // Make sure the trigger is released if weapon is holstered while firing + cWeapon["TriggerHeld"] = false; + + // Cancel any reload + cWeapon["IsReloading"] = false; + cWeapon["ReloadTimer"] = 0.0; + + LOG_DEBUG("HOLSTER"); +} + +void SidearmWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + +} + +bool SidearmWeaponBehaviour::canFire(ComponentWrapper cWeapon) +{ + bool triggerHeld = cWeapon["TriggerHeld"]; + double& cooldown = cWeapon["FireCooldown"]; + // TODO: Ammo checks + return triggerHeld && cooldown <= 0.0; +} \ No newline at end of file From 6f8023b285d260f68efd9ac615b702721e8ae0b4 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 1 Mar 2016 16:35:30 +0100 Subject: [PATCH 2/5] HACK: Added Activate button for spawners in editor. Right now it includes the event from Game, but SpawnerSystem should probably be moved to Engine. --- include/Engine/Editor/EditorGUI.h | 1 + src/Engine/Editor/EditorGUI.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/include/Engine/Editor/EditorGUI.h b/include/Engine/Editor/EditorGUI.h index 57574e66..807bfc8b 100644 --- a/include/Engine/Editor/EditorGUI.h +++ b/include/Engine/Editor/EditorGUI.h @@ -22,6 +22,7 @@ #include "../Core/ELockMouse.h" #include "../Core/EFileDropped.h" #include "../Rendering/Texture.h" +#include "Game/Events/ESpawnerSpawn.h" class EditorGUI { diff --git a/src/Engine/Editor/EditorGUI.cpp b/src/Engine/Editor/EditorGUI.cpp index 8ce15d0a..a1ceafd0 100644 --- a/src/Engine/Editor/EditorGUI.cpp +++ b/src/Engine/Editor/EditorGUI.cpp @@ -338,6 +338,15 @@ bool EditorGUI::drawComponentNode(EntityWrapper entity, const ComponentInfo& ci) } } + if (ci.Name == "Spawner") { + if (ImGui::Button("Activate")) { + Events::SpawnerSpawn e; + e.Spawner = entity; + e.Parent = entity; + m_EventBroker->Publish(e); + } + } + return true; } From afd0e69a8a9a0c2050429277b77ab85308731f21 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 1 Mar 2016 16:35:54 +0100 Subject: [PATCH 3/5] Updated Player.xml for multiple weapons --- .../Schema/Entities/DefenderWeaponView.xml | 8 ++--- resources/Schema/Entities/Player.xml | 30 ++++++++++++++----- .../Schema/Entities/SidearmWeaponView.xml | 27 +++++++++++++++++ .../Schema/Entities/SidearmWeaponWorld.xml | 27 +++++++++++++++++ src/Game/Game.cpp | 2 ++ 5 files changed, 81 insertions(+), 13 deletions(-) create mode 100644 resources/Schema/Entities/SidearmWeaponView.xml create mode 100644 resources/Schema/Entities/SidearmWeaponWorld.xml diff --git a/resources/Schema/Entities/DefenderWeaponView.xml b/resources/Schema/Entities/DefenderWeaponView.xml index f6b6e89d..b65194f9 100755 --- a/resources/Schema/Entities/DefenderWeaponView.xml +++ b/resources/Schema/Entities/DefenderWeaponView.xml @@ -1,16 +1,12 @@ - + - - R_Arm_Weapon_Joint - - Models/Weapons/Blue/DefenderGunBlue.mesh - + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index d157c99e..394f4622 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -11,6 +11,7 @@ 52.867678870419283 + @@ -453,7 +454,7 @@ Idle - 1.9408570429715581 + 0.022133545026491674 1 @@ -467,26 +468,38 @@ + + R_Arm_Weapon_Joint + DefenderWeapon Schema/Entities/DefenderWeaponView.xml - + + + + + + R_Arm_Weapon_Joint + AssaultWeapon + SidearmWeapon Schema/Entities/SidearmWeaponView.xml - - SidearmWeapon + + + + @@ -515,7 +528,7 @@ Idle - 1.5631122524686134 + 0.13373697879978863 1 @@ -550,14 +563,17 @@ + + R_Arm_Weapon_Joint + - AssaultWeapon + SidearmWeapon - Schema/Entities/AssaultWeaponWorld.xml + Schema/Entities/SidearmWeaponWorld.xml diff --git a/resources/Schema/Entities/SidearmWeaponView.xml b/resources/Schema/Entities/SidearmWeaponView.xml new file mode 100644 index 00000000..68d29676 --- /dev/null +++ b/resources/Schema/Entities/SidearmWeaponView.xml @@ -0,0 +1,27 @@ + + + + + + Models/Weapons/SecondaryWeapon.mesh + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + diff --git a/resources/Schema/Entities/SidearmWeaponWorld.xml b/resources/Schema/Entities/SidearmWeaponWorld.xml new file mode 100644 index 00000000..21cb26a7 --- /dev/null +++ b/resources/Schema/Entities/SidearmWeaponWorld.xml @@ -0,0 +1,27 @@ + + + + + + Models/Weapons/SecondaryWeapon.mesh + + + + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 21f5c901..7607efec 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -19,6 +19,7 @@ #include "Game/Systems/AmmoPickupSystem.h" #include "Game/Systems/DamageIndicatorSystem.h" #include "Game/Systems/Weapon/DefenderWeaponBehaviour.h" +#include "Game/Systems/Weapon/SidearmWeaponBehaviour.h" #include "Rendering/AnimationSystem.h" #include "Game/Systems/HealthHUDSystem.h" #include "Rendering/BoneAttachmentSystem.h" @@ -128,6 +129,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_OctreeCollision); + m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_OctreeCollision); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); From 13546aa3fc3e24a0744f12e89aa1e2191f13a334 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 1 Mar 2016 22:37:19 +0100 Subject: [PATCH 4/5] DefenderWeapon and SidearmWeapon --- .../Systems/Weapon/DefenderWeaponBehaviour.h | 12 +-- .../Systems/Weapon/SidearmWeaponBehaviour.h | 3 +- include/Game/Systems/Weapon/WeaponBehaviour.h | 57 +++++++++-- .../Schema/Components/DefenderWeapon.xml | 6 +- .../Schema/Components/DefenderWeapon.xsd | 6 +- resources/Schema/Components/SidearmWeapon.xml | 4 +- resources/Schema/Components/SidearmWeapon.xsd | 6 +- resources/Schema/Entities/Player.xml | 14 +-- resources/Schema/Entities/Ray2Red | 18 ++++ resources/Schema/Entities/Ray2Red.xml | 43 ++++++++ .../Schema/Entities/SidearmWeaponView.xml | 63 +++++++++++- src/Engine/Editor/EditorGUI.cpp | 52 ++++++++-- .../Weapon/DefenderWeaponBehaviour.cpp | 98 ++++++++++++++----- .../Systems/Weapon/SidearmWeaponBehaviour.cpp | 23 ++++- 14 files changed, 340 insertions(+), 65 deletions(-) create mode 100644 resources/Schema/Entities/Ray2Red create mode 100644 resources/Schema/Entities/Ray2Red.xml diff --git a/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h b/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h index 986d8586..c1e132b1 100644 --- a/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h +++ b/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h @@ -1,7 +1,6 @@ #include "WeaponBehaviour.h" #include "Collision/Collision.h" #include "Core/EPlayerDamage.h" -#include "Rendering/ESetCamera.h" class DefenderWeaponBehaviour : public WeaponBehaviour { @@ -10,29 +9,24 @@ public: : System(systemParams) , WeaponBehaviour(systemParams, "DefenderWeapon", renderer, collisionOctree) , m_RandomEngine(m_RandomDevice()) - { - EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &DefenderWeaponBehaviour::OnSetCamera); - } + { } void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt) override; void UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) override; void OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override; void OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override; + void OnReload(ComponentWrapper cWeapon, WeaponInfo& wi) override; bool OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e) override; private: std::random_device m_RandomDevice; std::mt19937 m_RandomEngine; - EntityWrapper m_CurrentCamera; - - EventRelay m_ESetCamera; - bool OnSetCamera(const Events::SetCamera& e); // Weapon functions void fireShell(ComponentWrapper cWeapon, WeaponInfo& wi); void dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi, glm::vec3 direction, double damage); + bool canFire(ComponentWrapper cWeapon, WeaponInfo& wi); // Utility - float traceRayDistance(glm::vec3 origin, glm::vec3 direction); Camera cameraFromEntity(EntityWrapper camera); }; \ No newline at end of file diff --git a/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h b/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h index 787c3c61..d221b8bb 100644 --- a/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h +++ b/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h @@ -15,12 +15,12 @@ public: void UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) override; void OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override; void OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override; + void OnEquip(ComponentWrapper cWeapon, WeaponInfo& wi) override; void OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) override; private: std::random_device m_RandomDevice; std::mt19937 m_RandomEngine; - EntityWrapper m_CurrentCamera; // Weapon functions void fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi); @@ -28,5 +28,6 @@ private: // Utility bool canFire(ComponentWrapper cWeapon); + bool playerInFirstPerson(EntityWrapper player); //float traceRayDistance(glm::vec3 origin, glm::vec3 direction); }; \ No newline at end of file diff --git a/include/Game/Systems/Weapon/WeaponBehaviour.h b/include/Game/Systems/Weapon/WeaponBehaviour.h index 2ab53e0e..e0783bd2 100644 --- a/include/Game/Systems/Weapon/WeaponBehaviour.h +++ b/include/Game/Systems/Weapon/WeaponBehaviour.h @@ -7,6 +7,7 @@ #include "Collision/EntityAABB.h" #include "Input/EInputCommand.h" #include "Systems/SpawnerSystem.h" +#include "Rendering/ESetCamera.h" template class WeaponBehaviour : public PureSystem @@ -21,6 +22,7 @@ public: , m_CollisionOctree(collisionOctree) { EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponBehaviour::_OnInputCommand) + EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &WeaponBehaviour::_OnSetCamera) } virtual ~WeaponBehaviour() = default; @@ -44,6 +46,7 @@ protected: }; IRenderer* m_Renderer; + EntityWrapper m_CurrentCamera; Octree* m_CollisionOctree; std::unordered_map m_ActiveWeapons; @@ -51,10 +54,49 @@ protected: virtual void OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) { } virtual void OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) { } virtual void OnReload(ComponentWrapper cWeapon, WeaponInfo& wi) { } + virtual void OnEquip(ComponentWrapper cWeapon, WeaponInfo& wi) { } virtual void OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) { } virtual bool OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e) { return false; } + bool isPlayerInFirstPerson(EntityWrapper player) + { + if (!m_CurrentCamera.Valid()) { + return false; + } else { + return m_CurrentCamera == player || m_CurrentCamera.IsChildOf(player); + } + } + + // Returns wi.FirstPersonEntity or wi.ThirdPersonEntity depending on + // if the player is in first person mode or not. + EntityWrapper getRelevantWeaponModelEntity(WeaponInfo& wi) + { + if (isPlayerInFirstPerson(wi.Player)) { + return wi.FirstPersonEntity; + } else { + return wi.ThirdPersonEntity; + } + } + + float traceRayDistance(glm::vec3 origin, glm::vec3 direction) + { + float distance; + glm::vec3 pos; + auto entity = Collision::EntityFirstHitByRay(Ray(origin, direction), m_CollisionOctree, distance, pos); + if (entity) { + return distance; + } else { + return 100.f; + } + } + private: + EventRelay m_ESetCamera; + bool _OnSetCamera(const Events::SetCamera& e) + { + m_CurrentCamera = e.CameraEntity; + return true; + } EventRelay m_EInputCommand; bool _OnInputCommand(const Events::InputCommand& e) { @@ -78,7 +120,7 @@ private: if (e.Command == "SelectWeapon") { if (e.Value > 0) { if (static_cast(e.Value) == static_cast((*cWeapon)["Slot"])) { - selectWeapon(player); + selectWeapon(*cWeapon, player); } else { holsterWeapon(*cWeapon, player); } @@ -132,7 +174,7 @@ private: return activeWeapon; } - void selectWeapon(EntityWrapper player) + void selectWeapon(ComponentWrapper cWeapon, EntityWrapper player) { // Don't reselect weapon if it's already active if (getActiveWeapon(player)) { @@ -170,10 +212,13 @@ private: thirdPersonWeapon = SpawnerSystem::Spawn(thirdPersonAttachment, thirdPersonAttachment); } - m_ActiveWeapons[player].Player = player; - m_ActiveWeapons[player].WeaponEntity = player; - m_ActiveWeapons[player].FirstPersonEntity = firstPersonWeapon; - m_ActiveWeapons[player].ThirdPersonEntity = thirdPersonWeapon; + WeaponInfo& wi = m_ActiveWeapons[player]; + wi.Player = player; + wi.WeaponEntity = player; + wi.FirstPersonEntity = firstPersonWeapon; + wi.ThirdPersonEntity = thirdPersonWeapon; + + OnEquip(cWeapon, wi); } void holsterWeapon(ComponentWrapper cWeapon, EntityWrapper player) diff --git a/resources/Schema/Components/DefenderWeapon.xml b/resources/Schema/Components/DefenderWeapon.xml index 998f3bde..1b336fc4 100755 --- a/resources/Schema/Components/DefenderWeapon.xml +++ b/resources/Schema/Components/DefenderWeapon.xml @@ -11,6 +11,8 @@ 0.01 0.5 - false - 0 + false + 0 + false + 0 \ No newline at end of file diff --git a/resources/Schema/Components/DefenderWeapon.xsd b/resources/Schema/Components/DefenderWeapon.xsd index 0ec61964..c1b98e2f 100755 --- a/resources/Schema/Components/DefenderWeapon.xsd +++ b/resources/Schema/Components/DefenderWeapon.xsd @@ -48,8 +48,10 @@ Time it takes to load ONE SHELL into the weapon in seconds - - + + + + diff --git a/resources/Schema/Components/SidearmWeapon.xml b/resources/Schema/Components/SidearmWeapon.xml index b63706b6..1d503ecc 100644 --- a/resources/Schema/Components/SidearmWeapon.xml +++ b/resources/Schema/Components/SidearmWeapon.xml @@ -3,9 +3,11 @@ 16 16 20 - 120 + 500 + false 0.01 0.5 + 0.5 false 0 diff --git a/resources/Schema/Components/SidearmWeapon.xsd b/resources/Schema/Components/SidearmWeapon.xsd index 844b449f..bafb9de2 100644 --- a/resources/Schema/Components/SidearmWeapon.xsd +++ b/resources/Schema/Components/SidearmWeapon.xsd @@ -23,7 +23,7 @@ Ammo currently loaded into the magazine - Max number of rounds in a magazine + Max number of rounds in a magazine Damage dealt if all shotgun pellets hit @@ -31,12 +31,16 @@ Rate of fire in rounds per minute + View punch in radians for each shell fired Time it takes to load ONE SHELL into the weapon in seconds + + Time it takes from selecting the weapon until it's ready to fire + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 394f4622..5c5efc07 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -8,7 +8,7 @@ - 52.867678870419283 + 102.85760837900634 @@ -454,7 +454,7 @@ Idle - 0.022133545026491674 + 1.8348644854054612 1 @@ -478,8 +478,8 @@ Schema/Entities/DefenderWeaponView.xml - - + + @@ -497,8 +497,8 @@ Schema/Entities/SidearmWeaponView.xml - - + + @@ -528,7 +528,7 @@ Idle - 0.13373697879978863 + 0.013134522267137072 1 diff --git a/resources/Schema/Entities/Ray2Red b/resources/Schema/Entities/Ray2Red new file mode 100644 index 00000000..813443b2 --- /dev/null +++ b/resources/Schema/Entities/Ray2Red @@ -0,0 +1,18 @@ + + + + + + Textures/Effects/Ray.png + + + + + + + + + + + + diff --git a/resources/Schema/Entities/Ray2Red.xml b/resources/Schema/Entities/Ray2Red.xml new file mode 100644 index 00000000..6c7c3248 --- /dev/null +++ b/resources/Schema/Entities/Ray2Red.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + Textures/Effects/Ray.png + + + + + + + + + + + + + + + Textures/Effects/Ray.png + + + + + + + + + + + + + + diff --git a/resources/Schema/Entities/SidearmWeaponView.xml b/resources/Schema/Entities/SidearmWeaponView.xml index 68d29676..f01ffdf7 100644 --- a/resources/Schema/Entities/SidearmWeaponView.xml +++ b/resources/Schema/Entities/SidearmWeaponView.xml @@ -14,7 +14,7 @@ - Schema/Entities/RayBlue.xml + Schema/Entities/Ray2Red.xml @@ -22,6 +22,67 @@ + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + + + + + + + 16 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + 8 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + diff --git a/src/Engine/Editor/EditorGUI.cpp b/src/Engine/Editor/EditorGUI.cpp index a1ceafd0..4e7c8ab6 100644 --- a/src/Engine/Editor/EditorGUI.cpp +++ b/src/Engine/Editor/EditorGUI.cpp @@ -390,14 +390,52 @@ bool EditorGUI::drawComponentField_Vector(ComponentWrapper &c, const ComponentIn // Limit scale values to a minimum of 0 return ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, 0.f, std::numeric_limits::max()); } else if (field.Name == "Orientation") { - // Make orentations have a period of 2*Pi - glm::vec3 tempVal = glm::fmod(val, glm::vec3(glm::two_pi())); - if (ImGui::SliderFloat3("", glm::value_ptr(tempVal), 0.f, glm::two_pi())) { - val = tempVal; - return true; - } else { - return false; + //glm::vec3 tempVal = val; + glm::vec3 originalVal = val; + + ImVec2 cursorPos = ImGui::GetCursorScreenPos(); + glm::tvec3 isSnapping(false, false, false); + bool changed = ImGui::DragFloat3("", glm::value_ptr(val), 0.066666f); + if (changed) { + // Make orentations have a period of 2*Pi + val = glm::fmod(val, glm::vec3(glm::two_pi())); + for (int i = 0; i < 3; i++) { + if (val[i] < 0) { + val[i] += glm::two_pi(); + } + } } + + // Snap to angle + //float snapRange = glm::pi() / 15.f; + //float snapAngle = glm::quarter_pi(); + //glm::vec3 snap = glm::fmod(val, glm::vec3(snapAngle)); + //for (int i = 0; i < 3; i++) { + // isSnapping[i] = glm::abs(snap[i] - (snapRange / 2.f)) < snapRange; + //} + //if (changed && ImGui::IsMouseDown(0)) { + // glm::vec3 change = val - originalVal; + // for (int i = 0; i < 3; i++) { + // if (isSnapping[i] && glm::abs(change[i]) < snapRange) { + // val[i] -= snap[i] - snapRange; + // } + // } + //} + + // Draw snapping outline + float width = ImGui::CalcItemWidth() / 3.f;; + float spacing = GImGui->Style.ItemInnerSpacing.x; + for (int i = 0; i < 3; i++) { + if (isSnapping[i]) { + ImVec2 pos = cursorPos + ImVec2(i * (width + spacing), 0.f); + ImRect bb(pos - ImVec2(1, 1), pos + ImVec2(width, 17)); + auto window = ImGui::GetCurrentWindow(); + const ImU32 col = window->Color(ImGuiCol_HeaderActive); + window->DrawList->AddRect(bb.Min, bb.Max, col, 3.f); + } + } + + return changed; } else { return ImGui::DragFloat3("", glm::value_ptr(val), 0.1f, std::numeric_limits::lowest(), std::numeric_limits::max()); } diff --git a/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp b/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp index 0a179b4c..4c0f9673 100644 --- a/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp @@ -2,33 +2,73 @@ void DefenderWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt) { - (double&)cWeapon["TimeSinceLastFire"] += dt; + double& fireCooldown = cWeapon["FireCooldown"]; + fireCooldown = glm::max(0.0, fireCooldown - dt); + WeaponBehaviour::UpdateComponent(entity, cWeapon, dt); } void DefenderWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) { - bool isFiring = cWeapon["IsFiring"]; - bool cooldownPassed = (double)cWeapon["TimeSinceLastFire"] >= (60.0 / (double)cWeapon["RPM"]); - bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0; - if (isFiring && cooldownPassed && isNotShielding) { + double& reloadTimer = cWeapon["ReloadTimer"]; + reloadTimer = glm::max(0.0, reloadTimer - dt); + + double reloadTime = cWeapon["ReloadTime"]; + bool& isReloading = cWeapon["IsReloading"]; + if (isReloading && reloadTimer <= 0.0) { + int& magAmmo = cWeapon["MagazineAmmo"]; + int& magSize = cWeapon["MagazineSize"]; + int& ammo = cWeapon["Ammo"]; + if (magAmmo < magSize && ammo > 0) { + ammo -= 1; + magAmmo += 1; + reloadTimer = reloadTime; + } else { + isReloading = false; + } + } + + if (canFire(cWeapon, wi)) { fireShell(cWeapon, wi); } } void DefenderWeaponBehaviour::OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) { - cWeapon["IsFiring"] = true; - bool cooldownPassed = (double)cWeapon["TimeSinceLastFire"] >= (60.0 / (double)cWeapon["RPM"]); - bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0; - if (cooldownPassed && isNotShielding) { + cWeapon["TriggerHeld"] = true; + if (canFire(cWeapon, wi)) { fireShell(cWeapon, wi); } } void DefenderWeaponBehaviour::OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) { - cWeapon["IsFiring"] = false; + cWeapon["TriggerHeld"] = false; +} + +void DefenderWeaponBehaviour::OnReload(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + bool& isReloading = cWeapon["IsReloading"]; + if (isReloading) { + return; + } + + int& magAmmo = cWeapon["MagazineAmmo"]; + int& magSize = cWeapon["MagazineSize"]; + if (magAmmo >= magSize) { + return; + } + int& ammo = cWeapon["Ammo"]; + if (ammo <= 0) { + return; + } + + double reloadTime = cWeapon["ReloadTime"]; + double& reloadTimer = cWeapon["ReloadTimer"]; + + // Start reload + isReloading = true; + reloadTimer = reloadTime; } bool DefenderWeaponBehaviour::OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e) @@ -47,15 +87,23 @@ bool DefenderWeaponBehaviour::OnInputCommand(ComponentWrapper cWeapon, WeaponInf return false; } -bool DefenderWeaponBehaviour::OnSetCamera(const Events::SetCamera& e) -{ - m_CurrentCamera = e.CameraEntity; - return true; -} - void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi) { - cWeapon["TimeSinceLastFire"] = 0.0; + cWeapon["FireCooldown"] = 60.0 / (double)cWeapon["RPM"]; + + // Stop reloading + bool& isReloading = cWeapon["IsReloading"]; + isReloading = false; + + // Ammo + int& magAmmo = cWeapon["MagazineAmmo"]; + if (magAmmo <= 0) { + OnReload(cWeapon, wi); + return; + } else { + magAmmo -= 1; + } + int numPellets = cWeapon["NumPellets"]; float spreadAngle = cWeapon["SpreadAngle"]; std::uniform_real_distribution randomSpreadAngle(-spreadAngle, spreadAngle); @@ -92,7 +140,6 @@ void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi dealDamage(cWeapon, wi, direction, pelletDamage); } } - } void DefenderWeaponBehaviour::dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi, glm::vec3 direction, double damage) @@ -154,16 +201,13 @@ void DefenderWeaponBehaviour::dealDamage(ComponentWrapper cWeapon, WeaponInfo& w LOG_DEBUG("Damage: %f", damage); } -float DefenderWeaponBehaviour::traceRayDistance(glm::vec3 origin, glm::vec3 direction) +bool DefenderWeaponBehaviour::canFire(ComponentWrapper cWeapon, WeaponInfo& wi) { - float distance; - glm::vec3 pos; - auto entity = Collision::EntityFirstHitByRay(Ray(origin, direction), m_CollisionOctree, distance, pos); - if (entity) { - return distance; - } else { - return 100.f; - } + bool triggerHeld = cWeapon["TriggerHeld"]; + bool cooldownPassed = (double)cWeapon["FireCooldown"] <= 0.0; + bool isNotShielding = wi.Player.ChildrenWithComponent("Shield").size() == 0; + // TODO: Ammo checks + return triggerHeld && cooldownPassed && isNotShielding; } Camera DefenderWeaponBehaviour::cameraFromEntity(EntityWrapper camera) diff --git a/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp b/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp index 8c3906af..9a3ed6ab 100644 --- a/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp @@ -14,7 +14,7 @@ void SidearmWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWra void SidearmWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) { - if (canFire(cWeapon)) { + if ((bool)cWeapon["Automatic"] && canFire(cWeapon)) { fireBullet(cWeapon, wi); } } @@ -32,6 +32,11 @@ void SidearmWeaponBehaviour::OnCeasePrimaryFire(ComponentWrapper cWeapon, Weapon cWeapon["TriggerHeld"] = false; } +void SidearmWeaponBehaviour::OnEquip(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + cWeapon["FireCooldown"] = (double)cWeapon["EquipTime"]; +} + void SidearmWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) { // Make sure the trigger is released if weapon is holstered while firing @@ -46,7 +51,23 @@ void SidearmWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) void SidearmWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi) { + cWeapon["FireCooldown"] = 60.0 / (double)cWeapon["RPM"]; + // Get weapon model based on current person + EntityWrapper weaponModelEntity = getRelevantWeaponModelEntity(wi); + if (!weaponModelEntity.Valid()) { + return; + } + + // Tracer + EntityWrapper tracerSpawner = weaponModelEntity.FirstChildByName("WeaponMuzzle"); + if (tracerSpawner.Valid()) { + glm::vec3 origin = Transform::AbsolutePosition(tracerSpawner); + glm::vec3 direction = Transform::AbsoluteOrientation(tracerSpawner) * glm::vec3(0, 0, -1); + float distance = traceRayDistance(origin, direction); + EntityWrapper ray = SpawnerSystem::Spawn(tracerSpawner); + ((glm::vec3&)ray["Transform"]["Scale"]).z = (distance / 100.f); + } } bool SidearmWeaponBehaviour::canFire(ComponentWrapper cWeapon) From 0e8b97dbbade6bb39c6f2b8af6c1cfc43ce67cde Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 3 Mar 2016 01:35:32 +0100 Subject: [PATCH 5/5] Made AmmunitionHUD into TextFieldReader which reads any component field on a parent and updates a Text component with the value! --- include/Engine/Core/EntityWrapper.h | 1 + include/Game/Systems/AmmunitionHUDSystem.h | 17 ---- include/Game/Systems/TextFieldReader.h | 19 +++++ resources/Schema/Components.xsd | 2 +- resources/Schema/Components/AmmunitionHUD.xml | 3 - resources/Schema/Components/AmmunitionHUD.xsd | 10 --- .../Schema/Components/TextFieldReader.xml | 6 ++ .../Schema/Components/TextFieldReader.xsd | 21 +++++ .../Schema/Entities/DefenderWeaponView.xml | 15 +++- resources/Schema/Entities/Player.xml | 82 +++++++++---------- .../Schema/Entities/SidearmWeaponView.xml | 13 ++- resources/Schema/Types/Entity.xsd | 2 +- src/Engine/Core/EntityWrapper.cpp | 12 +++ src/Game/Game.cpp | 6 +- src/Game/Systems/AmmunitionHUDSystem.cpp | 36 -------- src/Game/Systems/TextFieldReader.cpp | 46 +++++++++++ 16 files changed, 174 insertions(+), 117 deletions(-) delete mode 100644 include/Game/Systems/AmmunitionHUDSystem.h create mode 100644 include/Game/Systems/TextFieldReader.h delete mode 100644 resources/Schema/Components/AmmunitionHUD.xml delete mode 100644 resources/Schema/Components/AmmunitionHUD.xsd create mode 100644 resources/Schema/Components/TextFieldReader.xml create mode 100644 resources/Schema/Components/TextFieldReader.xsd delete mode 100644 src/Game/Systems/AmmunitionHUDSystem.cpp create mode 100644 src/Game/Systems/TextFieldReader.cpp diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index 8ece8e59..12029720 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -27,6 +27,7 @@ struct EntityWrapper bool HasComponent(const std::string& componentType); void AttachComponent(const char* componentName); EntityWrapper Parent(); + EntityWrapper FirstParentByName(const std::string& parentEntityName); EntityWrapper FirstChildByName(const std::string& name); EntityWrapper FirstParentWithComponent(const std::string& componentType); EntityWrapper Clone(EntityWrapper parent = EntityWrapper::Invalid); diff --git a/include/Game/Systems/AmmunitionHUDSystem.h b/include/Game/Systems/AmmunitionHUDSystem.h deleted file mode 100644 index b22a85b5..00000000 --- a/include/Game/Systems/AmmunitionHUDSystem.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef AmmunitionHUDSystem_h__ -#define AmmunitionHUDSystem_h__ - -#include "../../Engine/Core/System.h" -#include "../../Engine/GLM.h" - -class AmmunitionHUDSystem : public ImpureSystem -{ -public: - AmmunitionHUDSystem(SystemParams params) - : System(params) - { } - - virtual void Update(double dt) override; -}; - -#endif \ No newline at end of file diff --git a/include/Game/Systems/TextFieldReader.h b/include/Game/Systems/TextFieldReader.h new file mode 100644 index 00000000..1ea8e966 --- /dev/null +++ b/include/Game/Systems/TextFieldReader.h @@ -0,0 +1,19 @@ +#ifndef AmmunitionHUDSystem_h__ +#define AmmunitionHUDSystem_h__ + +#include +#include "../../Engine/Core/System.h" +#include "../../Engine/GLM.h" + +class TextFieldReader : public PureSystem +{ +public: + TextFieldReader(SystemParams params) + : System(params) + , PureSystem("TextFieldReader") + { } + + virtual void UpdateComponent(EntityWrapper& entity, ComponentWrapper& cTextFieldReader, double dt) override; +}; + +#endif \ No newline at end of file diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 711f4999..ee8bc31d 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -45,7 +45,7 @@ - + diff --git a/resources/Schema/Components/AmmunitionHUD.xml b/resources/Schema/Components/AmmunitionHUD.xml deleted file mode 100644 index 63b86150..00000000 --- a/resources/Schema/Components/AmmunitionHUD.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/resources/Schema/Components/AmmunitionHUD.xsd b/resources/Schema/Components/AmmunitionHUD.xsd deleted file mode 100644 index 1a48d8d1..00000000 --- a/resources/Schema/Components/AmmunitionHUD.xsd +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - Hud element for tracking ammunition from parent with AssaultWeapon component. Child with the name "MagazineAmmo" tracks clip ammunition. Child with the name "Ammo" tracks ammo. - - - \ No newline at end of file diff --git a/resources/Schema/Components/TextFieldReader.xml b/resources/Schema/Components/TextFieldReader.xml new file mode 100644 index 00000000..52430804 --- /dev/null +++ b/resources/Schema/Components/TextFieldReader.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/resources/Schema/Components/TextFieldReader.xsd b/resources/Schema/Components/TextFieldReader.xsd new file mode 100644 index 00000000..7c77890d --- /dev/null +++ b/resources/Schema/Components/TextFieldReader.xsd @@ -0,0 +1,21 @@ + + + + + + Reads a value from a specific field of a compoent of parent entity and writes it to the Text component on this entity. + + + + The name of the parent entity to read the component field from. Leave empty to read from this entity. + + + The component type to read the field value from. + + + The field name to read the value from. + + + + + \ No newline at end of file diff --git a/resources/Schema/Entities/DefenderWeaponView.xml b/resources/Schema/Entities/DefenderWeaponView.xml index b65194f9..0886ac67 100755 --- a/resources/Schema/Entities/DefenderWeaponView.xml +++ b/resources/Schema/Entities/DefenderWeaponView.xml @@ -33,7 +33,6 @@ - @@ -61,8 +60,13 @@ + + Player + DefenderWeapon + MagazineAmmo + - 32 + 0 Fonts/DroidSans.ttf,64 @@ -74,8 +78,13 @@ + + Player + DefenderWeapon + Ammo + - 360 + 0 Fonts/DroidSans.ttf,64 diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 5c5efc07..e0230582 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -7,9 +7,7 @@ - - 102.85760837900634 - + @@ -26,7 +24,7 @@ - + @@ -66,8 +64,8 @@ Textures/Weapons/Crosshair/SmallThickHoleDot.png - false + false @@ -90,42 +88,22 @@ - - - - 1 - - - - 100/100 - Fonts/DroidSans.ttf,64 - - - - - - - - - - - 1 + Textures/HealthHUD3.png - - + @@ -142,8 +120,8 @@ Textures/Core/White.png - false + false @@ -160,8 +138,8 @@ Textures/Core/White.png - false + false @@ -178,8 +156,8 @@ Textures/Core/White.png - false + false @@ -193,6 +171,26 @@ + + + + 1 + + + + 100/100 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + @@ -229,8 +227,8 @@ - + @@ -263,8 +261,8 @@ - + @@ -298,8 +296,8 @@ - + @@ -332,8 +330,8 @@ - + @@ -365,8 +363,8 @@ - + @@ -442,8 +440,8 @@ - + @@ -490,9 +488,8 @@ R_Arm_Weapon_Joint - AssaultWeapon - SidearmWeapon + Schema/Entities/SidearmWeaponView.xml @@ -575,7 +572,10 @@ Schema/Entities/SidearmWeaponWorld.xml - + + + + @@ -617,8 +617,8 @@ - + @@ -627,8 +627,8 @@ Textures/Icons/Arrow.png - false + false diff --git a/resources/Schema/Entities/SidearmWeaponView.xml b/resources/Schema/Entities/SidearmWeaponView.xml index f01ffdf7..d3dcda66 100644 --- a/resources/Schema/Entities/SidearmWeaponView.xml +++ b/resources/Schema/Entities/SidearmWeaponView.xml @@ -24,7 +24,11 @@ - + + + + + @@ -52,6 +56,11 @@ + + Player + SidearmWeapon + MagazineAmmo + 16 Fonts/DroidSans.ttf,64 @@ -73,8 +82,8 @@ - + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index f9870a51..b4ceb6d2 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -43,7 +43,7 @@ - + diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index b3bef55a..3c217353 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -34,6 +34,18 @@ EntityWrapper EntityWrapper::Parent() } } +EntityWrapper EntityWrapper::FirstParentByName(const std::string& parentEntityName) +{ + EntityWrapper entity = *this; + while (entity.Parent().Valid()) { + entity = entity.Parent(); + if (entity.Name() == parentEntityName) { + return entity; + } + } + return EntityWrapper::Invalid; +} + EntityWrapper EntityWrapper::FirstChildByName(const std::string& name) { return firstChildByNameRecursive(name, this->ID); diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 7607efec..10107ab1 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -27,7 +27,7 @@ #include "../Engine/Core/UniformScaleSystem.h" #include "Rendering/AnimationSystem.h" #include "Network/MultiplayerSnapshotFilter.h" -#include "Game/Systems/AmmunitionHUDSystem.h" +#include "Game/Systems/TextFieldReader.h" #include "Game/Systems/CapturePointArrowHUDSystem.h" #include "Game/Systems/KillFeedSystem.h" #include "Game/Systems/BoostSystem.h" @@ -136,7 +136,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); - m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); @@ -145,7 +145,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); - m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); diff --git a/src/Game/Systems/AmmunitionHUDSystem.cpp b/src/Game/Systems/AmmunitionHUDSystem.cpp deleted file mode 100644 index c9d87072..00000000 --- a/src/Game/Systems/AmmunitionHUDSystem.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "Game/Systems/AmmunitionHUDSystem.h" - -void AmmunitionHUDSystem::Update(double dt) -{ - //Hud element for tracking ammunition from parent with AssaultWeapon component.Child with the name "MagazineAmmo" tracks clip ammunition.Child with the name "Ammo" tracks ammo. - - auto ammunitionHUDs = m_World->GetComponents("AmmunitionHUD"); - if (ammunitionHUDs == nullptr) { - return; - } - - for (auto& ammunitionHUDComponent : *ammunitionHUDs) { - EntityWrapper entity = EntityWrapper(m_World, ammunitionHUDComponent.EntityID); - - EntityWrapper playerEntity = entity.FirstParentWithComponent("AssaultWeapon"); - - if (!playerEntity.Valid()) { - return; - } - - - EntityWrapper magazineAmmo = entity.FirstChildByName("MagazineAmmo"); - if(magazineAmmo.Valid()) { - if(magazineAmmo.HasComponent("Text")) { - (std::string&)magazineAmmo["Text"]["Content"] = std::to_string((int)playerEntity["AssaultWeapon"]["MagazineAmmo"]); - } - } - - EntityWrapper ammo = entity.FirstChildByName("Ammo"); - if (ammo.Valid()) { - if (ammo.HasComponent("Text")) { - (std::string&)ammo["Text"]["Content"] = std::to_string((int)playerEntity["AssaultWeapon"]["Ammo"]); - } - } - } -} diff --git a/src/Game/Systems/TextFieldReader.cpp b/src/Game/Systems/TextFieldReader.cpp new file mode 100644 index 00000000..8712a61f --- /dev/null +++ b/src/Game/Systems/TextFieldReader.cpp @@ -0,0 +1,46 @@ +#include "Game/Systems/TextFieldReader.h" + +void TextFieldReader::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cAmmunitionHUD, double dt) +{ + if (!entity.HasComponent("Text")) { + return; + } + + // Find the entity to read from + const std::string& parentEntityName = cAmmunitionHUD["ParentEntityName"]; + EntityWrapper readEntity = entity; + if (!parentEntityName.empty()) { + readEntity = entity.FirstParentByName(parentEntityName); + if (!readEntity.Valid()) { + return; + } + } + + // Find the component to read from + const std::string& componentType = cAmmunitionHUD["ComponentType"]; + if (componentType.empty() || !readEntity.HasComponent(componentType)) { + return; + } + ComponentWrapper component = readEntity[componentType]; + + // Find the field to read from + const std::string& fieldName = cAmmunitionHUD["Field"]; + if (fieldName.empty() || component.Info.Fields.count(fieldName) == 0) { + return; + } + const ComponentInfo::Field_t& field = component.Info.Fields.at(fieldName); + + std::string& text = entity["Text"]["Content"]; + + if (field.Type == "int") { + text = boost::lexical_cast((const int&)component[fieldName]); + } else if (field.Type == "float") { + text = boost::lexical_cast((const float&)component[fieldName]); + } else if (field.Type == "double") { + text = boost::lexical_cast((const double&)component[fieldName]); + } else if (field.Type == "bool") { + text = boost::lexical_cast((const bool&)component[fieldName]); + } else if (field.Type == "string") { + text = (const std::string&)component[fieldName]; + } +}