diff --git a/include/Engine/Core/EntitySystem.h b/include/Engine/Core/EntitySystem.h new file mode 100644 index 00000000..8f6a930a --- /dev/null +++ b/include/Engine/Core/EntitySystem.h @@ -0,0 +1,19 @@ +#ifndef EntitySystem_h__ +#define EntitySystem_h__ + +#include "World.h" +#include "SystemPipeline.h" + +// An "EntitySystem" is defined as the combination of a World with a SystemPipeline +template +class EntitySystem : public WorldType, public SystemPipeline +{ + static_assert(std::is_base_of::value, "WorldType must inherit from World"); +public: + EntitySystem(EventBroker* eventBroker, bool isClient, bool isServer) + : WorldType(eventBroker) + , SystemPipeline(this, eventBroker, isClient, isServer) + { } +}; + +#endif \ No newline at end of file diff --git a/include/Game/CapturePointsEntitySystem.h b/include/Game/CapturePointsEntitySystem.h new file mode 100644 index 00000000..6d07bcb3 --- /dev/null +++ b/include/Game/CapturePointsEntitySystem.h @@ -0,0 +1,18 @@ +#include "Core/EntitySystem.h" +#include "Rendering/IRenderer.h" +#include "Core/Octree.h" +#include "Collision/EntityAABB.h" + +class CapturePointsEntitySystem : public EntitySystem +{ +public: + CapturePointsEntitySystem(EventBroker* eventBroker, bool isClient, bool isServer, IRenderer* renderer, RenderFrame* renderFrame); + ~CapturePointsEntitySystem(); + +private: + IRenderer* m_Renderer; + RenderFrame* m_RenderFrame; + Octree* m_OctreeCollision = nullptr; + Octree* m_OctreeTrigger = nullptr; + Octree* m_OctreeFrustrumCulling = nullptr; +}; \ No newline at end of file diff --git a/include/Game/Events/EGameEnd.h b/include/Game/Events/EGameEnd.h new file mode 100644 index 00000000..8d9da448 --- /dev/null +++ b/include/Game/Events/EGameEnd.h @@ -0,0 +1,16 @@ +#ifndef EGameEnd_h__ +#define EGameEnd_h__ + +#include "Core/Event.h" + +namespace Events +{ + +struct GameEnd : Event +{ + +}; + +} + +#endif \ No newline at end of file diff --git a/include/Game/Events/EGameStart.h b/include/Game/Events/EGameStart.h new file mode 100644 index 00000000..3a180244 --- /dev/null +++ b/include/Game/Events/EGameStart.h @@ -0,0 +1,16 @@ +#ifndef EGameStart_h__ +#define EGameStart_h__ + +#include "Core/Event.h" + +namespace Events +{ + +struct GameStart : Event +{ + +}; + +} + +#endif \ No newline at end of file diff --git a/include/Game/Events/EWin.h b/include/Game/Events/EWin.h index 160b39c1..e5a89770 100644 --- a/include/Game/Events/EWin.h +++ b/include/Game/Events/EWin.h @@ -10,8 +10,8 @@ namespace Events //triggers when a team has captured all capturePoints struct Win : Event { - //can be 0 = none, 1,2 - int TeamThatWon; + // The winning team corresponding to TeamEnum + ComponentInfo::EnumType Team; }; } diff --git a/include/Game/Game.h b/include/Game/Game.h index 06fd4703..0688914d 100644 --- a/include/Game/Game.h +++ b/include/Game/Game.h @@ -12,18 +12,16 @@ #include "Input/InputProxy.h" #include "Input/KeyboardInputHandler.h" #include "Input/MouseInputHandler.h" -#include "Core/EKeyDown.h" #include "Core/EntityFilePreprocessor.h" -#include "Core/SystemPipeline.h" +#include "Core/EntitySystem.h" #include "Systems/ExplosionEffectSystem.h" #include "Editor/EditorSystem.h" #include "Core/EntityFile.h" -#include "Rendering/RenderSystem.h" #include "Core/EntityFileParser.h" #include "Core/Octree.h" #include "Rendering/Font.h" -#include "Systems/InterpolationSystem.h" #include "Collision/EntityAABB.h" + // Network #include #include "Network/Network.h" @@ -55,11 +53,7 @@ private: IRenderer* m_Renderer; InputManager* m_InputManager; InputProxy* m_InputProxy; - World* m_World; - Octree* m_OctreeCollision; - Octree* m_OctreeTrigger; - Octree* m_OctreeFrustrumCulling; - SystemPipeline* m_SystemPipeline; + EntitySystem* m_EntitySystem; RenderFrame* m_RenderFrame; Client* m_NetworkClient = nullptr; Server* m_NetworkServer = nullptr; diff --git a/include/Game/MainMenuEntitySystem.h b/include/Game/MainMenuEntitySystem.h new file mode 100644 index 00000000..e69de29b diff --git a/include/Game/Systems/CapturePointSystem.h b/include/Game/Systems/CapturePointSystem.h index 2c24b383..670f7b12 100644 --- a/include/Game/Systems/CapturePointSystem.h +++ b/include/Game/Systems/CapturePointSystem.h @@ -8,7 +8,6 @@ #include "Core/System.h" #include "Engine/Collision/ETrigger.h" #include "Events/ECaptured.h" -#include "Events/EWin.h" #include #include diff --git a/include/Game/Systems/CapturePointsGamemode.h b/include/Game/Systems/CapturePointsGamemode.h new file mode 100644 index 00000000..e43a29af --- /dev/null +++ b/include/Game/Systems/CapturePointsGamemode.h @@ -0,0 +1,27 @@ +#include "Core/System.h" +#include "Events/EGameStart.h" +#include "Events/EGameEnd.h" +#include "Events/ECaptured.h" +#include "Events/EWin.h" + +class CapturePointsGamemode : public ImpureSystem +{ +public: + CapturePointsGamemode(SystemParams params); + + virtual void Update(double dt) override; + +private: + bool m_GameRuning = false; + double m_GameTime = 0.0; + + EventRelay m_EGameStart; + bool OnGameStart(const Events::GameStart& e); + EventRelay m_ECaptured; + bool OnCaptured(const Events::Captured& e); + + boost::optional currentGamemode(); + bool isCurrentGamemode(); + boost::optional winCondition(); + void setRunning(bool running); +}; \ No newline at end of file diff --git a/resources/Schema/Components.xsd b/resources/Schema/Components.xsd index 74423f56..a0bae212 100644 --- a/resources/Schema/Components.xsd +++ b/resources/Schema/Components.xsd @@ -45,4 +45,5 @@ + \ No newline at end of file diff --git a/resources/Schema/Components/Gamemode.xml b/resources/Schema/Components/Gamemode.xml new file mode 100644 index 00000000..3ede5e6b --- /dev/null +++ b/resources/Schema/Components/Gamemode.xml @@ -0,0 +1,6 @@ + + + + 0 + false + \ No newline at end of file diff --git a/resources/Schema/Components/Gamemode.xsd b/resources/Schema/Components/Gamemode.xsd new file mode 100644 index 00000000..b92b81f2 --- /dev/null +++ b/resources/Schema/Components/Gamemode.xsd @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/Schema/Types/Entity.xsd b/resources/Schema/Types/Entity.xsd index a9c5f641..0f53d2bc 100644 --- a/resources/Schema/Types/Entity.xsd +++ b/resources/Schema/Types/Entity.xsd @@ -50,6 +50,7 @@ + diff --git a/src/Game/CMakeLists.txt b/src/Game/CMakeLists.txt index d8ba8599..c36a6895 100644 --- a/src/Game/CMakeLists.txt +++ b/src/Game/CMakeLists.txt @@ -33,10 +33,16 @@ file(GLOB SOURCE_FILES_Network "Network/*.cpp" ) source_group(Network FILES ${SOURCE_FILES_Network}) + +file(GLOB SOURCE_FILES + "${INCLUDE_PATH}/*.h" + "*.cpp" +) +list(REMOVE_ITEM SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/main.cpp") +source_group(Game FILES ${SOURCE_FILES}) + set(SOURCE_FILES ${SOURCE_FILES} - "Game.cpp" - "MiniDump.cpp" ${SOURCE_FILES_Systems} ${SOURCE_FILES_Systems_Weapon} ${SOURCE_FILES_Events} diff --git a/src/Game/CapturePointsEntitySystem.cpp b/src/Game/CapturePointsEntitySystem.cpp new file mode 100644 index 00000000..6bc2ea90 --- /dev/null +++ b/src/Game/CapturePointsEntitySystem.cpp @@ -0,0 +1,98 @@ +#include "CapturePointsEntitySystem.h" +#include "Systems/InterpolationSystem.h" +#include "Systems/SoundSystem.h" +#include "Systems/RaptorCopterSystem.h" +#include "Systems/ExplosionEffectSystem.h" +#include "Systems/HealthSystem.h" +#include "Systems/PlayerMovementSystem.h" +#include "Systems/SpawnerSystem.h" +#include "Systems/PlayerSpawnSystem.h" +#include "Systems/Weapon/WeaponSystem.h" +#include "Systems/LifetimeSystem.h" +#include "Systems/CapturePointSystem.h" +#include "Systems/CapturePointHUDSystem.h" +#include "Systems/PickupSpawnSystem.h" +#include "Systems/AmmoPickupSystem.h" +#include "Systems/DamageIndicatorSystem.h" +#include "Systems/AmmunitionHUDSystem.h" +#include "Systems/KillFeedSystem.h" +#include "GUI/ButtonSystem.h" +#include "GUI/MainMenuSystem.h" +#include "Collision/FillOctreeSystem.h" +#include "Collision/FillFrustumOctreeSystem.h" +#include "Rendering/AnimationSystem.h" +#include "Core/UniformScaleSystem.h" +#include "Systems/HealthHUDSystem.h" +#include "Systems/PlayerDeathSystem.h" +#include "Rendering/BoneAttachmentSystem.h" +#include "Collision/CollisionSystem.h" +#include "Collision/TriggerSystem.h" +#include "Rendering/RenderSystem.h" +#include "Editor/EditorSystem.h" + +CapturePointsEntitySystem::CapturePointsEntitySystem(EventBroker* eventBroker, bool isClient, bool isServer, IRenderer* renderer, RenderFrame* renderFrame) + : EntitySystem(eventBroker, isClient, isServer) + , m_Renderer(renderer) + , m_RenderFrame(renderFrame) +{ + // Create Octrees + // TODO: Perhaps the world bounds should be set in some non-arbitrary way instead of this. + AABB boxContainingTheWorld(glm::vec3(-300), glm::vec3(300)); + m_OctreeCollision = new Octree(boxContainingTheWorld, 4); + m_OctreeTrigger = new Octree(boxContainingTheWorld, 4); + m_OctreeFrustrumCulling = new Octree(boxContainingTheWorld, 4); + + // All systems with orderlevel 0 will be updated first. + unsigned int updateOrderLevel = 0; + AddSystem(updateOrderLevel); + ++updateOrderLevel; + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel, m_Renderer, m_OctreeCollision); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel, m_Renderer); + AddSystem(updateOrderLevel, m_Renderer); + // Populate Octree with collidables + ++updateOrderLevel; + AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); + AddSystem(updateOrderLevel, m_OctreeTrigger, "Player"); + AddSystem(updateOrderLevel, m_OctreeFrustrumCulling); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel); + // Collision and TriggerSystem should update after player. + ++updateOrderLevel; + AddSystem(updateOrderLevel); + AddSystem(updateOrderLevel, m_OctreeCollision); + AddSystem(updateOrderLevel, m_OctreeTrigger); + ++updateOrderLevel; + AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame, m_OctreeFrustrumCulling); + ++updateOrderLevel; + AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame); +} + +CapturePointsEntitySystem::~CapturePointsEntitySystem() +{ + if (m_OctreeFrustrumCulling != nullptr) { + delete m_OctreeFrustrumCulling; + } + if (m_OctreeCollision != nullptr) { + delete m_OctreeCollision; + } + if (m_OctreeTrigger != nullptr) { + delete m_OctreeTrigger; + } +} diff --git a/src/Game/Game.cpp b/src/Game/Game.cpp index 24b7cd1e..421094dd 100644 --- a/src/Game/Game.cpp +++ b/src/Game/Game.cpp @@ -1,34 +1,8 @@ #include "Game.h" -#include "Collision/FillOctreeSystem.h" -#include "Collision/FillFrustumOctreeSystem.h" -#include "Collision/EntityAABB.h" -#include "Collision/TriggerSystem.h" -#include "Collision/CollisionSystem.h" -#include "Systems/RaptorCopterSystem.h" -#include "Systems/HealthSystem.h" -#include "Systems/PlayerMovementSystem.h" -#include "Systems/SpawnerSystem.h" -#include "Systems/PlayerSpawnSystem.h" -#include "Systems/PlayerDeathSystem.h" #include "Core/EntityFileWriter.h" -#include "Game/Systems/CapturePointSystem.h" -#include "Game/Systems/CapturePointHUDSystem.h" -#include "Game/Systems/PickupSpawnSystem.h" -#include "Game/Systems/AmmoPickupSystem.h" -#include "Game/Systems/DamageIndicatorSystem.h" -#include "Game/Systems/Weapon/WeaponSystem.h" -#include "Rendering/AnimationSystem.h" -#include "Game/Systems/HealthHUDSystem.h" -#include "Rendering/BoneAttachmentSystem.h" -#include "Game/Systems/LifetimeSystem.h" -#include "../Engine/Core/UniformScaleSystem.h" -#include "Rendering/AnimationSystem.h" #include "Network/MultiplayerSnapshotFilter.h" -#include "Game/Systems/AmmunitionHUDSystem.h" -#include "Game/Systems/KillFeedSystem.h" -#include "GUI/ButtonSystem.h" -#include "GUI/MainMenuSystem.h" - +#include "Systems/PlayerSpawnSystem.h" +#include "CapturePointsEntitySystem.h" Game::Game(int argc, char* argv[]) { @@ -48,6 +22,7 @@ Game::Game(int argc, char* argv[]) ResourceManager::UseThreading = m_Config->Get("Multithreading.ResourceLoading", true); DisableMemoryPool::Value = m_Config->Get("Debug.DisableMemoryPool", false); LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get("Debug.LogLevel", 1)); + // HACK: This shouldn't be a config variable PlayerSpawnSystem::SetRespawnTime(m_Config->Get("Debug.RespawnTime", 15.0f)); // Create the core event broker @@ -74,91 +49,30 @@ Game::Game(int argc, char* argv[]) m_InputProxy->AddHandler(); m_InputProxy->LoadBindings("Input.ini"); - // Create a world - m_World = new World(m_EventBroker); - std::string mapToLoad = m_Config->Get("Debug.LoadMap", ""); - if (!mapToLoad.empty()) { - auto file = ResourceManager::Load(mapToLoad); - EntityFilePreprocessor fpp(file); - fpp.RegisterComponents(m_World); - EntityFileParser fp(file); - fp.MergeEntities(m_World); - } - // Create the sound manager - m_SoundManager = new SoundManager(m_World, m_EventBroker); + //m_SoundManager = new SoundManager(m_World, m_EventBroker); + + // Create an entity system + m_EntitySystem = new CapturePointsEntitySystem(m_EventBroker, m_IsClient, m_IsServer, m_Renderer, m_RenderFrame); // Initialize network if (m_Config->Get("Networking.StartNetwork", false)) { if (m_IsServer) { - m_NetworkServer = new Server(m_World, m_EventBroker, m_NetworkPort); + m_NetworkServer = new Server(m_EntitySystem, m_EventBroker, m_NetworkPort); m_Renderer->SetWindowTitle(m_Renderer->WindowTitle() + " SERVER"); } else if (m_IsClient) { - m_NetworkClient = new Client(m_World, m_EventBroker, std::make_unique(m_EventBroker)); + m_NetworkClient = new Client(m_EntitySystem, m_EventBroker, std::make_unique(m_EventBroker)); m_NetworkClient->Connect(m_NetworkAddress, m_NetworkPort); m_Renderer->SetWindowTitle(m_Renderer->WindowTitle() + " CLIENT"); } } - // Create Octrees - // TODO: Perhaps the world bounds should be set in some non-arbitrary way instead of this. - AABB boxContainingTheWorld(glm::vec3(-300), glm::vec3(300)); - m_OctreeCollision = new Octree(boxContainingTheWorld, 4); - m_OctreeTrigger = new Octree(boxContainingTheWorld, 4); - m_OctreeFrustrumCulling = new Octree(boxContainingTheWorld, 4); - // Create system pipeline - m_SystemPipeline = new SystemPipeline(m_World, m_EventBroker, m_IsClient, m_IsServer); - - // All systems with orderlevel 0 will be updated first. - unsigned int updateOrderLevel = 0; - m_SystemPipeline->AddSystem(updateOrderLevel); - ++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_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_OctreeCollision); - 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_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); - m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer); - // Populate Octree with collidables - ++updateOrderLevel; - m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision, "Collidable"); - m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger, "Player"); - m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeFrustrumCulling); - m_SystemPipeline->AddSystem(updateOrderLevel); - m_SystemPipeline->AddSystem(updateOrderLevel); - m_SystemPipeline->AddSystem(updateOrderLevel); - m_SystemPipeline->AddSystem(updateOrderLevel); - // Collision and TriggerSystem should update after player. - ++updateOrderLevel; - m_SystemPipeline->AddSystem(updateOrderLevel); - m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeCollision); - m_SystemPipeline->AddSystem(updateOrderLevel, m_OctreeTrigger); - ++updateOrderLevel; - m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame, m_OctreeFrustrumCulling); - ++updateOrderLevel; - m_SystemPipeline->AddSystem(updateOrderLevel, m_Renderer, m_RenderFrame); - m_LastTime = glfwGetTime(); } Game::~Game() { - delete m_SystemPipeline; - delete m_OctreeFrustrumCulling; - delete m_OctreeCollision; - delete m_OctreeTrigger; + delete m_EntitySystem; delete m_SoundManager; if (m_NetworkClient != nullptr) { delete m_NetworkClient; @@ -166,7 +80,6 @@ Game::~Game() if (m_NetworkServer != nullptr) { delete m_NetworkServer; } - delete m_World; delete m_InputProxy; delete m_InputManager; delete m_RenderFrame; @@ -195,7 +108,7 @@ void Game::Tick() m_EventBroker->Swap(); PerformanceTimer::StartTimerAndStopPrevious("SoundManager"); - m_SoundManager->Update(dt); + //m_SoundManager->Update(dt); // Update network PerformanceTimer::StartTimerAndStopPrevious("Network"); @@ -209,9 +122,9 @@ void Game::Tick() //m_SoundManager->Update(dt); // Iterate through systems and update world! - PerformanceTimer::StartTimerAndStopPrevious("SystemPipeline"); + PerformanceTimer::StartTimerAndStopPrevious("EntitySystem"); m_EventBroker->Process(); - m_SystemPipeline->Update(dt); + m_EntitySystem->Update(dt); PerformanceTimer::StartTimerAndStopPrevious("RendererUpdate"); m_Renderer->Update(dt); PerformanceTimer::StartTimerAndStopPrevious("RendererDraw"); diff --git a/src/Game/MainMenuEntitySystem.cpp b/src/Game/MainMenuEntitySystem.cpp new file mode 100644 index 00000000..e69de29b diff --git a/src/Game/Systems/CapturePointSystem.cpp b/src/Game/Systems/CapturePointSystem.cpp index 5fdd74cd..2e574026 100644 --- a/src/Game/Systems/CapturePointSystem.cpp +++ b/src/Game/Systems/CapturePointSystem.cpp @@ -192,27 +192,6 @@ void CapturePointSystem::UpdateComponent(EntityWrapper& capturePointEntity, Comp //NextPossibleCapturePoint will be calculated in the next update... } } - - //check for possible winCondition = check if the homebase is owned by the other team - bool checkForWinner = false; - if (capturePointNumber == m_RedTeamHomeCapturePoint && ownedBy != redTeam) - { - checkForWinner = true; - } - if (capturePointNumber == m_BlueTeamHomeCapturePoint && ownedBy != blueTeam) - { - checkForWinner = true; - } - - if (checkForWinner && !m_WinnerWasFound) - { - //publish Win event - Events::Win e; - e.TeamThatWon = ownedBy; - m_EventBroker->Publish(e); - m_WinnerWasFound = true; - } - } bool CapturePointSystem::OnTriggerTouch(const Events::TriggerTouch& e) diff --git a/src/Game/Systems/CapturePointsGamemode.cpp b/src/Game/Systems/CapturePointsGamemode.cpp new file mode 100644 index 00000000..06283a80 --- /dev/null +++ b/src/Game/Systems/CapturePointsGamemode.cpp @@ -0,0 +1,117 @@ +#include "Systems/CapturePointsGamemode.h" + +CapturePointsGamemode::CapturePointsGamemode(SystemParams params) + : System(params) +{ + EVENT_SUBSCRIBE_MEMBER(m_ECaptured, &CapturePointsGamemode::OnCaptured); + EVENT_SUBSCRIBE_MEMBER(m_EGameStart, &CapturePointsGamemode::OnGameStart); +} + +void CapturePointsGamemode::Update(double dt) +{ + if (!m_GameRuning) { + return; + } + + auto cGamemode = currentGamemode(); + if (!cGamemode) { + setRunning(false); + return; + } + + m_GameTime += dt; + (double&)(*cGamemode)["RoundTime"] = m_GameTime; +} + +bool CapturePointsGamemode::OnGameStart(const Events::GameStart& e) +{ + if (!isCurrentGamemode()) { + return false; + } + + setRunning(true); + + return true; +} + +bool CapturePointsGamemode::OnCaptured(const Events::Captured& e) +{ + if (!m_GameRuning) { + return false; + } + + auto cGamemode = currentGamemode(); + if (!cGamemode) { + return false; + } + + auto winningTeam = winCondition(); + if (winningTeam) { + setRunning(false); + + Events::Win e; + e.Team = *winningTeam; + m_EventBroker->Publish(e); + } + + return true; +} + +boost::optional CapturePointsGamemode::currentGamemode() +{ + auto cGamemodes = m_World->GetComponents("Gamemode"); + if (cGamemodes->begin() == cGamemodes->end()) { + return boost::none; + } + return *cGamemodes->begin(); +} + +bool CapturePointsGamemode::isCurrentGamemode() +{ + auto cGamemode = currentGamemode(); + if (!cGamemode) { + return false; + } + + // Check that we're the current gamemode + if ((ComponentInfo::EnumType)(*cGamemode)["Gamemode"] == (*cGamemode)["Gamemode"].Enum("CapturePoints")) { + return true; + } else { + return false; + } +} + +boost::optional CapturePointsGamemode::winCondition() +{ + auto cCapturePoints = m_World->GetComponents("CapturePoint"); + + // If all capture points are owned by the same team, they won + ComponentInfo::EnumType winningTeam = -1; + for (auto& c : *cCapturePoints) { + EntityWrapper e(m_World, c.EntityID); + ComponentInfo::EnumType team = e["Team"]["Team"]; + if (winningTeam != -1 && winningTeam != team) { + return boost::none; + } else { + winningTeam = team; + } + } + + return winningTeam; +} + +void CapturePointsGamemode::setRunning(bool running) +{ + m_GameRuning = running; + if (running) { + m_GameTime = 0.0; + } + + auto cGamemode = currentGamemode(); + if (cGamemode) { + m_GameRuning = running; + if (running) { + (*cGamemode)["RoundTime"] = 0.0; + } + } +}