diff --git a/src/engine/server.h b/src/engine/server.h index 3f2ec9137..1857b0d2c 100644 --- a/src/engine/server.h +++ b/src/engine/server.h @@ -354,10 +354,6 @@ class IServer : public IInterface virtual int* GetIdMap(int ClientID) = 0; virtual void SetCustClt(int ClientID) = 0; - // InfClassR spectators vector - std::vector spectators_id; - - virtual int GetActivePlayerCount() = 0; }; class IGameServer : public IInterface @@ -384,6 +380,7 @@ class IGameServer : public IInterface virtual bool IsClientReady(int ClientID) = 0; virtual bool IsClientPlayer(int ClientID) = 0; + virtual int GetActivePlayerCount() = 0; virtual const char *GameType() = 0; virtual const char *Version() = 0; diff --git a/src/engine/server/server.cpp b/src/engine/server/server.cpp index 8f8eb1cca..f01ca9cf0 100755 --- a/src/engine/server/server.cpp +++ b/src/engine/server/server.cpp @@ -13,7 +13,6 @@ #include #include #include - #include #include #include @@ -4386,22 +4385,6 @@ IServer::CClientSession* CServer::GetClientSession(int ClientID) return &m_aClients[ClientID].m_Session; } -// returns how many players are currently playing and not spectating -int CServer::GetActivePlayerCount() -{ - int PlayerCount = 0; - auto& vec = spectators_id; - for(int i=0; i= MAX_CLIENTS || To < 0 || To >= MAX_CLIENTS) @@ -4547,7 +4530,7 @@ IServer::CMapVote* CServer::GetMapVote() if (m_MapVotesCounter <= 0) return 0; - float PlayerCount = GetActivePlayerCount(); + float PlayerCount = GameServer()->GetActivePlayerCount(); int HighestNum = -1; int HighestNumIndex = -1; diff --git a/src/engine/server/server.h b/src/engine/server/server.h index a1b7caddb..d51f92cb0 100644 --- a/src/engine/server/server.h +++ b/src/engine/server/server.h @@ -412,9 +412,6 @@ class CServer : public IServer virtual void ResetMapVotes(); virtual IServer::CMapVote* GetMapVote(); virtual int GetMinPlayersForMap(const char* pMapName); - - virtual int GetActivePlayerCount(); - virtual int GetTimeShiftUnit() const { return m_TimeShiftUnit; } //In ms /* INFECTION MODIFICATION END *****************************************/ diff --git a/src/game/server/entities/hero-flag.cpp b/src/game/server/entities/hero-flag.cpp index 53217032e..5b35b96b9 100644 --- a/src/game/server/entities/hero-flag.cpp +++ b/src/game/server/entities/hero-flag.cpp @@ -43,7 +43,7 @@ void CHeroFlag::FindPosition() void CHeroFlag::SetCoolDown() { // Set cooldown for next flag depending on how many players are online - int PlayerCount = Server()->GetActivePlayerCount(); + int PlayerCount = GameServer()->GetActivePlayerCount(); if (PlayerCount <= 1) { // only 1 player on, let him find as many flags as he wants @@ -70,7 +70,7 @@ void CHeroFlag::GiveGift(CCharacter* pHero) if (g_Config.m_InfTurretEnable) { - if (Server()->GetActivePlayerCount() > 2) + if (GameServer()->GetActivePlayerCount() > 2) { if (pHero->m_TurretCount == 0) pHero->GiveWeapon(WEAPON_HAMMER, -1); diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index ccbb095f4..77cb53a66 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -50,7 +50,10 @@ void CGameContext::Construct(int Resetting) m_TargetToKill = -1; m_TargetToKillCoolDown = 0; m_HeroGiftCooldown = 0; - + m_NbActivePlayers = 0; + m_NbSpectators = 0; + m_NbHumans = 0; + m_NbZombies = 0; m_ChatResponseTargetID = -1; if(Resetting==NO_RESET) @@ -133,31 +136,118 @@ class CCharacter *CGameContext::GetPlayerChar(int ClientID) return m_apPlayers[ClientID]->GetCharacter(); } -int CGameContext::GetZombieCount() { - int count = 0; +void CGameContext::CountActivePlayers(){ + + // returns how many players are currently playing and not spectating + int PlayerCount = 0; + for(int i=0; im_IsInGame && !m_apPlayers[i]->IsSpectator()) + PlayerCount++; + } + + m_NbActivePlayers = PlayerCount; + + //console output + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), "Active Players: %d", m_NbActivePlayers); + Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); +} + + +int CGameContext::GetActivePlayerCount() +{ + return m_NbActivePlayers; +} + +void CGameContext::CountSpectators(){ + + int SpecCount = 0; + for(int i=0; im_IsInGame && m_apPlayers[i]->IsSpectator()) + SpecCount++; + } + + m_NbSpectators = SpecCount; + + //console output + char aBuf[256]; + str_format(aBuf, sizeof(aBuf), "Spectators: %d", m_NbSpectators); + Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); + +} + +int CGameContext::GetSpectatorCount() +{ + return m_NbSpectators; +} + + +void CGameContext::CountHumans() +{ + int humanCounter = 0; + int zombieCounter = 0; + for(int i = 0; i < MAX_CLIENTS; i++) + { + if (!m_apPlayers[i]) + continue; + if (m_apPlayers[i]->IsHuman()) + humanCounter++; + else + zombieCounter++; + } + m_NbHumans = humanCounter; + m_NbZombies = zombieCounter; + + dbg_msg("Game", "#humans: %d -- #zombies: %d", m_NbHumans, m_NbZombies); + +} + +int CGameContext::GetHumanCount() +{ + return m_NbHumans; +} + +void CGameContext::CountZombies() +{ + int humanCounter = 0; + int zombieCounter = 0; for(int i = 0; i < MAX_CLIENTS; i++) { if (!m_apPlayers[i]) continue; if (m_apPlayers[i]->IsZombie()) - count++; + zombieCounter++; + else + humanCounter++; } - return count; + m_NbZombies = zombieCounter; + m_NbHumans = humanCounter; + + dbg_msg("Server_Player_Info", "#humans: %d -- #zombies: %d", m_NbHumans, m_NbZombies); +} + +int CGameContext::GetZombieCount() +{ + return m_NbZombies; } -int CGameContext::GetZombieCount(int zombie_class) { +int CGameContext::GetIsOfClassCount(int player_class) +{ int count = 0; for(int i = 0; i < MAX_CLIENTS; i++) { if (!m_apPlayers[i]) continue; - if (m_apPlayers[i]->IsZombie() && m_apPlayers[i]->GetClass() == zombie_class) + if (m_apPlayers[i]->GetClass() == player_class) count++; } return count; } -int CGameContext::RandomZombieToWitch() { +int CGameContext::RandomZombieToWitch() +{ std::vector zombies_id; m_WitchCallers.clear(); @@ -1036,14 +1126,10 @@ void CGameContext::OnTick() //if(world.paused) // make sure that the game object always updates m_pController->Tick(); - int NumActivePlayers = 0; for(int i = 0; i < MAX_CLIENTS; i++) { if(m_apPlayers[i]) - { - if(m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS) - NumActivePlayers++; - + { Server()->RoundStatistics()->UpdatePlayer(i, m_apPlayers[i]->GetTeam() == TEAM_SPECTATORS); m_apPlayers[i]->Tick(); @@ -1149,7 +1235,7 @@ void CGameContext::OnTick() m_aHitSoundState[i] = 0; } - Server()->RoundStatistics()->UpdateNumberOfPlayers(NumActivePlayers); + Server()->RoundStatistics()->UpdateNumberOfPlayers(GetActivePlayerCount()); /* INFECTION MODIFICATION START ***************************************/ //Clean old dots @@ -1338,6 +1424,12 @@ void CGameContext::OnClientEnter(int ClientID) Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); m_VoteUpdate = true; + + //Count players + CountActivePlayers(); + CountSpectators(); + CountHumans(); //updates also zombies + } void CGameContext::OnClientConnected(int ClientID) @@ -1389,6 +1481,11 @@ void CGameContext::OnClientConnected(int ClientID) m_BroadcastStates[ClientID].m_Priority = BROADCAST_PRIORITY_LOWEST; m_BroadcastStates[ClientID].m_PrevMessage[0] = 0; m_BroadcastStates[ClientID].m_NextMessage[0] = 0; + + CountActivePlayers(); + CountSpectators(); + CountHumans(); //updates also zombies + } void CGameContext::OnClientDrop(int ClientID, int Type, const char *pReason) @@ -1418,6 +1515,12 @@ void CGameContext::OnClientDrop(int ClientID, int Type, const char *pReason) str_format(aBuf, sizeof(aBuf), "leave player='%d:%s'", ClientID, Server()->ClientName(ClientID)); Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); + //Count players + CountActivePlayers(); + CountSpectators(); + CountHumans(); //updates also zombies + + // InfClassR end } @@ -1556,7 +1659,7 @@ void CGameContext::OnCallVote(void *pRawMsg, int ClientID) int RoundCount = m_pController->GetRoundCount(); if (m_pController->IsRoundEndTime()) RoundCount++; - if (g_Config.m_InfMinRoundsForMapVote > RoundCount && Server()->GetActivePlayerCount() > 1) + if (g_Config.m_InfMinRoundsForMapVote > RoundCount && GetActivePlayerCount() > 1) { char aBufVoteMap[128]; str_format(aBufVoteMap, sizeof(aBufVoteMap), "Each map must be played at least %i rounds before calling a map vote", g_Config.m_InfMinRoundsForMapVote); @@ -1839,15 +1942,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) /* INFECTION MODIFICATION START ***************************************/ if(m_apPlayers[ClientID]->IsZombie() && pMsg->m_Team == TEAM_SPECTATORS) { - int InfectedCount = 0; - CPlayerIterator Iter(m_apPlayers); - while(Iter.Next()) - { - if(Iter.Player()->IsZombie()) - InfectedCount++; - } - - if(InfectedCount <= 2) + if(GetZombieCount() <= 2) { SendBroadcast_Localization(ClientID, BROADCAST_PRIORITY_GAMEANNOUNCE, BROADCAST_DURATION_GAMEANNOUNCE, _("You can't join the spectators right now"), NULL); return; @@ -1864,13 +1959,6 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) if(pPlayer->GetTeam() == TEAM_SPECTATORS || pMsg->m_Team == TEAM_SPECTATORS) m_VoteUpdate = true; pPlayer->SetTeam(pMsg->m_Team); - if (pPlayer->GetTeam() == TEAM_SPECTATORS) { - AddSpectatorCID(ClientID); - } else { - RemoveSpectatorCID(ClientID); - } - (void)m_pController->CheckTeamBalance(); - pPlayer->m_TeamChangeTick = Server()->Tick(); } else SendBroadcast(ClientID, "Teams must be balanced, please join other team", BROADCAST_PRIORITY_GAMEANNOUNCE, BROADCAST_DURATION_GAMEANNOUNCE); @@ -4028,8 +4116,9 @@ bool CGameContext::ConWitch(IConsole::IResult *pResult, void *pUserData) str_format(aBuf, sizeof(aBuf), "ConWitch() called"); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "conwitch", aBuf); - if (pSelf->GetZombieCount(PLAYERCLASS_WITCH) >= MAX_WITCHES) { - pSelf->SendChatTarget_Localization(ClientID, CHATCATEGORY_DEFAULT, _("All witches are already here")); + if (pSelf->GetIsOfClassCount(PLAYERCLASS_WITCH) >= MAX_WITCHES) { + str_format(aBuf, sizeof(aBuf), "All witches are already here", MAX_WITCHES); + pSelf->SendChatTarget(ClientID, aBuf); return true; } if (pSelf->GetZombieCount() <= MIN_ZOMBIES) { @@ -4329,19 +4418,13 @@ int CGameContext::GetTargetToKill() } void CGameContext::TargetKilled() { - m_TargetToKill = -1; - - int PlayerCounter = 0; - CPlayerIterator Iter(m_apPlayers); - while(Iter.Next()) - PlayerCounter++; - - m_TargetToKillCoolDown = Server()->TickSpeed()*(10 + 3*max(0, 16 - PlayerCounter)); + m_TargetToKill = -1; + m_TargetToKillCoolDown = Server()->TickSpeed()*(10 + 3*max(0, 16 - GetActivePlayerCount() )); } void CGameContext::FlagCollected() { - float t = (8-Server()->GetActivePlayerCount()) / 8.0f; + float t = (8-GetActivePlayerCount()) / 8.0f; if (t < 0.0f) t = 0.0f; @@ -4416,17 +4499,17 @@ void CGameContext::List(int ClientID, const char* filter) void CGameContext::AddSpectatorCID(int ClientID) { Server()->RemoveMapVotesForID(ClientID); - auto& vec = Server()->spectators_id; + auto& vec = spectators_id; if(!(std::find(vec.begin(), vec.end(), ClientID) != vec.end())) vec.push_back(ClientID); } void CGameContext::RemoveSpectatorCID(int ClientID) { - auto& vec = Server()->spectators_id; + auto& vec = spectators_id; vec.erase(std::remove(vec.begin(), vec.end(), ClientID), vec.end()); } bool CGameContext::IsSpectatorCID(int ClientID) { - auto& vec = Server()->spectators_id; + auto& vec = spectators_id; return std::find(vec.begin(), vec.end(), ClientID) != vec.end(); } diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index 082efc846..a3bc40011 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -140,8 +140,20 @@ class CGameContext : public IGameServer // helper functions class CCharacter *GetPlayerChar(int ClientID); // InfClassR + void CountActivePlayers(); + int GetActivePlayerCount(); + void CountSpectators(); + int GetSpectatorCount(); + void CountHumans(); + int GetHumanCount(); + void CountZombies(); int GetZombieCount(); - int GetZombieCount(int zombie_class); + std::vector spectators_id; //spectators vector + int m_NbActivePlayers; + int m_NbSpectators; + int m_NbHumans; + int m_NbZombies; + int GetIsOfClassCount(int player_class); int RandomZombieToWitch(); std::vector m_WitchCallers; diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp index cb385fbb7..295b1c6a9 100644 --- a/src/game/server/gamecontroller.cpp +++ b/src/game/server/gamecontroller.cpp @@ -240,7 +240,7 @@ void IGameController::CycleMap(bool Forced) if(!Forced && m_RoundCount < g_Config.m_SvRoundsPerMap-1) return; - int PlayerCount = Server()->GetActivePlayerCount(); + int PlayerCount = GameServer()->GetActivePlayerCount(); CMapRotationInfo pMapRotationInfo; GetMapRotationInfo(&pMapRotationInfo); @@ -348,7 +348,7 @@ void IGameController::OnPlayerInfoChange(class CPlayer *pP) int IGameController::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon) -{ +{ // do scoreing if(!pKiller || Weapon == WEAPON_GAME) return 0; @@ -511,15 +511,9 @@ void IGameController::Tick() m_UnbalancedTick = -1; } - unsigned int nbPlayers=0; - CPlayerIterator Iter(GameServer()->m_apPlayers); - while(Iter.Next()) - { - nbPlayers++; - } // check for inactive players - if(g_Config.m_SvInactiveKickTime > 0 && nbPlayers > 1) + if(g_Config.m_SvInactiveKickTime > 0 && GameServer()->GetActivePlayerCount() > 1) { for(int i = 0; i < MAX_CLIENTS; ++i) { diff --git a/src/game/server/gamemodes/mod.cpp b/src/game/server/gamemodes/mod.cpp index dd0e53748..625d0dc7a 100644 --- a/src/game/server/gamemodes/mod.cpp +++ b/src/game/server/gamemodes/mod.cpp @@ -24,6 +24,7 @@ CGameControllerMOD::CGameControllerMOD(class CGameContext *pGameServer) m_GrowingMap = new int[m_MapWidth*m_MapHeight]; m_InfectedStarted = false; + m_NumFirstInfected = 0; for(int j=0; jm_apPlayers[ClientID]; if(pPlayer && pPlayer->IsZombie() && m_InfectedStarted) { - int NumHumans; - int NumInfected; - int NumFirstInfected; - GetPlayerCounter(ClientID, NumHumans, NumInfected, NumFirstInfected); + SetFirstInfectedNumber(); - if(NumInfected < NumFirstInfected) + if(GameServer()->GetZombieCount() < GetFirstInfNb()) { Server()->Ban(ClientID, 60*g_Config.m_InfLeaverBanTime, "Leaver"); } @@ -116,27 +114,23 @@ void CGameControllerMOD::EndRound() IGameController::EndRound(); } -void CGameControllerMOD::GetPlayerCounter(int ClientException, int& NumHumans, int& NumInfected, int& NumFirstInfected) +void CGameControllerMOD::SetFirstInfectedNumber() { - NumHumans = 0; - NumInfected = 0; - - //Count type of players - CPlayerIterator Iter(GameServer()->m_apPlayers); - while(Iter.Next()) - { - if(Iter.ClientID() == ClientException) continue; - - if(Iter.Player()->IsZombie()) NumInfected++; - else NumHumans++; - } + int NumHumans = GameServer()->GetHumanCount(); + int NumInfected = GameServer()->GetZombieCount(); if(NumHumans + NumInfected <= 1) - NumFirstInfected = 0; - else if(NumHumans + NumInfected <= 2) - NumFirstInfected = 1; + m_NumFirstInfected = 0; + else if(NumHumans + NumInfected <= 3) + m_NumFirstInfected = 1; else - NumFirstInfected = 2; + m_NumFirstInfected = 2; + +} + +int CGameControllerMOD::GetFirstInfNb() +{ + return m_NumFirstInfected; } void CGameControllerMOD::Tick() @@ -175,16 +169,10 @@ void CGameControllerMOD::Tick() } } - int NumHumans = 0; - int NumInfected = 0; - int NumFirstInfected = 0; - GetPlayerCounter(-1, NumHumans, NumInfected, NumFirstInfected); - - m_InfectedStarted = false; - //If the game can start ... - if(m_GameOverTick == -1 && NumHumans + NumInfected >= g_Config.m_InfMinPlayers) + if(m_GameOverTick == -1 && GameServer()->GetActivePlayerCount() >= g_Config.m_InfMinPlayers) { + if(IsInfectionStarted()) { bool StartInfectionTrigger = (m_RoundStartTick + Server()->TickSpeed()*10 == Server()->Tick()); @@ -215,14 +203,14 @@ void CGameControllerMOD::Tick() } } - int NumNeededInfection = NumFirstInfected; + int NumNeededInfection = GetFirstInfNb(); //outer loop generates random numbers for each successful infected human - while(NumInfected < NumNeededInfection && NumHumans > 1) + while(GameServer()->GetZombieCount() < NumNeededInfection && GameServer()->GetHumanCount() > 1) { //propabillity for one human to get infected - float InfectionProb = 1.0/static_cast(NumHumans); + float InfectionProb = 1.0/static_cast(GameServer()->GetHumanCount()); //generate random float float random = random_float(); @@ -253,8 +241,7 @@ void CGameControllerMOD::Tick() //infect player Server()->InfecteClient(Iter.ClientID()); Iter.Player()->StartInfection(); - NumInfected++; - NumHumans--; + GameServer()->CountHumans(); //updates also zombies //notification to other players GameServer()->SendChatTarget_Localization(-1, CHATCATEGORY_INFECTION, _("{str:VictimName} has been infected"), @@ -281,8 +268,6 @@ void CGameControllerMOD::Tick() { Server()->InfecteClient(Iter.ClientID()); Iter.Player()->StartInfection(); - NumInfected++; - NumHumans--; GameServer()->SendChatTarget_Localization(-1, CHATCATEGORY_INFECTION, _("{str:VictimName} has been infected"), "VictimName", @@ -315,6 +300,8 @@ void CGameControllerMOD::Tick() } else { + SetFirstInfectedNumber(); // as long as infection is not started + GameServer()->DisableTargetToKill(); CPlayerIterator IterSpec(GameServer()->m_apPlayers); @@ -325,7 +312,7 @@ void CGameControllerMOD::Tick() } //Win check - if(m_InfectedStarted && NumHumans == 0 && NumInfected > 1) + if(m_InfectedStarted && GameServer()->GetHumanCount() == 0 && GameServer()->GetZombieCount() > 1) { int Seconds = (Server()->Tick()-m_RoundStartTick)/((float)Server()->TickSpeed()); @@ -418,13 +405,13 @@ void CGameControllerMOD::Tick() //If no more explosions, game over, decide who win if(!NewExplosion) { - if(NumHumans) + if(GameServer()->GetHumanCount()) { - GameServer()->SendChatTarget_Localization_P(-1, CHATCATEGORY_HUMANS, NumHumans, _P("One human won the round", "{int:NumHumans} humans won the round"), "NumHumans", &NumHumans, NULL); + GameServer()->SendChatTarget_Localization_P(-1, CHATCATEGORY_HUMANS, GameServer()->GetHumanCount(), _P("One human won the round", "{int:NumHumans} humans won the round"), "NumHumans", GameServer()->GetHumanCount(), NULL); char aBuf[512]; int Seconds = (Server()->Tick()-m_RoundStartTick)/((float)Server()->TickSpeed()); - str_format(aBuf, sizeof(aBuf), "round_end winner='humans' survivors='%d' duration='%d' round='%d of %d'", NumHumans, Seconds, m_RoundCount+1, g_Config.m_SvRoundsPerMap); + str_format(aBuf, sizeof(aBuf), "round_end winner='humans' survivors='%d' duration='%d' round='%d of %d'", GameServer()->GetHumanCount(), Seconds, m_RoundCount+1, g_Config.m_SvRoundsPerMap); GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); CPlayerIterator Iter(GameServer()->m_apPlayers); @@ -461,7 +448,21 @@ void CGameControllerMOD::Tick() { GameServer()->DisableTargetToKill(); - m_RoundStartTick = Server()->Tick(); + m_RoundStartTick = Server()->Tick(); + + //stop started round if not enough players are online + if(m_InfectedStarted) + { + + GameServer()->SendChatTarget_Localization(-1, CHATCATEGORY_INFECTED, _("Please wait until more players have joined the game"), NULL); + + char aBuf[512]; + str_format(aBuf, sizeof(aBuf), "round_end too few players round='%d of %d'", m_RoundCount+1, g_Config.m_SvRoundsPerMap); + GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); + + EndRound(); + } + } } diff --git a/src/game/server/gamemodes/mod.h b/src/game/server/gamemodes/mod.h index ac0e2bd67..dd5640aaf 100644 --- a/src/game/server/gamemodes/mod.h +++ b/src/game/server/gamemodes/mod.h @@ -35,10 +35,11 @@ class CGameControllerMOD : public IGameController virtual bool IsInfectionStarted(); void ResetFinalExplosion(); + int GetFirstInfNb(); private: bool IsSpawnable(vec2 Pos, int TeleZoneIndex); - void GetPlayerCounter(int ClientException, int& NumHumans, int& NumInfected, int& NumFirstInfected); + void SetFirstInfectedNumber(); private: int m_MapWidth; @@ -47,5 +48,6 @@ class CGameControllerMOD : public IGameController bool m_ExplosionStarted; bool m_InfectedStarted; + int m_NumFirstInfected; }; #endif diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index f167097ee..477110b36 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -57,6 +57,7 @@ CPlayer::CPlayer(CGameContext *pGameServer, int ClientID, int Team) m_PrevTuningParams = *pGameServer->Tuning(); m_NextTuningParams = m_PrevTuningParams; m_IsInGame = false; + m_IsSpectator = false; for(unsigned int i=0; im_pController->ClampTeam(Team); if(m_Team == Team) return; - + char aBuf[512]; - if(DoChatMsg) + + if(DoChatMsg) //default is true { if(Team == TEAM_SPECTATORS) { GameServer()->SendChatTarget_Localization(-1, CHATCATEGORY_PLAYER, _("{str:PlayerName} joined the spectators"), "PlayerName", Server()->ClientName(m_ClientID), NULL); - GameServer()->AddSpectatorCID(m_ClientID); - Server()->InfecteClient(m_ClientID); } else { @@ -563,7 +563,26 @@ void CPlayer::SetTeam(int Team, bool DoChatMsg) if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_SpectatorID == m_ClientID) GameServer()->m_apPlayers[i]->m_SpectatorID = SPEC_FREEVIEW; } + + //add spectator + GameServer()->AddSpectatorCID(m_ClientID); + m_IsSpectator = true; + + } + else + { + //remove spectator + GameServer()->RemoveSpectatorCID(m_ClientID); + m_IsSpectator = false; + } + + GameServer()->CountActivePlayers(); + GameServer()->CountSpectators(); + GameServer()->CountHumans(); // updates also zombies + + GameServer()->m_pController->CheckTeamBalance(); + m_TeamChangeTick = Server()->Tick(); } void CPlayer::TryRespawn() @@ -762,6 +781,9 @@ void CPlayer::SetClass(int newClass) char aBuf[256]; str_format(aBuf, sizeof(aBuf), "choose_class player='%s' class='%d'", Server()->ClientName(m_ClientID), newClass); GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "game", aBuf); + + //update number of humans and zombies + GameServer()->CountHumans(); //updates also zombies } int CPlayer::GetOldClass() @@ -815,6 +837,11 @@ bool CPlayer::IsHuman() const return !(m_class > END_HUMANCLASS); } +bool CPlayer::IsSpectator() const +{ + return m_IsSpectator; +} + bool CPlayer::IsKownClass(int c) { return m_knownClass[c]; diff --git a/src/game/server/player.h b/src/game/server/player.h index 31a6a39a6..df8e38c12 100644 --- a/src/game/server/player.h +++ b/src/game/server/player.h @@ -145,6 +145,7 @@ class CPlayer bool m_knownClass[NB_PLAYERCLASS]; int m_InfectionTick; + bool m_IsSpectator; int GetScoreMode(); void SetScoreMode(int Mode); @@ -160,6 +161,7 @@ class CPlayer bool IsInfected() const; bool IsZombie() const; bool IsHuman() const; + bool IsSpectator() const; void StartInfection(bool force = false); bool IsKownClass(int c);