From b431a875f75c741b0ecd5576b1819a2331ae5a85 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 1 Mar 2016 13:26:50 +0100 Subject: [PATCH 1/8] 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/8] 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/8] 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/8] 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/8] 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]; + } +} From 9d4441852c5d27d727c17f761679d9ce08028e0f Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 3 Mar 2016 03:39:00 +0100 Subject: [PATCH 6/8] DefenderWeapon view punch and crosshair travel with return --- assets | 2 +- .../Systems/Weapon/DefenderWeaponBehaviour.h | 2 + .../Schema/Components/DefenderWeapon.xml | 5 +- .../Schema/Components/DefenderWeapon.xsd | 7 +++ resources/Schema/Entities/MovementTest.xml | 12 ++-- resources/Schema/Entities/Player.xml | 13 ++-- .../Weapon/DefenderWeaponBehaviour.cpp | 59 ++++++++++++++++++- .../Systems/Weapon/SidearmWeaponBehaviour.cpp | 2 - 8 files changed, 83 insertions(+), 19 deletions(-) diff --git a/assets b/assets index 72530423..b8baf48e 160000 --- a/assets +++ b/assets @@ -1 +1 @@ -Subproject commit 72530423ad3744341f42cbfdcba18295a2cfac90 +Subproject commit b8baf48e5ee88ddb7d9bd818e31e3a52d96daec5 diff --git a/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h b/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h index c1e132b1..77d579f8 100644 --- a/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h +++ b/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h @@ -1,6 +1,7 @@ #include "WeaponBehaviour.h" #include "Collision/Collision.h" #include "Core/EPlayerDamage.h" +#include "Sound/EPlaySoundOnEntity.h" class DefenderWeaponBehaviour : public WeaponBehaviour { @@ -16,6 +17,7 @@ public: void OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override; void OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) override; void OnReload(ComponentWrapper cWeapon, WeaponInfo& wi) override; + void OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) override; bool OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e) override; private: diff --git a/resources/Schema/Components/DefenderWeapon.xml b/resources/Schema/Components/DefenderWeapon.xml index 1b336fc4..68b87759 100755 --- a/resources/Schema/Components/DefenderWeapon.xml +++ b/resources/Schema/Components/DefenderWeapon.xml @@ -6,13 +6,16 @@ 64 90 0.174533 + 0.174533 10 120 - 0.01 + 0.03 + 0.2 0.5 false 0 false 0 + 0 \ No newline at end of file diff --git a/resources/Schema/Components/DefenderWeapon.xsd b/resources/Schema/Components/DefenderWeapon.xsd index c1b98e2f..d2b503f8 100755 --- a/resources/Schema/Components/DefenderWeapon.xsd +++ b/resources/Schema/Components/DefenderWeapon.xsd @@ -37,6 +37,9 @@ Spread angle in radians + + Maximum vertical aim travel angle in radians + Rate of fire in rounds per minute @@ -44,6 +47,9 @@ View punch in radians for each shell fired + + The speed in radians per second the view returns to its original position after being punched + Time it takes to load ONE SHELL into the weapon in seconds @@ -52,6 +58,7 @@ + diff --git a/resources/Schema/Entities/MovementTest.xml b/resources/Schema/Entities/MovementTest.xml index 41474568..3429194a 100644 --- a/resources/Schema/Entities/MovementTest.xml +++ b/resources/Schema/Entities/MovementTest.xml @@ -26,7 +26,7 @@ - Models/Characters/Assault/AssaultTPose.mesh + Models/Characters/Assault/AssaultRed.mesh @@ -39,7 +39,7 @@ - Models/Characters/Assault/AssaultTPose.mesh + Models/Characters/Assault/AssaultRed.mesh @@ -94,11 +94,11 @@ - Models/Characters/Assault/AssaultTPose.mesh + Models/Characters/Assault/AssaultBlue.mesh - + @@ -107,11 +107,11 @@ - Models/Characters/Assault/AssaultTPose.mesh + Models/Characters/Assault/AssaultBlue.mesh - + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index e0230582..1ee9d5d3 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -458,7 +458,7 @@ - Models/Characters/Assault/FirstPerson.mesh + Models/Characters/Assault/Test/FirstPerson.mesh @@ -524,8 +524,7 @@ - Idle - 0.013134522267137072 + IdleF 1 @@ -537,8 +536,8 @@ - Models/Characters/Assault/AssaultAnimations.mesh - + Models/Characters/Assault/AssaultBlue.mesh + @@ -573,8 +572,8 @@ Schema/Entities/SidearmWeaponWorld.xml - - + + diff --git a/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp b/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp index 4c0f9673..50d5889d 100644 --- a/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp @@ -10,9 +10,11 @@ void DefenderWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWr void DefenderWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) { + // Decrement reload timer double& reloadTimer = cWeapon["ReloadTimer"]; reloadTimer = glm::max(0.0, reloadTimer - dt); + // Handle reloading double reloadTime = cWeapon["ReloadTime"]; bool& isReloading = cWeapon["IsReloading"]; if (isReloading && reloadTimer <= 0.0) { @@ -23,11 +25,31 @@ void DefenderWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& ammo -= 1; magAmmo += 1; reloadTimer = reloadTime; + Events::PlaySoundOnEntity e; + e.EmitterID = wi.Player.ID; + e.FilePath = "Audio/weapon/Zoom.wav"; + m_EventBroker->Publish(e); } else { isReloading = false; } } + // Restore view angle + if (IsClient) { + float& currentTravel = cWeapon["CurrentTravel"]; + float& returnSpeed = cWeapon["ViewReturnSpeed"]; + if (currentTravel > 0) { + float change = returnSpeed * dt; + currentTravel = glm::max(0.f, currentTravel - change); + EntityWrapper camera = wi.Player.FirstChildByName("Camera"); + if (camera.Valid()) { + glm::vec3& cameraOrientation = camera["Transform"]["Orientation"]; + cameraOrientation.x -= change; + } + } + } + + // Fire if we're able to fire if (canFire(cWeapon, wi)) { fireShell(cWeapon, wi); } @@ -71,6 +93,16 @@ void DefenderWeaponBehaviour::OnReload(ComponentWrapper cWeapon, WeaponInfo& wi) reloadTimer = reloadTime; } +void DefenderWeaponBehaviour::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; +} + bool DefenderWeaponBehaviour::OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e) { if (e.Command == "SpecialAbility" && IsServer) { @@ -114,11 +146,29 @@ void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi std::vector pelletAngles; for (int i = 0; i < numPellets; i++) { pelletAngles.push_back(glm::vec2(randomSpreadAngle(m_RandomEngine), randomSpreadAngle(m_RandomEngine))); - LOG_DEBUG("%f %f", pelletAngles[i].x, pelletAngles[i].y); } double pelletDamage = (double)cWeapon["BaseDamage"] / numPellets; + // View punch + if (IsClient) { + EntityWrapper camera = wi.Player.FirstChildByName("Camera"); + if (camera.Valid()) { + glm::vec3& cameraOrientation = camera["Transform"]["Orientation"]; + float viewPunch = cWeapon["ViewPunch"]; + float maxTravelAngle = cWeapon["MaxTravelAngle"]; + float& currentTravel = cWeapon["CurrentTravel"]; + if (currentTravel < maxTravelAngle) { + float change = viewPunch; + if (currentTravel + change > maxTravelAngle) { + change = maxTravelAngle - currentTravel; + } + cameraOrientation.x += change; + currentTravel += change; + } + } + } + // Tracers EntityWrapper weaponModelEntity; if (wi.Player == LocalPlayer) { @@ -140,6 +190,12 @@ void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi dealDamage(cWeapon, wi, direction, pelletDamage); } } + + // Sound + Events::PlaySoundOnEntity e; + e.EmitterID = wi.Player.ID; + e.FilePath = "Audio/weapon/Blast.wav"; + m_EventBroker->Publish(e); } void DefenderWeaponBehaviour::dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi, glm::vec3 direction, double damage) @@ -206,7 +262,6 @@ bool DefenderWeaponBehaviour::canFire(ComponentWrapper cWeapon, WeaponInfo& wi) 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; } diff --git a/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp b/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp index 9a3ed6ab..d32b7d7e 100644 --- a/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/SidearmWeaponBehaviour.cpp @@ -45,8 +45,6 @@ void SidearmWeaponBehaviour::OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) // Cancel any reload cWeapon["IsReloading"] = false; cWeapon["ReloadTimer"] = 0.0; - - LOG_DEBUG("HOLSTER"); } void SidearmWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi) From 1210c915351def2445ab8e9749e578261658d518 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 3 Mar 2016 13:51:47 +0100 Subject: [PATCH 7/8] Added Gameplay.AutoReload bool to config --- include/Game/Systems/Weapon/WeaponBehaviour.h | 8 ++++++-- resources/DefaultConfig.ini | 3 +++ src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp | 10 +++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/include/Game/Systems/Weapon/WeaponBehaviour.h b/include/Game/Systems/Weapon/WeaponBehaviour.h index e0783bd2..d4520c9f 100644 --- a/include/Game/Systems/Weapon/WeaponBehaviour.h +++ b/include/Game/Systems/Weapon/WeaponBehaviour.h @@ -8,6 +8,7 @@ #include "Input/EInputCommand.h" #include "Systems/SpawnerSystem.h" #include "Rendering/ESetCamera.h" +#include "Core/ConfigFile.h" template class WeaponBehaviour : public PureSystem @@ -21,8 +22,10 @@ public: , m_Renderer(renderer) , m_CollisionOctree(collisionOctree) { - EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponBehaviour::_OnInputCommand) - EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &WeaponBehaviour::_OnSetCamera) + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &WeaponBehaviour::_OnInputCommand); + EVENT_SUBSCRIBE_MEMBER(m_ESetCamera, &WeaponBehaviour::_OnSetCamera); + auto config = ResourceManager::Load("Config.ini"); + m_ConfigAutoReload = config->Get("Gameplay.AutoReload", true); } virtual ~WeaponBehaviour() = default; @@ -49,6 +52,7 @@ protected: EntityWrapper m_CurrentCamera; Octree* m_CollisionOctree; std::unordered_map m_ActiveWeapons; + bool m_ConfigAutoReload; virtual void UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) { } virtual void OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) { } diff --git a/resources/DefaultConfig.ini b/resources/DefaultConfig.ini index 8917e3e1..fd468fd6 100644 --- a/resources/DefaultConfig.ini +++ b/resources/DefaultConfig.ini @@ -1,3 +1,6 @@ +[Gameplay] +AutoReload=true + [Debug] LogLevel=1 LoadMap= diff --git a/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp b/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp index 50d5889d..3a4ed3a4 100644 --- a/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp +++ b/src/Game/Systems/Weapon/DefenderWeaponBehaviour.cpp @@ -14,11 +14,16 @@ void DefenderWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& double& reloadTimer = cWeapon["ReloadTimer"]; reloadTimer = glm::max(0.0, reloadTimer - dt); + // Start reloading automatically if at 0 mag ammo + int& magAmmo = cWeapon["MagazineAmmo"]; + if (m_ConfigAutoReload && magAmmo <= 0) { + OnReload(cWeapon, wi); + } + // Handle reloading - double reloadTime = cWeapon["ReloadTime"]; bool& isReloading = cWeapon["IsReloading"]; if (isReloading && reloadTimer <= 0.0) { - int& magAmmo = cWeapon["MagazineAmmo"]; + double reloadTime = cWeapon["ReloadTime"]; int& magSize = cWeapon["MagazineSize"]; int& ammo = cWeapon["Ammo"]; if (magAmmo < magSize && ammo > 0) { @@ -130,7 +135,6 @@ void DefenderWeaponBehaviour::fireShell(ComponentWrapper cWeapon, WeaponInfo& wi // Ammo int& magAmmo = cWeapon["MagazineAmmo"]; if (magAmmo <= 0) { - OnReload(cWeapon, wi); return; } else { magAmmo -= 1; From b2371f4a43a92991a79266805472be145dd295b8 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Thu, 3 Mar 2016 20:00:42 +0100 Subject: [PATCH 8/8] Working AssaultWeapon --- .../Systems/Weapon/AssaultWeaponBehaviour.h | 51 +- .../Systems/Weapon/DefenderWeaponBehaviour.h | 7 +- .../Systems/Weapon/SidearmWeaponBehaviour.h | 7 +- resources/Schema/Components/AssaultWeapon.xml | 21 +- resources/Schema/Components/AssaultWeapon.xsd | 23 +- .../Schema/Components/DefenderWeapon.xml | 2 +- .../Schema/Components/DefenderWeapon.xsd | 2 +- resources/Schema/Components/SidearmWeapon.xml | 2 +- resources/Schema/Components/SidearmWeapon.xsd | 2 +- .../Schema/Entities/AssaultWeaponView.xml | 28 +- .../Schema/Entities/AssaultWeaponWorld.xml | 10 +- resources/Schema/Entities/Player.xml | 16 +- .../Entities/PlayerAssaultFallbackBlue.xml | 695 ++++++++++++++++++ resources/Schema/Entities/Ray2Red | 18 - resources/Schema/Entities/Ray2Red.xml | 43 -- resources/Schema/Entities/RayBlue | 17 - resources/Schema/Entities/RayBlue.xml | 44 +- resources/Schema/Entities/RayRed | 17 - resources/Schema/Entities/RayRed.xml | 20 - src/Game/Game.cpp | 2 + .../Systems/Weapon/AssaultWeaponBehaviour.cpp | 228 ++++++ 21 files changed, 1061 insertions(+), 194 deletions(-) create mode 100644 resources/Schema/Entities/PlayerAssaultFallbackBlue.xml delete mode 100644 resources/Schema/Entities/Ray2Red delete mode 100644 resources/Schema/Entities/Ray2Red.xml delete mode 100644 resources/Schema/Entities/RayBlue delete mode 100644 resources/Schema/Entities/RayRed delete mode 100644 resources/Schema/Entities/RayRed.xml create mode 100644 src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp diff --git a/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h b/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h index 993dd060..7244d443 100644 --- a/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h +++ b/include/Game/Systems/Weapon/AssaultWeaponBehaviour.h @@ -1,47 +1,40 @@ #ifndef AssaultWeaponBehaviour_h__ #define AssaultWeaponBehaviour_h__ -#include "Sound/EPlaySoundOnEntity.h" -#include "Collision/Collision.h" -#include "Core/ConfigFile.h" #include "WeaponBehaviour.h" -#include "../SpawnerSystem.h" +#include "Collision/Collision.h" #include "Core/EPlayerDamage.h" -#include "Core/EShoot.h" +#include "Sound/EPlaySoundOnEntity.h" class AssaultWeaponBehaviour : public WeaponBehaviour { public: AssaultWeaponBehaviour(SystemParams systemParams, IRenderer* renderer, Octree* collisionOctree) - : WeaponBehaviour(systemParams, "AssaultWeapon", renderer, collisionOctree) + : System(systemParams) + , WeaponBehaviour(systemParams, "AssaultWeapon", renderer, collisionOctree) + , m_RandomEngine(m_RandomDevice()) { } -protected: - virtual void OnPrimaryFire(WeaponInfo& wi) override; - virtual void OnCeasePrimaryFire(WeaponInfo& wi) override; - virtual void OnReload(WeaponInfo& wi) override; + 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; + void OnHolster(ComponentWrapper cWeapon, WeaponInfo& wi) override; + //bool OnInputCommand(ComponentWrapper cWeapon, WeaponInfo& wi, const Events::InputCommand& e) override; private: - // State - bool m_Firing = false; - bool m_Reloading = false; - double m_ReloadTimer = 0.0; - double m_TimeSinceLastFire = 0.0; - EntityWrapper m_FirstPersonReloadImpostor; + std::random_device m_RandomDevice; + std::mt19937 m_RandomEngine; - bool hasAmmo(); - void fireRound(); - void spawnTracer(); - float traceRayDistance(glm::vec3 origin, glm::vec3 direction); - void playFireSound(); - void playEmptySound(); - void viewPunch(); - void finishReload(); - void playShootAnimation(); - void playIdleAnimation(); - void playReloadAnimation(); - bool shoot(double damage); - void showHitMarker(); + // Weapon functions + void fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi); + //void dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi, glm::vec3 direction, double damage); + bool canFire(ComponentWrapper cWeapon, WeaponInfo& wi); + bool dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi); + + // Utility + //Camera cameraFromEntity(EntityWrapper camera); }; #endif \ No newline at end of file diff --git a/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h b/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h index 77d579f8..9e7d4991 100644 --- a/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h +++ b/include/Game/Systems/Weapon/DefenderWeaponBehaviour.h @@ -1,3 +1,6 @@ +#ifndef DefenderWeaponBehaviour_h__ +#define DefenderWeaponBehaviour_h__ + #include "WeaponBehaviour.h" #include "Collision/Collision.h" #include "Core/EPlayerDamage.h" @@ -31,4 +34,6 @@ private: // Utility Camera cameraFromEntity(EntityWrapper camera); -}; \ No newline at end of file +}; + +#endif \ No newline at end of file diff --git a/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h b/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h index d221b8bb..10e6105a 100644 --- a/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h +++ b/include/Game/Systems/Weapon/SidearmWeaponBehaviour.h @@ -1,3 +1,6 @@ +#ifndef SidearmWeaponBehaviour_h__ +#define SidearmWeaponBehaviour_h__ + #include "WeaponBehaviour.h" #include "Collision/Collision.h" #include "Core/EPlayerDamage.h" @@ -30,4 +33,6 @@ private: bool canFire(ComponentWrapper cWeapon); bool playerInFirstPerson(EntityWrapper player); //float traceRayDistance(glm::vec3 origin, glm::vec3 direction); -}; \ No newline at end of file +}; + +#endif \ No newline at end of file diff --git a/resources/Schema/Components/AssaultWeapon.xml b/resources/Schema/Components/AssaultWeapon.xml index c835217b..ba74fbb7 100755 --- a/resources/Schema/Components/AssaultWeapon.xml +++ b/resources/Schema/Components/AssaultWeapon.xml @@ -1,12 +1,21 @@ + 32 32 - 360 - 360 - 5 - 120 - 0.01 + 320 + 320 + 15 + 0.174533 + 0.10 + 420 + 0.03 + 0.18 2 - + 0.5 + false + 0 + false + 0 + 0 \ No newline at end of file diff --git a/resources/Schema/Components/AssaultWeapon.xsd b/resources/Schema/Components/AssaultWeapon.xsd index 7e9854a2..a1e745de 100755 --- a/resources/Schema/Components/AssaultWeapon.xsd +++ b/resources/Schema/Components/AssaultWeapon.xsd @@ -7,6 +7,7 @@ + Ammo currently loaded into the magazine @@ -20,16 +21,32 @@ Maximum ammo able to be carried + + Spread angle in radians + + + Maximum vertical aim travel angle in radians + Rate of fire in rounds per minute - View punch in radians for each bullet fired + View punch in radians for each shell fired + + + The speed in radians per second the view returns to its original position after being punched - Time it takes to reload the weapon in seconds + 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/Components/DefenderWeapon.xml b/resources/Schema/Components/DefenderWeapon.xml index 68b87759..b01955bc 100755 --- a/resources/Schema/Components/DefenderWeapon.xml +++ b/resources/Schema/Components/DefenderWeapon.xml @@ -1,5 +1,6 @@ + 8 8 64 @@ -12,7 +13,6 @@ 0.03 0.2 0.5 - false 0 false diff --git a/resources/Schema/Components/DefenderWeapon.xsd b/resources/Schema/Components/DefenderWeapon.xsd index d2b503f8..53200952 100755 --- a/resources/Schema/Components/DefenderWeapon.xsd +++ b/resources/Schema/Components/DefenderWeapon.xsd @@ -19,6 +19,7 @@ + Ammo currently loaded into the magazine @@ -53,7 +54,6 @@ 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 1d503ecc..bc90c067 100644 --- a/resources/Schema/Components/SidearmWeapon.xml +++ b/resources/Schema/Components/SidearmWeapon.xml @@ -1,5 +1,6 @@ + 16 16 20 @@ -8,7 +9,6 @@ 0.01 0.5 0.5 - false 0 false diff --git a/resources/Schema/Components/SidearmWeapon.xsd b/resources/Schema/Components/SidearmWeapon.xsd index bafb9de2..514bf354 100644 --- a/resources/Schema/Components/SidearmWeapon.xsd +++ b/resources/Schema/Components/SidearmWeapon.xsd @@ -19,6 +19,7 @@ + Ammo currently loaded into the magazine @@ -41,7 +42,6 @@ Time it takes from selecting the weapon until it's ready to fire - diff --git a/resources/Schema/Entities/AssaultWeaponView.xml b/resources/Schema/Entities/AssaultWeaponView.xml index 4b985fbb..b5c87674 100755 --- a/resources/Schema/Entities/AssaultWeaponView.xml +++ b/resources/Schema/Entities/AssaultWeaponView.xml @@ -1,17 +1,11 @@ - + - - R_Arm_Weapon_Joint - Models/Weapons/Blue/AssaultWeaponBlue.mesh - - - - + @@ -21,7 +15,8 @@ Schema/Entities/RayBlue.xml - + + @@ -37,9 +32,8 @@ - - + @@ -70,6 +64,11 @@ Fonts/DroidSans.ttf,64 + + Player + AssaultWeapon + MagazineAmmo + @@ -79,10 +78,15 @@ - 360 + 320 Fonts/DroidSans.ttf,64 + + Player + AssaultWeapon + Ammo + diff --git a/resources/Schema/Entities/AssaultWeaponWorld.xml b/resources/Schema/Entities/AssaultWeaponWorld.xml index 6fcb97b3..9f33c8f2 100755 --- a/resources/Schema/Entities/AssaultWeaponWorld.xml +++ b/resources/Schema/Entities/AssaultWeaponWorld.xml @@ -1,17 +1,11 @@ - + - - R_Arm_Weapon_Joint - Models/Weapons/Blue/AssaultWeaponBlue.mesh - - - - + diff --git a/resources/Schema/Entities/Player.xml b/resources/Schema/Entities/Player.xml index 1ee9d5d3..affe9f79 100644 --- a/resources/Schema/Entities/Player.xml +++ b/resources/Schema/Entities/Player.xml @@ -6,10 +6,14 @@ + + + + + - + - @@ -470,10 +474,10 @@ R_Arm_Weapon_Joint - DefenderWeapon + AssaultWeapon - Schema/Entities/DefenderWeaponView.xml + Schema/Entities/AssaultWeaponView.xml @@ -545,13 +549,13 @@ - DefenderWeapon + AssaultWeapon - Schema/Entities/DefenderWeaponWorld.xml + Schema/Entities/AssaultWeaponWorld.xml diff --git a/resources/Schema/Entities/PlayerAssaultFallbackBlue.xml b/resources/Schema/Entities/PlayerAssaultFallbackBlue.xml new file mode 100644 index 00000000..bb6367f8 --- /dev/null +++ b/resources/Schema/Entities/PlayerAssaultFallbackBlue.xml @@ -0,0 +1,695 @@ + + + + + + + + + + + + + + + + + + 5 + + + + + + + + + + + + + + + + + 0.10000000149011612 + 300 + + + + + + + + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + + + + + + + + Textures/Weapons/Crosshair/SmallThickHoleDot.png + + false + + + + + + + + + + + + Schema/Entities/HitMarker.xml + + + + + + + + + + + + + + 1 + + + + + Textures/HealthHUD3.png + + + + + + + + + + + + + + + + + + + + + + + Textures/Core/White.png + + false + + + + + + + + + + + + + + + + Textures/Core/White.png + + false + + + + + + + + + + + + + + + + Textures/Core/White.png + + false + + + + + + + + + + + + + + + + + 1 + + + + 100/100 + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 2 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 3 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 4 + + + 1 + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + 1 + + + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + Textures/Core/UnitHexagon.png + + + + + + + + + + + + + 1 + + + + Textures/Core/UnitHexagon_Rotated.png + + + + + + + + + + + + + + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + Fonts/DroidSans.ttf,64 + + + + + + + + + + + + + + + + + Models/Widgets/Arrows/Arrow5.mesh + + + + + + + + + + + + + + + + + + + + Idle + 1.8348644854054612 + 1 + + + + + Models/Characters/Assault/Test/FirstPerson.mesh + + + + + + + + + R_Arm_Weapon_Joint + + + AssaultWeapon + + + Schema/Entities/AssaultWeaponView.xml + + + + + + + + + + + + R_Arm_Weapon_Joint + + + SidearmWeapon + + + Schema/Entities/SidearmWeaponView.xml + + + + + + + + + + + + + + + + 0.10000000149011612 + 300 + + + Models/Widgets/Camera.mesh + false + + + + + + + + + + + + IdleF + 1 + + + + + AimRifle + + + + + + Models/Characters/Assault/AssaultBlue.mesh + + + + + + + + + R_Arm_Weapon_Joint + + + AssaultWeapon + + + + + + Schema/Entities/AssaultWeaponWorld.xml + + + + + + + + + + + Models/Weapons/Blue/AssaultWeaponBlue.mesh + + + + + + + + Schema/Entities/RayBlue.xml + + + + + + + + + + + Schema/Entities/ReloadEffectWorld.xml + + + + + + + + + + + + + R_Arm_Weapon_Joint + + + SidearmWeapon + + + + + + Schema/Entities/SidearmWeaponWorld.xml + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + + Models/Core/UnitCube.mesh + + false + + + + + + + + + + + Insert name here + Fonts/DroidSans.ttf,100 + + + + + + + + + + + + + + Textures/Icons/Arrow.png + + false + + + + + 50 + true + + + + + + + + + + + + Schema/Entities/DefenderShield.xml + + + + + + + + + + diff --git a/resources/Schema/Entities/Ray2Red b/resources/Schema/Entities/Ray2Red deleted file mode 100644 index 813443b2..00000000 --- a/resources/Schema/Entities/Ray2Red +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - Textures/Effects/Ray.png - - - - - - - - - - - - diff --git a/resources/Schema/Entities/Ray2Red.xml b/resources/Schema/Entities/Ray2Red.xml deleted file mode 100644 index 6c7c3248..00000000 --- a/resources/Schema/Entities/Ray2Red.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - Textures/Effects/Ray.png - - - - - - - - - - - - - - - Textures/Effects/Ray.png - - - - - - - - - - - - - - diff --git a/resources/Schema/Entities/RayBlue b/resources/Schema/Entities/RayBlue deleted file mode 100644 index d34e185e..00000000 --- a/resources/Schema/Entities/RayBlue +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - Models/Core/UnitCylinder.mesh - - - - - - - - - - - diff --git a/resources/Schema/Entities/RayBlue.xml b/resources/Schema/Entities/RayBlue.xml index 022d7769..0ad0ddf0 100644 --- a/resources/Schema/Entities/RayBlue.xml +++ b/resources/Schema/Entities/RayBlue.xml @@ -1,20 +1,46 @@ - + - 0.25 + 0.10000000149011612 - - Models/Effects/CylinderShot.mesh - - true - - + - + + + + + Textures/Effects/Ray.png + + + + + + + + + + + + + + + Textures/Effects/Ray.png + + + + + + + + + + + + diff --git a/resources/Schema/Entities/RayRed b/resources/Schema/Entities/RayRed deleted file mode 100644 index d34e185e..00000000 --- a/resources/Schema/Entities/RayRed +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - Models/Core/UnitCylinder.mesh - - - - - - - - - - - diff --git a/resources/Schema/Entities/RayRed.xml b/resources/Schema/Entities/RayRed.xml deleted file mode 100644 index 0a20f148..00000000 --- a/resources/Schema/Entities/RayRed.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - 0.25 - - - Models/Effects/CylinderShot.mesh - - true - - - - - - - - - diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 10107ab1..9ebb28eb 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -18,6 +18,7 @@ #include "Game/Systems/PickupSpawnSystem.h" #include "Game/Systems/AmmoPickupSystem.h" #include "Game/Systems/DamageIndicatorSystem.h" +#include "Game/Systems/Weapon/AssaultWeaponBehaviour.h" #include "Game/Systems/Weapon/DefenderWeaponBehaviour.h" #include "Game/Systems/Weapon/SidearmWeaponBehaviour.h" #include "Rendering/AnimationSystem.h" @@ -128,6 +129,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel); 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_Renderer, m_OctreeCollision); m_SystemPipeline->AddSystem(updateOrderLevel); diff --git a/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp new file mode 100644 index 00000000..c982637b --- /dev/null +++ b/src/Game/Systems/Weapon/AssaultWeaponBehaviour.cpp @@ -0,0 +1,228 @@ +#include "Systems/Weapon/AssaultWeaponBehaviour.h" + +void AssaultWeaponBehaviour::UpdateComponent(EntityWrapper& entity, ComponentWrapper& cWeapon, double dt) +{ + double& fireCooldown = cWeapon["FireCooldown"]; + fireCooldown = glm::max(0.0, fireCooldown - dt); + + WeaponBehaviour::UpdateComponent(entity, cWeapon, dt); +} + +void AssaultWeaponBehaviour::UpdateWeapon(ComponentWrapper cWeapon, WeaponInfo& wi, double dt) +{ + // Decrement reload timer + double& reloadTimer = cWeapon["ReloadTimer"]; + reloadTimer = glm::max(0.0, reloadTimer - dt); + + // Start reloading automatically if at 0 mag ammo + int& magAmmo = cWeapon["MagazineAmmo"]; + if (m_ConfigAutoReload && magAmmo <= 0) { + OnReload(cWeapon, wi); + } + + // Handle reloading + bool& isReloading = cWeapon["IsReloading"]; + if (isReloading && reloadTimer <= 0.0) { + int& magSize = cWeapon["MagazineSize"]; + int& ammo = cWeapon["Ammo"]; + + ammo = glm::max(0, ammo - (magSize - magAmmo)); + magAmmo = glm::min(magSize, ammo); + isReloading = false; + } + + // Restore view angle + if (IsClient) { + float& currentTravel = cWeapon["CurrentTravel"]; + float& returnSpeed = cWeapon["ViewReturnSpeed"]; + if (currentTravel > 0) { + float change = returnSpeed * dt; + currentTravel = glm::max(0.f, currentTravel - change); + EntityWrapper camera = wi.Player.FirstChildByName("Camera"); + if (camera.Valid()) { + glm::vec3& cameraOrientation = camera["Transform"]["Orientation"]; + cameraOrientation.x -= change; + } + } + } + + // Fire if we're able to fire + if (canFire(cWeapon, wi)) { + fireBullet(cWeapon, wi); + } +} + +void AssaultWeaponBehaviour::OnPrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + cWeapon["TriggerHeld"] = true; + if (canFire(cWeapon, wi)) { + fireBullet(cWeapon, wi); + } +} + +void AssaultWeaponBehaviour::OnCeasePrimaryFire(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + cWeapon["TriggerHeld"] = false; +} + +void AssaultWeaponBehaviour::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; +} + +void AssaultWeaponBehaviour::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; +} + +void AssaultWeaponBehaviour::fireBullet(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + cWeapon["FireCooldown"] = 60.0 / (double)cWeapon["RPM"]; + + // Ammo + int& magAmmo = cWeapon["MagazineAmmo"]; + if (magAmmo <= 0) { + return; + } else { + magAmmo -= 1; + } + + // View punch + if (IsClient) { + EntityWrapper camera = wi.Player.FirstChildByName("Camera"); + if (camera.Valid()) { + glm::vec3& cameraOrientation = camera["Transform"]["Orientation"]; + float viewPunch = cWeapon["ViewPunch"]; + float maxTravelAngle = cWeapon["MaxTravelAngle"]; + float& currentTravel = cWeapon["CurrentTravel"]; + if (currentTravel < maxTravelAngle) { + float change = viewPunch; + if (currentTravel + change > maxTravelAngle) { + change = maxTravelAngle - currentTravel; + } + cameraOrientation.x += change; + currentTravel += change; + } + } + } + + // 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 = glm::quat(Transform::AbsoluteOrientationEuler(tracerSpawner)) * glm::vec3(0, 0, -1); + float distance = traceRayDistance(origin, direction); + EntityWrapper ray = SpawnerSystem::Spawn(tracerSpawner); + if (ray.Valid()) { + ((glm::vec3&)ray["Transform"]["Scale"]).z = distance; + } + } + + // Deal damage + if (dealDamage(cWeapon, wi)) { + // Show hit marker + EntityWrapper hitMarkerSpawner = wi.Player.FirstChildByName("HitMarkerSpawner"); + if (hitMarkerSpawner.Valid()) { + SpawnerSystem::Spawn(hitMarkerSpawner, hitMarkerSpawner); + Events::PlaySoundOnEntity e; + e.EmitterID = wi.Player.ID; + e.FilePath = "Audio/weapon/hitclick.wav"; + m_EventBroker->Publish(e); + } + } +} + +bool AssaultWeaponBehaviour::canFire(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + bool triggerHeld = cWeapon["TriggerHeld"]; + bool cooldownPassed = (double)cWeapon["FireCooldown"] <= 0.0; + bool isReloading = cWeapon["IsReloading"]; + return triggerHeld && cooldownPassed; +} + +bool AssaultWeaponBehaviour::dealDamage(ComponentWrapper cWeapon, WeaponInfo& wi) +{ + // Only deal damage client side + if (!IsClient) { + return false; + } + + // Only handle damage for the local player + if (wi.Player != LocalPlayer) { + return false; + } + + // Make sure the player isn't shooting from the grave + if (!wi.Player.Valid()) { + return false; + } + + // 3D-pick middle of screen + Rectangle viewport = m_Renderer->GetViewportSize(); + glm::vec2 centerScreen(viewport.Width / 2, viewport.Height / 2); + // TODO: Some horizontal spread + PickData pickData = m_Renderer->Pick(centerScreen); + EntityWrapper victim(m_World, pickData.Entity); + if (!victim.Valid()) { + return false; + } + + // Don't let us somehow shoot ourselves in the foot + if (victim == LocalPlayer) { + return false; + } + + // Only care about players being hit + if (!victim.HasComponent("Player")) { + victim = victim.FirstParentWithComponent("Player"); + } + if (!victim.Valid()) { + return false; + } + + double damage = cWeapon["BaseDamage"]; + // If friendly fire, reduce damage to 0 (needed to make Boosts, Ammosharing work) + if ((ComponentInfo::EnumType)victim["Team"]["Team"] == (ComponentInfo::EnumType)wi.Player["Team"]["Team"]) { + damage = 0; + } + + // Deal damage! + Events::PlayerDamage ePlayerDamage; + ePlayerDamage.Inflictor = wi.Player; + ePlayerDamage.Victim = victim; + ePlayerDamage.Damage = damage; + m_EventBroker->Publish(ePlayerDamage); + + return damage > 0; +}