Working Spawner, SpawnPoint, PlayerSpawn and Team components, along with their systems.

This commit is contained in:
2016-01-17 01:00:48 +01:00
parent 6385a98eca
commit f281d220de
13 changed files with 93 additions and 50 deletions
+2
View File
@@ -20,6 +20,8 @@ struct EntityWrapper
::World* World; ::World* World;
EntityID ID; EntityID ID;
static const EntityWrapper Invalid;
bool HasComponent(const std::string& componentName); bool HasComponent(const std::string& componentName);
ComponentWrapper operator[](const std::string& componentName); ComponentWrapper operator[](const std::string& componentName);
+1
View File
@@ -1,5 +1,6 @@
#include "Core/System.h" #include "Core/System.h"
#include "Input/EInputCommand.h" #include "Input/EInputCommand.h"
#include "Systems/SpawnerSystem.h"
#include "Events/ESpawnerSpawn.h" #include "Events/ESpawnerSpawn.h"
class PlayerSpawnSystem : public ImpureSystem class PlayerSpawnSystem : public ImpureSystem
+7 -2
View File
@@ -1,3 +1,6 @@
#ifndef SpawnerSystem_h__
#define SpawnerSystem_h__
#include <random> #include <random>
#include "Common.h" #include "Common.h"
#include "GLM.h" #include "GLM.h"
@@ -12,9 +15,11 @@ class SpawnerSystem : public System
public: public:
SpawnerSystem(EventBroker* eventBroker); SpawnerSystem(EventBroker* eventBroker);
static EntityWrapper Spawn(EntityWrapper spawner, EntityWrapper parent = EntityWrapper::Invalid);
private: private:
EventRelay<SpawnerSystem, Events::SpawnerSpawn> m_OnSpawnerSpawn; EventRelay<SpawnerSystem, Events::SpawnerSpawn> m_OnSpawnerSpawn;
bool OnSpawnerSpawn(Events::SpawnerSpawn& e); bool OnSpawnerSpawn(Events::SpawnerSpawn& e);
};
void spawnEntity(EntityWrapper spawner, EntityID parent, glm::vec3 position); #endif
};
-1
View File
@@ -4,7 +4,6 @@
<xs:include schemaLocation="Components/Transform.xsd"/> <xs:include schemaLocation="Components/Transform.xsd"/>
<xs:include schemaLocation="Components/Physics.xsd"/> <xs:include schemaLocation="Components/Physics.xsd"/>
<xs:include schemaLocation="Components/Model.xsd"/> <xs:include schemaLocation="Components/Model.xsd"/>
<xs:include schemaLocation="Components/Test.xsd"/>
<xs:include schemaLocation="Components/RaptorCopter.xsd"/> <xs:include schemaLocation="Components/RaptorCopter.xsd"/>
<xs:include schemaLocation="Components/Player.xsd"/> <xs:include schemaLocation="Components/Player.xsd"/>
<xs:include schemaLocation="Components/Camera.xsd"/> <xs:include schemaLocation="Components/Camera.xsd"/>
+1 -3
View File
@@ -1,4 +1,2 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<PlayerSpawn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PlayerSpawn.xsd"> <PlayerSpawn xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PlayerSpawn.xsd"/>
<TeamID>1</TeamID>
</PlayerSpawn>
+1 -8
View File
@@ -5,14 +5,7 @@
<xs:element name="PlayerSpawn"> <xs:element name="PlayerSpawn">
<xs:annotation> <xs:annotation>
<xs:documentation>Combined with a Spawner, defines a spawn point for a player team.</xs:documentation> <xs:documentation>Combined with a Spawner and a Team component, defines a spawn point for a player team.</xs:documentation>
</xs:annotation> </xs:annotation>
<xs:complexType>
<xs:all>
<xs:element name="TeamID" type="t:int" minOccurs="0">
<xs:annotation><xs:documentation>1 = Spectator, 2 = Red, 3 = Blue</xs:documentation></xs:annotation>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element> </xs:element>
</xs:schema> </xs:schema>
+7 -2
View File
@@ -8,9 +8,13 @@
<Children> <Children>
<Entity> <Entity>
<Components> <Components>
<c:PlayerSpawn/>
<c:Spawner> <c:Spawner>
<EntityFile>Schema/Entities/Player.xml</EntityFile> <EntityFile>Schema/Entities/Player.xml</EntityFile>
</c:Spawner> </c:Spawner>
<c:Team>
<Team>2</Team>
</c:Team>
<c:Transform> <c:Transform>
<Position X="11.2723322" Y="1.28011799" Z="3.66820574"/> <Position X="11.2723322" Y="1.28011799" Z="3.66820574"/>
</c:Transform> </c:Transform>
@@ -47,9 +51,10 @@
<Entity> <Entity>
<Components> <Components>
<c:Camera/> <c:Camera/>
<c:Listener/>
<c:Transform> <c:Transform>
<Position X="-9.75645447" Y="12.7158976" Z="7.92630243"/> <Position X="-0.123331964" Y="7.64918661" Z="6.59480286"/>
<Orientation X="-0.757485211" Y="-1.44177103" Z="7.17310422e-06"/> <Orientation X="-0.500915647" Y="-1.35800648" Z="-7.76194497e-07"/>
</c:Transform> </c:Transform>
</Components> </Components>
<Children/> <Children/>
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<Entity xmlns:c="components" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Types/Entity.xsd">
<Components>
<c:Team>
<Team>3</Team>
</c:Team>
<c:Transform/>
</Components>
<Children/>
</Entity>
-1
View File
@@ -13,7 +13,6 @@
<xs:element ref="c:Transform" minOccurs="0"/> <xs:element ref="c:Transform" minOccurs="0"/>
<xs:element ref="c:Physics" minOccurs="0"/> <xs:element ref="c:Physics" minOccurs="0"/>
<xs:element ref="c:Model" minOccurs="0"/> <xs:element ref="c:Model" minOccurs="0"/>
<xs:element ref="c:Test" minOccurs="0"/>
<xs:element ref="c:RaptorCopter" minOccurs="0"/> <xs:element ref="c:RaptorCopter" minOccurs="0"/>
<xs:element ref="c:Player" minOccurs="0"/> <xs:element ref="c:Player" minOccurs="0"/>
<xs:element ref="c:Camera" minOccurs="0"/> <xs:element ref="c:Camera" minOccurs="0"/>
+2
View File
@@ -1,6 +1,8 @@
#include "Core/EntityWrapper.h" #include "Core/EntityWrapper.h"
#include "Core/World.h" #include "Core/World.h"
const EntityWrapper EntityWrapper::Invalid = EntityWrapper(nullptr, EntityID_Invalid);
bool EntityWrapper::operator==(const EntityWrapper& e) bool EntityWrapper::operator==(const EntityWrapper& e)
{ {
return (this->World == e.World) && (this->ID == e.ID); return (this->World == e.World) && (this->ID == e.ID);
+2 -2
View File
@@ -63,7 +63,7 @@ void InputProxy::Process()
e.Command = command; e.Command = command;
e.Value = currentValue; e.Value = currentValue;
m_EventBroker->Publish(e); 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; m_LastCommandValues[command] = currentValue;
} }
} }
@@ -79,7 +79,7 @@ void InputProxy::Process()
} }
//e.Value = std::max(-1.f, std::min(e.Value, 1.f)); //e.Value = std::max(-1.f, std::min(e.Value, 1.f));
m_EventBroker->Publish(e); 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(); m_CommandQueue.clear();
} }
+20 -8
View File
@@ -8,17 +8,29 @@ PlayerSpawnSystem::PlayerSpawnSystem(EventBroker* eventBroker)
void PlayerSpawnSystem::Update(World* world, double dt) void PlayerSpawnSystem::Update(World* world, double dt)
{ {
auto componentPools = world->GetComponentPools(); auto playerSpawns = world->GetComponents("PlayerSpawn");
auto spawnerPool = componentPools.find("Spawner"); if (playerSpawns == nullptr) {
if (spawnerPool == componentPools.end()) {
return; return;
} }
;
for (auto& team : m_SpawnRequests) { for (auto& team : m_SpawnRequests) {
for (auto& spawner : *spawnerPool->second) { for (auto& cPlayerSpawn : *playerSpawns) {
Events::SpawnerSpawn e; EntityWrapper spawner(world, cPlayerSpawn.EntityID);
e.Spawner = EntityWrapper(world, spawner.EntityID); if (!spawner.HasComponent("Spawner")) {
m_EventBroker->Publish(e); 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(); m_SpawnRequests.clear();
+37 -23
View File
@@ -5,43 +5,57 @@ SpawnerSystem::SpawnerSystem(EventBroker* eventBroker) : System(eventBroker)
EVENT_SUBSCRIBE_MEMBER(m_OnSpawnerSpawn, &SpawnerSystem::OnSpawnerSpawn); 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); auto children = spawner.World->GetChildren(spawner.ID);
std::vector<EntityID> spawnPoints; std::vector<EntityWrapper> spawnPoints;
for (auto kv = children.first; kv != children.second; ++kv) { for (auto kv = children.first; kv != children.second; ++kv) {
const EntityID& child = kv->second; const EntityID& child = kv->second;
if (spawner.World->HasComponent(child, "SpawnPoint")) { 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()) { if (!spawnPoints.empty()) {
// Select a random spawn point if (spawnPoints.size() > 1) {
static std::random_device randomDevice; static std::random_device randomDevice;
static std::mt19937 randomGenerator(randomDevice()); static std::mt19937 randomGenerator(randomDevice());
std::uniform_int_distribution<> distribution(0, std::distance(spawnPoints.begin(), spawnPoints.end()) - 1); std::uniform_int_distribution<> distribution(0, std::distance(spawnPoints.begin(), spawnPoints.end()) - 1);
auto randomSpawnPointIt = spawnPoints.begin(); auto randomSpawnPointIt = spawnPoints.begin();
std::advance(randomSpawnPointIt, distribution(randomGenerator)); std::advance(randomSpawnPointIt, distribution(randomGenerator));
spawnPoint = *randomSpawnPointIt; spawnPoint = *randomSpawnPointIt;
} else {
spawnPoint = spawnPoints.front();
}
} }
spawnEntity(spawner, e.Parent.ID, Transform::AbsolutePosition(spawner.World, spawnPoint));
// Load the entity file and parse it
return true;
}
void SpawnerSystem::spawnEntity(EntityWrapper spawner, EntityID parent, glm::vec3 position)
{
const std::string& entityFilePath = spawner["Spawner"]["EntityFile"]; const std::string& entityFilePath = spawner["Spawner"]["EntityFile"];
auto entityFile = ResourceManager::Load<EntityFile>(entityFilePath); auto entityFile = ResourceManager::Load<EntityFile>(entityFilePath);
if (entityFile == nullptr) { if (entityFile == nullptr) {
return; return EntityWrapper::Invalid;
} }
EntityFileParser parser(entityFile); EntityFileParser parser(entityFile);
EntityWrapper spawnedEntity(spawner.World, parser.MergeEntities(spawner.World, parent)); EntityWrapper spawnedEntity(world, parser.MergeEntities(world, parent.ID));
spawnedEntity["Transform"]["Position"] = position;
// 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;
} }