WIP respawning.
This commit is contained in:
@@ -13,6 +13,8 @@ public:
|
|||||||
PlayerSpawnSystem(World* world, EventBroker* eventBroker);
|
PlayerSpawnSystem(World* world, EventBroker* eventBroker);
|
||||||
|
|
||||||
virtual void Update(double dt) override;
|
virtual void Update(double dt) override;
|
||||||
|
|
||||||
|
static void SetRespawnTime(float respawnTime) { m_RespawnTime = respawnTime; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct SpawnRequest
|
struct SpawnRequest
|
||||||
@@ -23,10 +25,19 @@ private:
|
|||||||
|
|
||||||
bool m_NetworkEnabled = false;
|
bool m_NetworkEnabled = false;
|
||||||
std::vector<SpawnRequest> m_SpawnRequests;
|
std::vector<SpawnRequest> m_SpawnRequests;
|
||||||
|
|
||||||
|
//Player ID -> EntityWrapper.
|
||||||
std::map<int, EntityWrapper> m_PlayerEntities;
|
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;
|
EventRelay<PlayerSpawnSystem, Events::InputCommand> m_OnInputCommand;
|
||||||
bool OnInputCommand(const Events::InputCommand& e);
|
bool OnInputCommand(Events::InputCommand& e);
|
||||||
EventRelay<PlayerSpawnSystem, Events::PlayerSpawned> m_OnPlayerSpawnerd;
|
EventRelay<PlayerSpawnSystem, Events::PlayerSpawned> m_OnPlayerSpawnerd;
|
||||||
bool OnPlayerSpawned(Events::PlayerSpawned& e);
|
bool OnPlayerSpawned(Events::PlayerSpawned& e);
|
||||||
|
EventRelay<PlayerSpawnSystem, Events::PlayerDeath> m_OnPlayerDeath;
|
||||||
|
bool OnPlayerDeath(Events::PlayerDeath& e);
|
||||||
};
|
};
|
||||||
@@ -4,6 +4,7 @@ LoadMap=
|
|||||||
; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation.
|
; if true -> Pool allocation is not used when calling Allocate/Free, just use regular dynamic allocation.
|
||||||
; if false -> Use pool allocation.
|
; if false -> Use pool allocation.
|
||||||
DisableMemoryPool=false
|
DisableMemoryPool=false
|
||||||
|
RespawnTime = 8.0
|
||||||
|
|
||||||
[Editor]
|
[Editor]
|
||||||
CameraSpeed=3
|
CameraSpeed=3
|
||||||
|
|||||||
@@ -120,123 +120,6 @@
|
|||||||
</Entity>
|
</Entity>
|
||||||
</Children>
|
</Children>
|
||||||
</Entity>
|
</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>
|
</Children>
|
||||||
|
|
||||||
</Entity>
|
</Entity>
|
||||||
|
|||||||
+2
-1
@@ -34,6 +34,7 @@ Game::Game(int argc, char* argv[])
|
|||||||
ResourceManager::UseThreading = m_Config->Get<bool>("Multithreading.ResourceLoading", true);
|
ResourceManager::UseThreading = m_Config->Get<bool>("Multithreading.ResourceLoading", true);
|
||||||
DisableMemoryPool::Value = m_Config->Get<bool>("Debug.DisableMemoryPool", false);
|
DisableMemoryPool::Value = m_Config->Get<bool>("Debug.DisableMemoryPool", false);
|
||||||
LOG_LEVEL = static_cast<_LOG_LEVEL>(m_Config->Get<int>("Debug.LogLevel", 1));
|
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
|
// Create the core event broker
|
||||||
m_EventBroker = new EventBroker();
|
m_EventBroker = new EventBroker();
|
||||||
@@ -97,7 +98,6 @@ Game::Game(int argc, char* argv[])
|
|||||||
m_SystemPipeline->AddSystem<InterpolationSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<InterpolationSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<SpawnerSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<PlayerSpawnSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<PlayerSpawnSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<PlayerDeathSystem>(updateOrderLevel);
|
|
||||||
m_SystemPipeline->AddSystem<WeaponSystem>(updateOrderLevel, m_Renderer);
|
m_SystemPipeline->AddSystem<WeaponSystem>(updateOrderLevel, m_Renderer);
|
||||||
m_SystemPipeline->AddSystem<LifetimeSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<LifetimeSystem>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<CapturePointSystem>(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<FillFrustumOctreeSystem>(updateOrderLevel, m_OctreeFrustrumCulling);
|
||||||
m_SystemPipeline->AddSystem<PlayerHUD>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<PlayerHUD>(updateOrderLevel);
|
||||||
m_SystemPipeline->AddSystem<AnimationSystem>(updateOrderLevel);
|
m_SystemPipeline->AddSystem<AnimationSystem>(updateOrderLevel);
|
||||||
|
m_SystemPipeline->AddSystem<PlayerDeathSystem>(updateOrderLevel);
|
||||||
|
|
||||||
// Collision and TriggerSystem should update after player.
|
// Collision and TriggerSystem should update after player.
|
||||||
++updateOrderLevel;
|
++updateOrderLevel;
|
||||||
|
|||||||
@@ -34,14 +34,23 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
|
|||||||
|
|
||||||
//components that we need from player
|
//components that we need from player
|
||||||
auto playerCamera = player.FirstChildByName("Camera");
|
auto playerCamera = player.FirstChildByName("Camera");
|
||||||
auto playerEntityModel = player.FirstChildByName("PlayerModel")["Model"];
|
auto playerModel = player.FirstChildByName("PlayerModel");
|
||||||
auto playerEntityAnimation = player.FirstChildByName("PlayerModel")["Animation"];
|
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
|
//copy the data from player to explisioneffectmodel
|
||||||
playerEntityModel.Copy(deathEffectEW["Model"]);
|
playerEntityModel.Copy(deathEffectEW["Model"]);
|
||||||
playerEntityAnimation.Copy(deathEffectEW["Animation"]);
|
playerEntityAnimation.Copy(deathEffectEW["Animation"]);
|
||||||
//freeze the 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
|
//copy the models position,orientation
|
||||||
deathEffectEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"];
|
deathEffectEW["Transform"]["Position"] = (glm::vec3)player["Transform"]["Position"];
|
||||||
|
|||||||
@@ -1,20 +1,39 @@
|
|||||||
#include "Systems/PlayerSpawnSystem.h"
|
#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)
|
PlayerSpawnSystem::PlayerSpawnSystem(World* m_World, EventBroker* eventBroker)
|
||||||
: System(m_World, eventBroker)
|
: System(m_World, eventBroker)
|
||||||
|
, m_Timer(0.f)
|
||||||
{
|
{
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerSpawnSystem::OnInputCommand);
|
EVENT_SUBSCRIBE_MEMBER(m_OnInputCommand, &PlayerSpawnSystem::OnInputCommand);
|
||||||
EVENT_SUBSCRIBE_MEMBER(m_OnPlayerSpawnerd, &PlayerSpawnSystem::OnPlayerSpawned);
|
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);
|
m_NetworkEnabled = ResourceManager::Load<ConfigFile>("Config.ini")->Get("Networking.StartNetwork", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerSpawnSystem::Update(double dt)
|
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");
|
auto playerSpawns = m_World->GetComponents("PlayerSpawn");
|
||||||
if (playerSpawns == nullptr) {
|
if (playerSpawns == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int numSpawnedPlayers = 0;
|
||||||
for (auto& req : m_SpawnRequests) {
|
for (auto& req : m_SpawnRequests) {
|
||||||
for (auto& cPlayerSpawn : *playerSpawns) {
|
for (auto& cPlayerSpawn : *playerSpawns) {
|
||||||
EntityWrapper spawner(m_World, cPlayerSpawn.EntityID);
|
EntityWrapper spawner(m_World, cPlayerSpawn.EntityID);
|
||||||
@@ -40,13 +59,19 @@ void PlayerSpawnSystem::Update(double dt)
|
|||||||
e.Player = player;
|
e.Player = player;
|
||||||
e.Spawner = spawner;
|
e.Spawner = spawner;
|
||||||
m_EventBroker->Publish(e);
|
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();
|
m_SpawnRequests.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e)
|
bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
|
||||||
{
|
{
|
||||||
if (e.Command != "PickTeam") {
|
if (e.Command != "PickTeam") {
|
||||||
return false;
|
return false;
|
||||||
@@ -58,11 +83,37 @@ bool PlayerSpawnSystem::OnInputCommand(const Events::InputCommand& e)
|
|||||||
return false;
|
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;
|
SpawnRequest req;
|
||||||
req.PlayerID = e.PlayerID;
|
req.PlayerID = e.PlayerID;
|
||||||
req.Team = (ComponentInfo::EnumType)e.Value;
|
req.Team = (ComponentInfo::EnumType)e.Value;
|
||||||
m_SpawnRequests.push_back(req);
|
m_SpawnRequests.push_back(req);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -82,6 +133,7 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
|||||||
|
|
||||||
// Store the player for future reference
|
// Store the player for future reference
|
||||||
m_PlayerEntities[e.PlayerID] = e.Player;
|
m_PlayerEntities[e.PlayerID] = e.Player;
|
||||||
|
m_PlayerIDs[e.Player.ID] = e.PlayerID;
|
||||||
|
|
||||||
// Set the camera to the correct entity
|
// Set the camera to the correct entity
|
||||||
EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera");
|
EntityWrapper cameraEntity = e.Player.FirstChildByName("Camera");
|
||||||
@@ -110,4 +162,20 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -57,10 +57,10 @@ bool SoundSystem::OnInputCommand(const Events::InputCommand & e)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (e.Command == "TakeDamage" && e.Value > 0) {
|
if (e.Command == "TakeDamage" && e.Value > 0 && m_LocalPlayer.Valid()) {
|
||||||
Events::PlayerDamage ev;
|
Events::PlayerDamage ev;
|
||||||
ev.Player = m_LocalPlayer;
|
ev.Player = m_LocalPlayer;
|
||||||
ev.Damage = 1.0;
|
ev.Damage = e.Value;
|
||||||
m_EventBroker->Publish(ev);
|
m_EventBroker->Publish(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user