diff --git a/include/Engine/Core/EPickupSpawned.h b/include/Engine/Core/EPickupSpawned.h new file mode 100644 index 00000000..9f85913a --- /dev/null +++ b/include/Engine/Core/EPickupSpawned.h @@ -0,0 +1,17 @@ +#ifndef EPickupSpawned_h__ +#define EPickupSpawned_h__ + +#include "Core/Event.h" +#include "Core/EntityWrapper.h" + +namespace Events +{ + +struct PickupSpawned : Event +{ + EntityWrapper Pickup; +}; + +} + +#endif \ No newline at end of file diff --git a/include/Game/Systems/HealthSystem.h b/include/Game/Systems/HealthSystem.h index 46f24630..61456d5d 100644 --- a/include/Game/Systems/HealthSystem.h +++ b/include/Game/Systems/HealthSystem.h @@ -12,6 +12,7 @@ #include #include +#include class HealthSystem : public PureSystem { diff --git a/include/Game/Systems/PickupSpawnSystem.h b/include/Game/Systems/PickupSpawnSystem.h new file mode 100644 index 00000000..24cee2b9 --- /dev/null +++ b/include/Game/Systems/PickupSpawnSystem.h @@ -0,0 +1,33 @@ +#ifndef PickupSpawnSystem_h__ +#define PickupSpawnSystem_h__ + +#include "Core/System.h" +#include "Core/Transform.h" +#include "Core/ResourceManager.h" +#include "Core/EntityFileParser.h" +#include "Core/EPickupSpawned.h" +#include "Core/EPlayerHealthPickup.h" +#include "Engine/Collision/ETrigger.h" +#include "Common.h" +#include + +class PickupSpawnSystem : public ImpureSystem +{ +public: + PickupSpawnSystem(World* world, EventBroker* eventBroker); + + virtual void Update(double dt) override; + +private: + EventRelay m_ETriggerTouch; + bool OnTriggerTouch(Events::TriggerTouch& e); + + struct NewHealthPickup { + glm::vec3 Pos; + double HealthGain; + double RespawnTimer; + double DecreaseThisRespawnTimer; + }; + std::vector m_ETriggerTouchVector; +}; +#endif diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 265a3cc5..c3c1e0af 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -30,5 +30,6 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/HealthPickup.xml b/resources/Schema/Components/HealthPickup.xml new file mode 100644 index 00000000..1c9ee0f4 --- /dev/null +++ b/resources/Schema/Components/HealthPickup.xml @@ -0,0 +1,5 @@ + + + 3 + 30 + \ No newline at end of file diff --git a/resources/Schema/Components/HealthPickup.xsd b/resources/Schema/Components/HealthPickup.xsd new file mode 100644 index 00000000..bf3b327c --- /dev/null +++ b/resources/Schema/Components/HealthPickup.xsd @@ -0,0 +1,21 @@ + + + + + + + + A Health Pickup + + + + + The respawn timer for a health pickup + + + How much percent max-health the player will get when he picks the healthPickup up + + + + + diff --git a/resources/Schema/Entities/HealthPickup.xml b/resources/Schema/Entities/HealthPickup.xml new file mode 100644 index 00000000..dfc6f938 --- /dev/null +++ b/resources/Schema/Entities/HealthPickup.xml @@ -0,0 +1,18 @@ + + + + + + + + Models/Core/UnitSphere.mesh + + + + + + + + + + diff --git a/resources/Schema/Entities/HealthPickupTest.xml b/resources/Schema/Entities/HealthPickupTest.xml new file mode 100644 index 00000000..2980fb51 --- /dev/null +++ b/resources/Schema/Entities/HealthPickupTest.xml @@ -0,0 +1,294 @@ + + + + + + + + + + + + Models\MapVersion1.mesh + + + + + + + + + 2 + + + Models/DirectionalLightWidget.mesh + false + + + + + + + + + + + + + 8 + 2.7999999523162842 + + + + + + + + + + + 8 + 2.7999999523162842 + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + + + + + + + + + + + + + Models/Core/UnitCube.mesh + false + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Models/Core/UnitCube.mesh + false + + + Schema/Entities/Player.xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + 22 + + + Models/Core/UnitSphere.mesh + + + + + + + + + + + + + 1 + 22 + + + Models/Core/UnitSphere.mesh + + + + + + + + + + + + + 4 + 44 + + + Models/Core/UnitSphere.mesh + + + + + + + + + + + diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 6dbd98f4..0c92271d 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -11,6 +11,7 @@ #include "Systems/PlayerDeathSystem.h" #include "Core/EntityFileWriter.h" #include "Game/Systems/CapturePointSystem.h" +#include "Game/Systems/PickupSpawnSystem.h" #include "Game/Systems/WeaponSystem.h" #include "Game/Systems/PlayerHUD.h" #include "Game/Systems/LifetimeSystem.h" @@ -93,6 +94,7 @@ Game::Game(int argc, char* argv[]) m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); m_SystemPipeline->AddSystem(updateOrderLevel); m_SystemPipeline->AddSystem(updateOrderLevel); + m_SystemPipeline->AddSystem(updateOrderLevel); // Populate Octree with collidables ++updateOrderLevel; m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); diff --git a/src/Game/Systems/HealthSystem.cpp b/src/Game/Systems/HealthSystem.cpp index 18a15828..de290aa5 100644 --- a/src/Game/Systems/HealthSystem.cpp +++ b/src/Game/Systems/HealthSystem.cpp @@ -18,7 +18,7 @@ bool HealthSystem::OnPlayerDamaged(Events::PlayerDamage& e) ComponentWrapper cHealth = e.Player["Health"]; double& health = cHealth["Health"]; health -= e.Damage; - + if (health <= 0.0) { Events::PlayerDeath ePlayerDeath; ePlayerDeath.Player = e.Player; @@ -33,8 +33,8 @@ bool HealthSystem::OnPlayerHealthPickup(Events::PlayerHealthPickup& e) { ComponentWrapper cHealth = e.Player["Health"]; double& health = cHealth["Health"]; - //NOTE: its possible to get more than MaxHealth health health += e.HealthAmount; + health = std::min(health, (double)cHealth["MaxHealth"]); return true; } diff --git a/src/Game/Systems/PickupSpawnSystem.cpp b/src/Game/Systems/PickupSpawnSystem.cpp new file mode 100644 index 00000000..e9f201c1 --- /dev/null +++ b/src/Game/Systems/PickupSpawnSystem.cpp @@ -0,0 +1,66 @@ +#include "Systems/PickupSpawnSystem.h" + +PickupSpawnSystem::PickupSpawnSystem(World* m_World, EventBroker* eventBroker) + : System(m_World, eventBroker) +{ + EVENT_SUBSCRIBE_MEMBER(m_ETriggerTouch, &PickupSpawnSystem::OnTriggerTouch); +} + +void PickupSpawnSystem::Update(double dt) +{ + for (auto it = m_ETriggerTouchVector.begin(); it != m_ETriggerTouchVector.end(); ++it) + { + auto& healthPickupPosition = *it; + //set the double timer value (value 3) + healthPickupPosition.DecreaseThisRespawnTimer -= dt; + if (healthPickupPosition.DecreaseThisRespawnTimer < 0) { + //spawn and delete the vector item + auto entityFile = ResourceManager::Load("Schema/Entities/HealthPickup.xml"); + EntityFileParser parser(entityFile); + EntityID healthPickupID = parser.MergeEntities(m_World); + + //let the world know a pickup has spawned (graphics effects, etc) + Events::PickupSpawned ePickupSpawned; + ePickupSpawned.Pickup = EntityWrapper(m_World, healthPickupID); + m_EventBroker->Publish(ePickupSpawned); + + //set values from the old entity to the new entity + auto& newHealthPickupEntity = EntityWrapper(m_World, healthPickupID); + newHealthPickupEntity["Transform"]["Position"] = healthPickupPosition.Pos; + newHealthPickupEntity["HealthPickup"]["HealthGain"] = healthPickupPosition.HealthGain; + newHealthPickupEntity["HealthPickup"]["RespawnTimer"] = healthPickupPosition.RespawnTimer; + + //erase the current element (healthPickupPosition) + m_ETriggerTouchVector.erase(it); + break; + } + } +} + + +bool PickupSpawnSystem::OnTriggerTouch(Events::TriggerTouch& e) +{ + if (!e.Trigger.HasComponent("HealthPickup")) { + return false; + } + double healthGiven = 0.01*(double)e.Trigger["HealthPickup"]["HealthGain"] * (double)e.Entity["Health"]["MaxHealth"]; + //cant pick up healthpacks if you are already at MaxHealth + if ((double)e.Entity["Health"]["Health"] >= (double)e.Entity["Health"]["MaxHealth"]) { + return false; + } + + //personEntered = e.Entity, thingEntered = e.Trigger + Events::PlayerHealthPickup ePlayerHealthPickup; + ePlayerHealthPickup.HealthAmount = healthGiven; + ePlayerHealthPickup.Player = e.Entity; + m_EventBroker->Publish(ePlayerHealthPickup); + + //copy position, healthgain, respawntimer (twice since one of the values will be counted down to 0, the other will be set in the new object) + //we need to copy all values since each value can be different for each healthPickup + m_ETriggerTouchVector.push_back({ (glm::vec3)e.Trigger["Transform"]["Position"] ,e.Trigger["HealthPickup"]["HealthGain"], + e.Trigger["HealthPickup"]["RespawnTimer"],e.Trigger["HealthPickup"]["RespawnTimer"] }); + + //delete the healthpickup + m_World->DeleteEntity(e.Trigger.ID); + return true; +}