From f281d220de9e466a701d8d0f9200833fa00a5cab Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Sun, 17 Jan 2016 01:00:48 +0100 Subject: [PATCH] Working Spawner, SpawnPoint, PlayerSpawn and Team components, along with their systems. --- include/Engine/Core/EntityWrapper.h | 2 + include/Game/Systems/PlayerSpawnSystem.h | 1 + include/Game/Systems/SpawnerSystem.h | 9 +++- resources/Schema/Components.xsd | 1 - resources/Schema/Components/PlayerSpawn.xml | 4 +- resources/Schema/Components/PlayerSpawn.xsd | 9 +--- resources/Schema/Entities/SpawnTest.xml | 9 +++- resources/Schema/Entities/TeamTest.xml | 13 +++++ resources/Schema/Types/Entity.xsd | 1 - src/Engine/Core/EntityWrapper.cpp | 2 + src/Engine/Input/InputProxy.cpp | 4 +- src/Game/Systems/PlayerSpawnSystem.cpp | 28 +++++++--- src/Game/Systems/SpawnerSystem.cpp | 60 +++++++++++++-------- 13 files changed, 93 insertions(+), 50 deletions(-) create mode 100755 resources/Schema/Entities/TeamTest.xml diff --git a/include/Engine/Core/EntityWrapper.h b/include/Engine/Core/EntityWrapper.h index 4cc8bbea..55b64c6f 100644 --- a/include/Engine/Core/EntityWrapper.h +++ b/include/Engine/Core/EntityWrapper.h @@ -20,6 +20,8 @@ struct EntityWrapper ::World* World; EntityID ID; + static const EntityWrapper Invalid; + bool HasComponent(const std::string& componentName); ComponentWrapper operator[](const std::string& componentName); diff --git a/include/Game/Systems/PlayerSpawnSystem.h b/include/Game/Systems/PlayerSpawnSystem.h index 414d32d8..f0e10949 100644 --- a/include/Game/Systems/PlayerSpawnSystem.h +++ b/include/Game/Systems/PlayerSpawnSystem.h @@ -1,5 +1,6 @@ #include "Core/System.h" #include "Input/EInputCommand.h" +#include "Systems/SpawnerSystem.h" #include "Events/ESpawnerSpawn.h" class PlayerSpawnSystem : public ImpureSystem diff --git a/include/Game/Systems/SpawnerSystem.h b/include/Game/Systems/SpawnerSystem.h index cbb7c100..2c094528 100644 --- a/include/Game/Systems/SpawnerSystem.h +++ b/include/Game/Systems/SpawnerSystem.h @@ -1,3 +1,6 @@ +#ifndef SpawnerSystem_h__ +#define SpawnerSystem_h__ + #include #include "Common.h" #include "GLM.h" @@ -12,9 +15,11 @@ class SpawnerSystem : public System public: SpawnerSystem(EventBroker* eventBroker); + static EntityWrapper Spawn(EntityWrapper spawner, EntityWrapper parent = EntityWrapper::Invalid); + private: EventRelay m_OnSpawnerSpawn; bool OnSpawnerSpawn(Events::SpawnerSpawn& e); +}; - void spawnEntity(EntityWrapper spawner, EntityID parent, glm::vec3 position); -}; \ No newline at end of file +#endif \ No newline at end of file diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 88f09d6c..8d837aea 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -4,7 +4,6 @@ - diff --git a/resources/Schema/Components/PlayerSpawn.xml b/resources/Schema/Components/PlayerSpawn.xml index 1c621ef9..edc1394e 100644 --- a/resources/Schema/Components/PlayerSpawn.xml +++ b/resources/Schema/Components/PlayerSpawn.xml @@ -1,4 +1,2 @@ - - 1 - \ No newline at end of file + \ No newline at end of file diff --git a/resources/Schema/Components/PlayerSpawn.xsd b/resources/Schema/Components/PlayerSpawn.xsd index b076de27..6e321724 100644 --- a/resources/Schema/Components/PlayerSpawn.xsd +++ b/resources/Schema/Components/PlayerSpawn.xsd @@ -5,14 +5,7 @@ - Combined with a Spawner, defines a spawn point for a player team. + Combined with a Spawner and a Team component, defines a spawn point for a player team. - - - - 1 = Spectator, 2 = Red, 3 = Blue - - - diff --git a/resources/Schema/Entities/SpawnTest.xml b/resources/Schema/Entities/SpawnTest.xml index f4af726d..a5574027 100644 --- a/resources/Schema/Entities/SpawnTest.xml +++ b/resources/Schema/Entities/SpawnTest.xml @@ -8,9 +8,13 @@ + Schema/Entities/Player.xml + + 2 + @@ -47,9 +51,10 @@ + - - + + diff --git a/resources/Schema/Entities/TeamTest.xml b/resources/Schema/Entities/TeamTest.xml new file mode 100755 index 00000000..69be6141 --- /dev/null +++ b/resources/Schema/Entities/TeamTest.xml @@ -0,0 +1,13 @@ + + + + + + 3 + + + + + + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index 3ca6e545..1aaa8497 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -13,7 +13,6 @@ - diff --git a/src/Engine/Core/EntityWrapper.cpp b/src/Engine/Core/EntityWrapper.cpp index 9d15dd39..7b321a63 100644 --- a/src/Engine/Core/EntityWrapper.cpp +++ b/src/Engine/Core/EntityWrapper.cpp @@ -1,6 +1,8 @@ #include "Core/EntityWrapper.h" #include "Core/World.h" +const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Invalid); + bool EntityWrapper::operator==(const EntityWrapper& e) { return (this->World == e.World) && (this->ID == e.ID); diff --git a/src/Engine/Input/InputProxy.cpp b/src/Engine/Input/InputProxy.cpp index 7e977542..6c3591e3 100644 --- a/src/Engine/Input/InputProxy.cpp +++ b/src/Engine/Input/InputProxy.cpp @@ -63,7 +63,7 @@ void InputProxy::Process() e.Command = command; e.Value = currentValue; m_EventBroker->Publish(e); - LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); + //LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); m_LastCommandValues[command] = currentValue; } } @@ -79,7 +79,7 @@ void InputProxy::Process() } //e.Value = std::max(-1.f, std::min(e.Value, 1.f)); m_EventBroker->Publish(e); - LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); + //LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, e.PlayerID); } m_CommandQueue.clear(); } diff --git a/src/Game/Systems/PlayerSpawnSystem.cpp b/src/Game/Systems/PlayerSpawnSystem.cpp index a522f679..0bf5bdea 100644 --- a/src/Game/Systems/PlayerSpawnSystem.cpp +++ b/src/Game/Systems/PlayerSpawnSystem.cpp @@ -8,17 +8,29 @@ PlayerSpawnSystem::PlayerSpawnSystem(EventBroker* eventBroker) void PlayerSpawnSystem::Update(World* world, double dt) { - auto componentPools = world->GetComponentPools(); - auto spawnerPool = componentPools.find("Spawner"); - if (spawnerPool == componentPools.end()) { + auto playerSpawns = world->GetComponents("PlayerSpawn"); + if (playerSpawns == nullptr) { return; } -; + for (auto& team : m_SpawnRequests) { - for (auto& spawner : *spawnerPool->second) { - Events::SpawnerSpawn e; - e.Spawner = EntityWrapper(world, spawner.EntityID); - m_EventBroker->Publish(e); + for (auto& cPlayerSpawn : *playerSpawns) { + EntityWrapper spawner(world, cPlayerSpawn.EntityID); + if (!spawner.HasComponent("Spawner")) { + continue; + } + + // If the spawner has a team affiliation, check it + if (spawner.HasComponent("Team")) { + if ((int)spawner["Team"]["Team"] != team) { + continue; + } + } + + // Spawn the player! + EntityWrapper player = SpawnerSystem::Spawn(spawner); + // Set the player team affiliation + player["Team"]["Team"] = team; } } m_SpawnRequests.clear(); diff --git a/src/Game/Systems/SpawnerSystem.cpp b/src/Game/Systems/SpawnerSystem.cpp index c1122d98..3454c58b 100644 --- a/src/Game/Systems/SpawnerSystem.cpp +++ b/src/Game/Systems/SpawnerSystem.cpp @@ -5,43 +5,57 @@ SpawnerSystem::SpawnerSystem(EventBroker* eventBroker) : System(eventBroker) EVENT_SUBSCRIBE_MEMBER(m_OnSpawnerSpawn, &SpawnerSystem::OnSpawnerSpawn); } -bool SpawnerSystem::OnSpawnerSpawn(Events::SpawnerSpawn& e) +EntityWrapper SpawnerSystem::Spawn(EntityWrapper spawner, EntityWrapper parent /*= EntityWrapper::Invalid*/) { - EntityWrapper& spawner = e.Spawner; + // Spawn the entity in the parent's world if it exists, otherwise in the spawner's world + World* world = parent.World; + if (world == nullptr) { + world = spawner.World; + } + // Find any SpawnPoints existing as children of spawner auto children = spawner.World->GetChildren(spawner.ID); - std::vector spawnPoints; + std::vector spawnPoints; for (auto kv = children.first; kv != children.second; ++kv) { const EntityID& child = kv->second; if (spawner.World->HasComponent(child, "SpawnPoint")) { - spawnPoints.push_back(child); + spawnPoints.push_back(EntityWrapper(spawner.World, child)); } } - EntityID spawnPoint = spawner.ID; + // Choose a random SpawnPoint + EntityWrapper spawnPoint = spawner; if (!spawnPoints.empty()) { - // Select a random spawn point - static std::random_device randomDevice; - static std::mt19937 randomGenerator(randomDevice()); - std::uniform_int_distribution<> distribution(0, std::distance(spawnPoints.begin(), spawnPoints.end()) - 1); - auto randomSpawnPointIt = spawnPoints.begin(); - std::advance(randomSpawnPointIt, distribution(randomGenerator)); - spawnPoint = *randomSpawnPointIt; + if (spawnPoints.size() > 1) { + static std::random_device randomDevice; + static std::mt19937 randomGenerator(randomDevice()); + std::uniform_int_distribution<> distribution(0, std::distance(spawnPoints.begin(), spawnPoints.end()) - 1); + auto randomSpawnPointIt = spawnPoints.begin(); + std::advance(randomSpawnPointIt, distribution(randomGenerator)); + spawnPoint = *randomSpawnPointIt; + } else { + spawnPoint = spawnPoints.front(); + } } - spawnEntity(spawner, e.Parent.ID, Transform::AbsolutePosition(spawner.World, spawnPoint)); - - return true; -} - -void SpawnerSystem::spawnEntity(EntityWrapper spawner, EntityID parent, glm::vec3 position) -{ + + // Load the entity file and parse it const std::string& entityFilePath = spawner["Spawner"]["EntityFile"]; auto entityFile = ResourceManager::Load(entityFilePath); if (entityFile == nullptr) { - return; + return EntityWrapper::Invalid; } - EntityFileParser parser(entityFile); - EntityWrapper spawnedEntity(spawner.World, parser.MergeEntities(spawner.World, parent)); - spawnedEntity["Transform"]["Position"] = position; + EntityWrapper spawnedEntity(world, parser.MergeEntities(world, parent.ID)); + + // Set its position and orientation to that of the SpawnPoint + spawnedEntity["Transform"]["Position"] = Transform::AbsolutePosition(spawnPoint.World, spawnPoint.ID); + spawnedEntity["Transform"]["Orientation"] = glm::eulerAngles(Transform::AbsoluteOrientation(spawnPoint.World, spawnPoint.ID)); + + return spawnedEntity; +} + +bool SpawnerSystem::OnSpawnerSpawn(Events::SpawnerSpawn& e) +{ + EntityWrapper spawnedEntity = Spawn(e.Spawner, e.Parent); + return true; } \ No newline at end of file