WIP respawning.

This commit is contained in:
William Moberg
2016-02-11 16:08:19 +01:00
parent c3cc5ae70b
commit 8eea0c8395
7 changed files with 101 additions and 128 deletions
+12 -1
View File
@@ -13,6 +13,8 @@ public:
PlayerSpawnSystem(World* world, EventBroker* eventBroker);
virtual void Update(double dt) override;
static void SetRespawnTime(float respawnTime) { m_RespawnTime = respawnTime; };
private:
struct SpawnRequest
@@ -23,10 +25,19 @@ private:
bool m_NetworkEnabled = false;
std::vector<SpawnRequest> m_SpawnRequests;
//Player ID -> EntityWrapper.
std::map<int, EntityWrapper> m_PlayerEntities;
//EntityWrapper ID -> Player ID.
std::map<EntityID, int> m_PlayerIDs;
static float m_RespawnTime;
float m_Timer;
EventRelay<PlayerSpawnSystem, Events::InputCommand> m_OnInputCommand;
bool OnInputCommand(const Events::InputCommand& e);
bool OnInputCommand(Events::InputCommand& e);
EventRelay<PlayerSpawnSystem, Events::PlayerSpawned> m_OnPlayerSpawnerd;
bool OnPlayerSpawned(Events::PlayerSpawned& e);
EventRelay<PlayerSpawnSystem, Events::PlayerDeath> m_OnPlayerDeath;
bool OnPlayerDeath(Events::PlayerDeath& e);
};
+1
View File
@@ -4,6 +4,7 @@ LoadMap=
; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation.
; if false -> Use pool allocation.
DisableMemoryPool=false
RespawnTime = 8.0
[Editor]
CameraSpeed=3
-117
View File
@@ -120,123 +120,6 @@
</Entity>
</Children>
</Entity>
<Entity name="Player">
<Components>
<c:AABB>
<Origin X="0" Y="0.772000015" Z="0"/>
<Size X="1" Y="1.60000002" Z="1"/>
</c:AABB>
<c:Collidable/>
<c:Model/>
<c:Physics>
<Gravity>false</Gravity>
</c:Physics>
<c:Player>
<MovementSpeed>5</MovementSpeed>
</c:Player>
<c:Team>
<Team>
<Red/>
</Team>
</c:Team>
<c:Transform>
<Position X="-1.68112314" Y="0.0288829971" Z="3.06287026"/>
<Orientation X="0" Y="2.14675093" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity name="Camera">
<Components>
<c:Camera/>
<c:Transform>
<Position X="0" Y="1.37700009" Z="0"/>
</c:Transform>
</Components>
<Children>
<Entity name="PlayerName">
<Components>
<c:Text>
<Resource>Fonts/DroidSans.ttf,100</Resource>
<Color A="1" B="0" G="1" R="0"/>
<Visible>false</Visible>
</c:Text>
<c:Transform>
<Position X="0" Y="0.247910097" Z="-0.447844714"/>
<Scale X="0.100000001" Y="0.113000005" Z="0.5"/>
<Orientation X="0" Y="3.14199996" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="CameraModel">
<Components>
<c:Model>
<Resource>Models/Widgets/Camera.mesh</Resource>
</c:Model>
<c:Transform>
<Position X="0" Y="0.0331346765" Z="-0.0792061687"/>
<Scale X="1.30000007" Y="1.50000012" Z="1"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
<Entity name="ThirdPersonCamera">
<Components>
<c:Camera/>
<c:Model>
<Resource>Models/Widgets/Camera.mesh</Resource>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="-0.284000009" Y="1.83800006" Z="1.18900001"/>
<Orientation X="5.95600033" Y="0" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="PlayerModel">
<Components>
<c:Model>
<Resource>Models/Characters/Assault/AssaultHeadless.mesh</Resource>
<Color A="1" B="0" G="0" R="1"/>
</c:Model>
<c:Transform>
<Orientation X="0" Y="3.14159274" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="AABBStanding">
<Components>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="0.427450985" B="1" G="1" R="1"/>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="0" Y="0.772000015" Z="0"/>
<Scale X="1" Y="1.60000002" Z="1"/>
</c:Transform>
</Components>
<Children/>
</Entity>
<Entity name="AABBCrouching">
<Components>
<c:Model>
<Resource>Models/Core/UnitCube.mesh</Resource>
<Color A="0.745098054" B="1" G="0" R="1"/>
<Visible>false</Visible>
</c:Model>
<c:Transform>
<Position X="0" Y="0.772000015" Z="0"/>
</c:Transform>
</Components>
<Children/>
</Entity>
</Children>
</Entity>
</Children>
</Entity>
+2 -1
View File
@@ -34,6 +34,7 @@ Game::Game(int argc, char* argv[])
ResourceManager::UseThreading = m_Config->Get<bool>("Multithreading.ResourceLoading", true);
DisableMemoryPool::Value = m_Config->Get<bool>("Debug.DisableMemoryPool", false);
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
PlayerSpawnSystem::SetRespawnTime(m_Config->Get<float>("Debug.RespawnTime", 15.0f));
// Create the core event broker
m_EventBroker = new EventBroker();
@@ -97,7 +98,6 @@ Game::Game(int argc, char* argv[])
m_SystemPipeline->AddSystem<InterpolationSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<PlayerSpawnSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<PlayerDeathSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<WeaponSystem>(updateOrderLevel, m_Renderer);
m_SystemPipeline->AddSystem<LifetimeSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<CapturePointSystem>(updateOrderLevel);
@@ -109,6 +109,7 @@ Game::Game(int argc, char* argv[])
m_SystemPipeline->AddSystem<FillFrustumOctreeSystem>(updateOrderLevel, m_OctreeFrustrumCulling);
m_SystemPipeline->AddSystem<PlayerHUD>(updateOrderLevel);
m_SystemPipeline->AddSystem<AnimationSystem>(updateOrderLevel);
m_SystemPipeline->AddSystem<PlayerDeathSystem>(updateOrderLevel);
// Collision and TriggerSystem should update after player.
++updateOrderLevel;
+12 -3
View File
@@ -34,14 +34,23 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
//components that we need from player
auto playerCamera = player.FirstChildByName("Camera");
auto playerEntityModel = player.FirstChildByName("PlayerModel")["Model"];
auto playerEntityAnimation = player.FirstChildByName("PlayerModel")["Animation"];
auto playerModel = player.FirstChildByName("PlayerModel");
if (!playerCamera.Valid() || !playerModel.Valid()) {
return;
}
if (!playerModel.HasComponent("Model") || !playerModel.HasComponent("Animation")) {
return;
}
auto playerEntityModel = playerModel["Model"];
auto playerEntityAnimation = playerModel["Animation"];
//copy the data from player to explisioneffectmodel
playerEntityModel.Copy(deathEffectEW["Model"]);
playerEntityAnimation.Copy(deathEffectEW["Animation"]);
//freeze the animation
deathEffectEW["Animation"]["Speed"] = 0.0;
deathEffectEW["Animation"]["Speed1"] = 0.0;
deathEffectEW["Animation"]["Speed2"] = 0.0;
deathEffectEW["Animation"]["Speed3"] = 0.0;
//copy the models position,orientation
deathEffectEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"];
+72 -4
View File
@@ -1,20 +1,39 @@
#include "Systems/PlayerSpawnSystem.h"
//This should be set by the config anyway.
float PlayerSpawnSystem::m_RespawnTime = 15.0f;
PlayerSpawnSystem::PlayerSpawnSystem(World* m_World, EventBroker* eventBroker)
: System(m_World, eventBroker)
, m_Timer(0.f)
{
EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerSpawnSystem::OnInputCommand);
EVENT_SUBSCRIBE_MEMBER(m_OnPlayerSpawnerd, &PlayerSpawnSystem::OnPlayerSpawned);
EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerSpawnSystem::OnPlayerDeath);
m_NetworkEnabled = ResourceManager::Load<ConfigFile>("Config.ini")->Get("Networking.StartNetwork", false);
}
void PlayerSpawnSystem::Update(double dt)
{
//Increase timer.
m_Timer += dt;
if (m_Timer < m_RespawnTime) {
return;
}
//If respawn time has passed, we spawn all players that have requested to be spawned.
m_Timer = 0.f;
//If there are no spawn requests, return immediately, if we are client the SpawnRequests should always be empty.
if (m_SpawnRequests.size() == 0) {
return;
}
auto playerSpawns = m_World->GetComponents("PlayerSpawn");
if (playerSpawns == nullptr) {
return;
}
int numSpawnedPlayers = 0;
for (auto& req : m_SpawnRequests) {
for (auto& cPlayerSpawn : *playerSpawns) {
EntityWrapper spawner(m_World, cPlayerSpawn.EntityID);
@@ -40,13 +59,19 @@ void PlayerSpawnSystem::Update(double dt)
e.Player = player;
e.Spawner = spawner;
m_EventBroker->Publish(e);
++numSpawnedPlayers;
break;
}
}
if (numSpawnedPlayers != (int)m_SpawnRequests.size()) {
LOG_DEBUG("%i players were supposed to be spawned, but %i was spawned.", (int)m_SpawnRequests.size(), numSpawnedPlayers);
} else {
LOG_DEBUG("%i players were spawned.", numSpawnedPlayers);
}
m_SpawnRequests.clear();
}
bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e)
bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
{
if (e.Command != "PickTeam") {
return false;
@@ -58,11 +83,37 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e)
return false;
}
if (e.Value != 0) {
if (e.Value == 0) {
return false;
}
//TODO: Spectating?
if (e.Player.Valid() && e.Player.HasComponent("Team")) {
ComponentWrapper cTeam = e.Player["Team"];
if ((ComponentInfo::EnumType)e.Value == cTeam["Team"].Enum("Spectator")) {
return false;
}
}
auto iter = m_SpawnRequests.begin();
for (; iter != m_SpawnRequests.end(); ++iter) {
if (iter->PlayerID == e.PlayerID) {
break;
}
}
if (iter != m_SpawnRequests.end()) {
//If player is in queue to spawn, then change their team affiliation.
iter->Team = (ComponentInfo::EnumType)e.Value;
} else if (m_PlayerEntities.count(e.PlayerID) == 0 || !m_PlayerEntities[e.PlayerID].Valid()) {
//If player is not in queue to spawn, then create a spawn request,
//but only if they are spectating and/or just connected.
SpawnRequest req;
req.PlayerID = e.PlayerID;
req.Team = (ComponentInfo::EnumType)e.Value;
m_SpawnRequests.push_back(req);
} else {
return false;
}
return true;
@@ -82,6 +133,7 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
// Store the player for future reference
m_PlayerEntities[e.PlayerID] = e.Player;
m_PlayerIDs[e.Player.ID] = e.PlayerID;
// Set the camera to the correct entity
EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera");
@@ -110,4 +162,20 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
}
return true;
}
}
bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e)
{
if (!e.Player.HasComponent("Team")) {
return false;
}
ComponentWrapper cTeam = e.Player["Team"];
//A spectator can't die anyway
if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Spectator")) {
return false;
}
SpawnRequest req;
req.PlayerID = m_PlayerIDs[e.Player.ID];
req.Team = cTeam["Team"];
m_SpawnRequests.push_back(req);
}
+2 -2
View File
@@ -57,10 +57,10 @@ bool SoundSystem::OnInputCommand(const Events::InputCommand & e)
return true;
}
}
if (e.Command == "TakeDamage" && e.Value > 0) {
if (e.Command == "TakeDamage" && e.Value > 0 && m_LocalPlayer.Valid()) {
Events::PlayerDamage ev;
ev.Player = m_LocalPlayer;
ev.Damage = 1.0;
ev.Damage = e.Value;
m_EventBroker->Publish(ev);
}