Merge remote-tracking branch 'origin/master' into Menu
# Conflicts: # resources/Schema/Components.xsd # resources/Schema/Entities/NewMapWSpectatorCam.xml # resources/Schema/Types/Entity.xsd # src/Game/Game.cpp
This commit is contained in:
@@ -40,7 +40,7 @@ bool ButtonSystem::OnMousePress(const Events::MousePress& e)
|
||||
//You have clicked on a button entity, send pressed event.
|
||||
if (m_World->HasComponent(m_PickData.Entity, "InputCmdButton")) {
|
||||
Events::InputCommand eInputCmd;
|
||||
eInputCmd.PlayerID = LocalPlayer.ID;
|
||||
eInputCmd.PlayerID = -1;
|
||||
eInputCmd.Player = LocalPlayer;
|
||||
EntityWrapper button = EntityWrapper(m_World, m_PickData.Entity);
|
||||
eInputCmd.Command = (std::string)button["InputCmdButton"]["Command"];
|
||||
@@ -68,7 +68,7 @@ bool ButtonSystem::OnMouseRelease(const Events::MouseRelease& e)
|
||||
|
||||
if (m_World->HasComponent(m_PickData.Entity, "InputCmdButton")) {
|
||||
Events::InputCommand eInputCmd;
|
||||
eInputCmd.PlayerID = LocalPlayer.ID;
|
||||
eInputCmd.PlayerID = -1;
|
||||
eInputCmd.Player = LocalPlayer;
|
||||
EntityWrapper button = EntityWrapper(m_World, m_PickData.Entity);
|
||||
eInputCmd.Command = (std::string)button["InputCmdButton"]["Command"];
|
||||
|
||||
@@ -641,22 +641,7 @@ void Server::parsePlayerTransform(Packet& packet)
|
||||
|
||||
bool Server::shouldSendToClient(EntityWrapper childEntity)
|
||||
{
|
||||
auto children = m_World->GetDirectChildren(childEntity.ID);
|
||||
for (auto it = children.first; it != children.second; it++) {
|
||||
EntityWrapper child(m_World, it->second);
|
||||
if (child.HasComponent("CapturePoint") || child.HasComponent("HealthPickup")
|
||||
|| child.HasComponent("AmmoPickup")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return childEntity.HasComponent("Player")
|
||||
|| childEntity.FirstParentWithComponent("Player").Valid()
|
||||
|| childEntity.HasComponent("CapturePoint")
|
||||
|| childEntity.HasComponent("HealthPickup")
|
||||
|| childEntity.HasComponent("AmmoPickup")
|
||||
|| childEntity.HasComponent("ScoreScreen")
|
||||
|| childEntity.FirstParentWithComponent("ScoreScreen").Valid()
|
||||
|| childEntity.FirstParentWithComponent("CapturePoint").Valid();
|
||||
return childEntity.HasComponent("NetworkComponent") || childEntity.FirstParentWithComponent("NetworkComponent").Valid();
|
||||
}
|
||||
|
||||
PlayerID Server::getPlayerIDFromEndpoint()
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "Game/Systems/BoostSystem.h"
|
||||
#include "Game/Systems/BoostIconsHUDSystem.h"
|
||||
#include "Game/Systems/ScoreScreenSystem.h"
|
||||
#include "Game/Systems/SpectatorCameraSystem.h"
|
||||
#include "GUI/ButtonSystem.h"
|
||||
#include "Game/Systems/MainMenuSystem.h"
|
||||
#include "Game/Systems/ServerListSystem.h"
|
||||
@@ -150,6 +151,7 @@ Game::Game(int argc, char* argv[])
|
||||
m_SystemPipeline->AddSystem<MainMenuSystem>(updateOrderLevel, m_Renderer);
|
||||
m_SystemPipeline->AddSystem<BoostIconsHUDSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<ScoreScreenSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<SpectatorCameraSystem>(updateOrderLevel);
|
||||
m_SystemPipeline->AddSystem<ServerListSystem>(updateOrderLevel, m_Renderer);
|
||||
// Populate Octree with collidables
|
||||
++updateOrderLevel;
|
||||
|
||||
@@ -37,8 +37,7 @@ void AmmoPickupSystem::Update(double dt)
|
||||
|
||||
//erase the current element (somePickup)
|
||||
it = m_ETriggerTouchVector.erase(it);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
it++;
|
||||
}
|
||||
}
|
||||
@@ -48,7 +47,7 @@ void AmmoPickupSystem::Update(double dt)
|
||||
m_PickupAtMaximum.erase(it);
|
||||
break;
|
||||
}
|
||||
if ((int)it->player["AssaultWeapon"]["Ammo"] < (int)it->player["AssaultWeapon"]["MaxAmmo"]) {
|
||||
if (!DoesPlayerHaveMaxAmmo(it->player)) {
|
||||
DoPickup(it->player, it->trigger);
|
||||
m_PickupAtMaximum.erase(it);
|
||||
break;
|
||||
@@ -56,6 +55,58 @@ void AmmoPickupSystem::Update(double dt)
|
||||
}
|
||||
}
|
||||
}
|
||||
bool AmmoPickupSystem::DoesPlayerHaveMaxAmmo(EntityWrapper &player) {
|
||||
PlayerClass playerClass = DetermineClass(player);
|
||||
if (playerClass == PlayerClass::Defender) {
|
||||
return !((int)player["DefenderWeapon"]["Ammo"] < (int)player["DefenderWeapon"]["MaxAmmo"]);
|
||||
} else if (playerClass == PlayerClass::Sniper) {
|
||||
return !((int)player["SniperWeapon"]["Ammo"] < (int)player["SniperWeapon"]["MaxAmmo"]);
|
||||
} else if (playerClass == PlayerClass::Assault) {
|
||||
return !((int)player["AssaultWeapon"]["Ammo"] < (int)player["AssaultWeapon"]["MaxAmmo"]);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
void AmmoPickupSystem::SetPlayerAmmo(EntityWrapper &player, int ammoGain) {
|
||||
int maxWeaponAmmo = GetPlayerMaxAmmo(player);
|
||||
|
||||
PlayerClass playerClass = DetermineClass(player);
|
||||
if (playerClass == PlayerClass::Defender) {
|
||||
(int&)player["DefenderWeapon"]["Ammo"] = std::min((int)player["DefenderWeapon"]["Ammo"] + ammoGain, maxWeaponAmmo);
|
||||
} else if (playerClass == PlayerClass::Sniper) {
|
||||
(int&)player["SniperWeapon"]["Ammo"] = std::min((int)player["SniperWeapon"]["Ammo"] + ammoGain, maxWeaponAmmo);
|
||||
} else if (playerClass == PlayerClass::Assault) {
|
||||
(int&)player["AssaultWeapon"]["Ammo"] = std::min((int)player["AssaultWeapon"]["Ammo"] + ammoGain, maxWeaponAmmo);
|
||||
} else {
|
||||
//unknown class - ignore
|
||||
}
|
||||
}
|
||||
int AmmoPickupSystem::GetPlayerMaxAmmo(EntityWrapper &player) {
|
||||
PlayerClass playerClass = DetermineClass(player);
|
||||
if (playerClass == PlayerClass::Defender) {
|
||||
return (int)player["DefenderWeapon"]["MaxAmmo"];
|
||||
} else if (playerClass == PlayerClass::Sniper) {
|
||||
return (int)player["SniperWeapon"]["MaxAmmo"];
|
||||
} else if (playerClass == PlayerClass::Assault) {
|
||||
return (int)player["AssaultWeapon"]["MaxAmmo"];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
AmmoPickupSystem::PlayerClass AmmoPickupSystem::DetermineClass(EntityWrapper &player)
|
||||
{
|
||||
//determine the class based on what component the inflictor-player has
|
||||
if (m_World->HasComponent(player.ID, "DashAbility")) {
|
||||
return PlayerClass::Assault;
|
||||
}
|
||||
if (m_World->HasComponent(player.ID, "ShieldAbility")) {
|
||||
return PlayerClass::Defender;
|
||||
}
|
||||
if (m_World->HasComponent(player.ID, "SprintAbility")) {
|
||||
return PlayerClass::Sniper;
|
||||
}
|
||||
return PlayerClass::None;
|
||||
}
|
||||
|
||||
bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
|
||||
{
|
||||
@@ -63,7 +114,7 @@ bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
|
||||
return false;
|
||||
}
|
||||
//TODO: add other weapontypes
|
||||
if (!e.Entity.HasComponent("AssaultWeapon")) {
|
||||
if (DetermineClass(e.Entity) == PlayerClass::None) {
|
||||
return false;
|
||||
}
|
||||
if (!e.Trigger.HasComponent("AmmoPickup")) {
|
||||
@@ -71,7 +122,7 @@ bool AmmoPickupSystem::OnTriggerTouch(Events::TriggerTouch& e)
|
||||
}
|
||||
|
||||
//if at maxammo, save the trigger-touch to a vector since standing inside it will not re-trigger the trigger
|
||||
if ((int)e.Entity["AssaultWeapon"]["Ammo"] >= (int)e.Entity["AssaultWeapon"]["MaxAmmo"]) {
|
||||
if (DoesPlayerHaveMaxAmmo(e.Entity)) {
|
||||
m_PickupAtMaximum.push_back({ e.Entity, e.Trigger });
|
||||
return false;
|
||||
}
|
||||
@@ -85,19 +136,16 @@ bool AmmoPickupSystem::OnAmmoPickup(Events::AmmoPickup & e)
|
||||
return false;
|
||||
}
|
||||
//TODO: add other weapontypes
|
||||
if (!e.Player.HasComponent("AssaultWeapon")) {
|
||||
if (DetermineClass(e.Player) == PlayerClass::None) {
|
||||
return false;
|
||||
}
|
||||
int maxWeaponAmmo = (int)e.Player["AssaultWeapon"]["MaxAmmo"];
|
||||
int& currentAmmo = (int)e.Player["AssaultWeapon"]["Ammo"];
|
||||
//cant pick up ammopacks if you are already at MaxAmmo
|
||||
if (currentAmmo >= maxWeaponAmmo) {
|
||||
if (DoesPlayerHaveMaxAmmo(e.Player)) {
|
||||
return false;
|
||||
}
|
||||
SetPlayerAmmo(e.Player, e.AmmoGain);
|
||||
|
||||
currentAmmo = std::min(currentAmmo + e.AmmoGain, maxWeaponAmmo);
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AmmoPickupSystem::OnTriggerLeave(Events::TriggerLeave& e) {
|
||||
@@ -119,7 +167,7 @@ void AmmoPickupSystem::DoPickup(EntityWrapper &player, EntityWrapper &trigger) {
|
||||
if (!trigger.Valid()) {
|
||||
return;
|
||||
}
|
||||
int maxWeaponAmmo = (int)player["AssaultWeapon"]["MaxAmmo"];
|
||||
int maxWeaponAmmo = GetPlayerMaxAmmo(player);
|
||||
int ammoGiven = 0.01*(double)trigger["AmmoPickup"]["AmmoGain"] * maxWeaponAmmo;
|
||||
|
||||
Events::AmmoPickup ePlayerAmmoPickup;
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
#include "Systems/PlayerDeathSystem.h"
|
||||
#include "Core/ELockMouse.h"
|
||||
|
||||
PlayerDeathSystem::PlayerDeathSystem(SystemParams params)
|
||||
: System(params)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_OnPlayerDeath, &PlayerDeathSystem::OnPlayerDeath);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EEntityDeleted, &PlayerDeathSystem::OnEntityDeleted);
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &PlayerDeathSystem::OnInputCommand);
|
||||
}
|
||||
|
||||
void PlayerDeathSystem::Update(double dt)
|
||||
@@ -33,10 +35,10 @@ void PlayerDeathSystem::createDeathEffect(EntityWrapper player)
|
||||
|
||||
//components that we need from player
|
||||
auto playerModel = player.FirstChildByName("PlayerModel");
|
||||
if (!playerModel.Valid()) {
|
||||
return;
|
||||
}
|
||||
if (!playerModel.HasComponent("Model") || !playerModel.HasComponent("Animation")) {
|
||||
if (player == LocalPlayer) {
|
||||
setSpectatorCamera();
|
||||
}
|
||||
return;
|
||||
}
|
||||
auto playerEntityModel = playerModel["Model"];
|
||||
@@ -68,14 +70,35 @@ bool PlayerDeathSystem::OnEntityDeleted(Events::EntityDeleted& e)
|
||||
if (m_LocalPlayerDeathEffect.ID != e.DeletedEntity) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// If the player hasn't spawned already, activate the spectator camera.
|
||||
if (!LocalPlayer.Valid()) {
|
||||
setSpectatorCamera();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void PlayerDeathSystem::setSpectatorCamera()
|
||||
{
|
||||
// Look for the spectator camera entity in the level.
|
||||
EntityWrapper spectatorCam = m_World->GetFirstEntityByName("SpectatorCamera");
|
||||
if (!spectatorCam.Valid() || !spectatorCam.HasComponent("Camera") || LocalPlayer.Valid()) {
|
||||
return false;
|
||||
if (!spectatorCam.HasComponent("Camera")) {
|
||||
return;
|
||||
}
|
||||
Events::SetCamera eSetCamera;
|
||||
eSetCamera.CameraEntity = spectatorCam;
|
||||
m_EventBroker->Publish(eSetCamera);
|
||||
return true;
|
||||
Events::UnlockMouse unlock;
|
||||
m_EventBroker->Publish(unlock);
|
||||
}
|
||||
|
||||
bool PlayerDeathSystem::OnInputCommand(Events::InputCommand& e)
|
||||
{
|
||||
if (e.Value == 0 || e.Command != "SwapToTeamPick" && e.Command != "SwapToClassPick") {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ensure that we don't set spectator camera if the player deliberately changes to class/team pick.
|
||||
m_LocalPlayerDeathEffect = EntityWrapper::Invalid;
|
||||
return true;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "Systems/PlayerSpawnSystem.h"
|
||||
#include "Core/ELockMouse.h"
|
||||
|
||||
PlayerSpawnSystem::PlayerSpawnSystem(SystemParams params)
|
||||
: System(params)
|
||||
@@ -59,7 +60,15 @@ void PlayerSpawnSystem::Update(double dt)
|
||||
}
|
||||
|
||||
int numSpawnedPlayers = 0;
|
||||
for (auto& req : m_SpawnRequests) {
|
||||
int playersSpectating = 0;
|
||||
const int numRequestsToHandle = (int)m_SpawnRequests.size();
|
||||
for (auto it = m_SpawnRequests.begin(); it != m_SpawnRequests.end(); ++it) {
|
||||
// It is valid if they didn't pick class yet
|
||||
// but don't spawn anything, goto next spawnrequest.
|
||||
if (it->Class == PlayerClass::None) {
|
||||
++playersSpectating;
|
||||
continue;
|
||||
}
|
||||
for (auto& cPlayerSpawn : *playerSpawns) {
|
||||
EntityWrapper spawner(m_World, cPlayerSpawn.EntityID);
|
||||
if (!spawner.HasComponent("Spawner")) {
|
||||
@@ -69,43 +78,49 @@ void PlayerSpawnSystem::Update(double dt)
|
||||
// If the spawner has a team affiliation, check it
|
||||
if (spawner.HasComponent("Team")) {
|
||||
auto cSpawnerTeam = spawner["Team"];
|
||||
if ((int)cSpawnerTeam["Team"] != req.Team) {
|
||||
// Increase num spawned players if someone picks spectator, since it is valid to pick spectator
|
||||
// but don't spawn anything, goto next spawnrequest.
|
||||
if (req.Team == (int)cSpawnerTeam["Team"].Enum("Spectator")) {
|
||||
++numSpawnedPlayers;
|
||||
if ((int)cSpawnerTeam["Team"] != it->Team) {
|
||||
// If they somehow has a valid class as spectator, don't spawn them.
|
||||
if (it->Team == cSpawnerTeam["Team"].Enum("Spectator")) {
|
||||
++playersSpectating;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Choose a different spawner depending on class picked?
|
||||
|
||||
// Spawn the player!
|
||||
EntityWrapper player = SpawnerSystem::Spawn(spawner, EntityWrapper::Invalid, "Player");
|
||||
// Set the player team affiliation
|
||||
player["Team"]["Team"] = req.Team;
|
||||
player["Team"]["Team"] = it->Team;
|
||||
|
||||
// Publish a PlayerSpawned event
|
||||
Events::PlayerSpawned e;
|
||||
e.PlayerID = req.PlayerID;
|
||||
e.PlayerID = it->PlayerID;
|
||||
e.Player = player;
|
||||
e.Spawner = spawner;
|
||||
m_EventBroker->Publish(e);
|
||||
++numSpawnedPlayers;
|
||||
it = m_SpawnRequests.erase(it);
|
||||
break;
|
||||
}
|
||||
if (it == m_SpawnRequests.end()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (numSpawnedPlayers != (int)m_SpawnRequests.size()) {
|
||||
LOG_DEBUG("%i players were supposed to be spawned or set as spectator, but only %i was handled.", (int)m_SpawnRequests.size(), numSpawnedPlayers);
|
||||
if (numSpawnedPlayers != numRequestsToHandle - playersSpectating) {
|
||||
LOG_DEBUG("%i players were supposed to be spawned, but only %i was successfully.", numRequestsToHandle - playersSpectating, numSpawnedPlayers);
|
||||
} else {
|
||||
LOG_DEBUG("%i players were spawned or set as spectator.", numSpawnedPlayers);
|
||||
std::string dbg = numSpawnedPlayers != 0 ? std::to_string(numSpawnedPlayers) + " players were spawned. " : "";
|
||||
dbg += playersSpectating != 0 ? std::to_string(playersSpectating) + " players are spectating/picking class. " : "";
|
||||
LOG_DEBUG(dbg.c_str());
|
||||
}
|
||||
m_SpawnRequests.clear();
|
||||
}
|
||||
|
||||
bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
|
||||
{
|
||||
if (e.Command != "PickTeam" && e.Command != "SwapToClassPick") {
|
||||
if (e.Command != "PickTeam" && e.Command != "PickClass" && e.Command != "SwapToTeamPick" && e.Command != "SwapToClassPick") {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -113,19 +128,6 @@ bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
|
||||
return false;
|
||||
}
|
||||
|
||||
// A dead client should be able to swap to the overwatch camera.
|
||||
if (IsClient && !LocalPlayer.Valid()) {
|
||||
// Set the camera as active, if it exists.
|
||||
// Find the respawn camera or class pick camera.
|
||||
std::string camName = e.Command == "SwapToClassPick" ? "PickClassCamera" : "SpectatorCamera";
|
||||
EntityWrapper spectatorCam = m_World->GetFirstEntityByName(camName);
|
||||
if (spectatorCam.Valid() && spectatorCam.HasComponent("Camera")) {
|
||||
Events::SetCamera eSetCamera;
|
||||
eSetCamera.CameraEntity = spectatorCam;
|
||||
m_EventBroker->Publish(eSetCamera);
|
||||
}
|
||||
}
|
||||
|
||||
// Team picks should be processed ONLY server-side!
|
||||
// Don't make a spawn request if we're the client.
|
||||
if (!IsServer && m_NetworkEnabled) {
|
||||
@@ -136,27 +138,38 @@ bool PlayerSpawnSystem::OnInputCommand(Events::InputCommand& e)
|
||||
auto iter = m_SpawnRequests.begin();
|
||||
for (; iter != m_SpawnRequests.end(); ++iter) {
|
||||
if (iter->PlayerID == e.PlayerID) {
|
||||
// If player wants to switch class, remove their spawn request.
|
||||
if (e.Command == "SwapToClassPick") {
|
||||
m_SpawnRequests.erase(iter);
|
||||
// If player wants to switch team or class , remove their selected class so they don't spawn.
|
||||
if (e.Command == "SwapToTeamPick" || e.Command == "SwapToClassPick") {
|
||||
iter->Class = PlayerClass::None;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (e.Command == "SwapToClassPick") {
|
||||
return true;
|
||||
}
|
||||
//If we get here we got a PickTeam or PickClass, so add or alter a spawn request.
|
||||
|
||||
if (iter != m_SpawnRequests.end()) {
|
||||
// If player is in queue to spawn, then change their team affiliation in the request.
|
||||
iter->Team = (ComponentInfo::EnumType)e.Value;
|
||||
// If player is in queue to spawn, then change their team affiliation or class in the request.
|
||||
if (e.Command == "PickTeam") {
|
||||
iter->Team = (ComponentInfo::EnumType)e.Value;
|
||||
} else {
|
||||
iter->Class = static_cast<PlayerClass>((int)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;
|
||||
if (e.Command == "PickTeam") {
|
||||
req.Team = (ComponentInfo::EnumType)e.Value;
|
||||
req.Class = PlayerClass::None;
|
||||
} else {
|
||||
// Should never get here, since you should have picked a team before you ever get a chance to pick class.
|
||||
LOG_WARNING("Sequence error: Should not be able to pick class before team");
|
||||
req.Team = 1; // TODO: 1 Signifies spectator, should probably have real enum here later.
|
||||
req.Class = static_cast<PlayerClass>((int)e.Value);
|
||||
}
|
||||
m_SpawnRequests.push_back(req);
|
||||
} else {
|
||||
return false;
|
||||
@@ -191,6 +204,8 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
||||
Events::SetCamera e;
|
||||
e.CameraEntity = cameraEntity;
|
||||
m_EventBroker->Publish(e);
|
||||
Events::LockMouse lock;
|
||||
m_EventBroker->Publish(lock);
|
||||
}
|
||||
|
||||
// HACK: Set the player model color to team color
|
||||
@@ -210,7 +225,7 @@ bool PlayerSpawnSystem::OnPlayerSpawned(Events::PlayerSpawned& e)
|
||||
|
||||
bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e)
|
||||
{
|
||||
//Only spawn request if network is disabled or we are server.
|
||||
// Only spawn request if network is disabled or we are server.
|
||||
if (!IsServer && m_NetworkEnabled) {
|
||||
return false;
|
||||
}
|
||||
@@ -218,10 +233,6 @@ bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e)
|
||||
return false;
|
||||
}
|
||||
ComponentWrapper cTeam = e.Player["Team"];
|
||||
//A spectator can't die anyway
|
||||
if ((ComponentInfo::EnumType)cTeam["Team"] == cTeam["Team"].Enum("Spectator")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_PlayerIDs.count(e.Player.ID) == 0) {
|
||||
return false;
|
||||
@@ -230,6 +241,16 @@ bool PlayerSpawnSystem::OnPlayerDeath(Events::PlayerDeath& e)
|
||||
SpawnRequest req;
|
||||
req.PlayerID = m_PlayerIDs.at(e.Player.ID);
|
||||
req.Team = cTeam["Team"];
|
||||
// TODO: Something better than temp class state code, if we ever add class enums in .xml
|
||||
if (e.Player.HasComponent("DashAbility")) {
|
||||
req.Class = PlayerClass::Assault;
|
||||
} else if (e.Player.HasComponent("SprintAbility")) {
|
||||
req.Class = PlayerClass::Sniper;
|
||||
} else if (e.Player.HasComponent("ShieldAbility")) {
|
||||
req.Class = PlayerClass::Defender;
|
||||
} else {
|
||||
req.Class = PlayerClass::None;
|
||||
}
|
||||
m_SpawnRequests.push_back(req);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "Systems/SpectatorCameraSystem.h"
|
||||
#include "Rendering/ESetCamera.h"
|
||||
#include "Core/ELockMouse.h"
|
||||
|
||||
SpectatorCameraSystem::SpectatorCameraSystem(SystemParams params)
|
||||
: System(params)
|
||||
, m_CamSetToTeamPick(false)
|
||||
, m_PickedTeam(-1)
|
||||
{
|
||||
EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &SpectatorCameraSystem::OnInputCommand);
|
||||
}
|
||||
|
||||
void SpectatorCameraSystem::Update(double dt)
|
||||
{
|
||||
if (!m_CamSetToTeamPick && IsClient) {
|
||||
// Find the class pick camera and set them to it, since they need to pick a team before they can leave the screen.
|
||||
EntityWrapper spectatorCam = m_World->GetFirstEntityByName("PickTeamCamera");
|
||||
if (spectatorCam.HasComponent("Camera")) {
|
||||
m_CamSetToTeamPick = true;
|
||||
Events::SetCamera eSetCamera;
|
||||
eSetCamera.CameraEntity = spectatorCam;
|
||||
m_EventBroker->Publish(eSetCamera);
|
||||
Events::UnlockMouse unlock;
|
||||
m_EventBroker->Publish(unlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SpectatorCameraSystem::OnInputCommand(const Events::InputCommand& e)
|
||||
{
|
||||
// Only the client should do this, and only if player is not spawned.
|
||||
if (!IsClient || LocalPlayer.Valid()) {
|
||||
return false;
|
||||
}
|
||||
bool swapToClass = e.Command == "PickTeam" || e.Command == "SwapToClassPick";
|
||||
if (e.Value == 0 || !swapToClass && e.Command != "SwapToTeamPick" && e.Command != "PickClass") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.Command == "PickTeam") {
|
||||
m_PickedTeam = e.Value;
|
||||
}
|
||||
|
||||
// If a team has not been picked, they may not exit the pick team screen.
|
||||
if (m_PickedTeam == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// A dead client should be able to swap to and between the overwatch cameras.
|
||||
std::string camName;
|
||||
// TODO: 1 Signifies spectator, should probably have real enum here later.
|
||||
// Spectators should never end up at the class select, instead put them at the SpectatorCamera.
|
||||
if (swapToClass && m_PickedTeam != 1) {
|
||||
camName = "PickClassCamera";
|
||||
} else if (e.Command == "SwapToTeamPick") {
|
||||
camName = "PickTeamCamera";
|
||||
} else {
|
||||
camName = "SpectatorCamera";
|
||||
}
|
||||
EntityWrapper spectatorCam = m_World->GetFirstEntityByName(camName);
|
||||
// Set the camera as active, if it exists.
|
||||
if (spectatorCam.HasComponent("Camera")) {
|
||||
// Set the class pick button visible if a blue or red team is picked, else invisible.
|
||||
EntityWrapper HUD;
|
||||
if (camName == "SpectatorCamera") {
|
||||
HUD = spectatorCam.FirstChildByName("SpectatorHUD");
|
||||
} else if (camName == "PickTeamCamera") {
|
||||
HUD = spectatorCam.FirstChildByName("PickTeamHUD");
|
||||
}
|
||||
// If we are at the class pick already, or if HUD is invalid for any other reason, do nothing.
|
||||
if (HUD.Valid()) {
|
||||
EntityWrapper toClassButton = spectatorCam.FirstChildByName("ToClassPick");
|
||||
if (toClassButton.Valid()) {
|
||||
// Set ClassButton as invisible if spectator, else visible.
|
||||
bool visible = m_PickedTeam != 1; // TODO: 1 Signifies spectator.
|
||||
toClassButton["Sprite"]["Visible"] = visible;
|
||||
for (auto& child : toClassButton.ChildrenWithComponent("Text")) {
|
||||
child["Text"]["Visible"] = visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
Events::SetCamera eSetCamera;
|
||||
eSetCamera.CameraEntity = spectatorCam;
|
||||
m_EventBroker->Publish(eSetCamera);
|
||||
Events::UnlockMouse unlock;
|
||||
m_EventBroker->Publish(unlock);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user