diff options
| author | Marius "Teelevision" Neugebauer <marius@teele.eu> | 2014-03-30 04:05:57 +0200 |
|---|---|---|
| committer | Marius "Teelevision" Neugebauer <marius@teele.eu> | 2014-03-30 04:05:57 +0200 |
| commit | e799504cb2655bb3aa3a25c2a69ddc80558f9e99 (patch) | |
| tree | e9d3d8f63f4b50de198b5444f1d5111bc4391554 /src | |
| parent | 19a471a30c922ea3beffc7489fa05fe16d614f5b (diff) | |
| download | zcatch-e799504cb2655bb3aa3a25c2a69ddc80558f9e99.tar.gz zcatch-e799504cb2655bb3aa3a25c2a69ddc80558f9e99.zip | |
reworked the catching, counting and color system
Diffstat (limited to 'src')
| -rw-r--r-- | src/game/server/gamecontext.cpp | 91 | ||||
| -rw-r--r-- | src/game/server/gamemodes/zcatch.cpp | 95 | ||||
| -rw-r--r-- | src/game/server/gamemodes/zcatch.h | 2 | ||||
| -rw-r--r-- | src/game/server/player.cpp | 68 | ||||
| -rw-r--r-- | src/game/server/player.h | 22 |
5 files changed, 155 insertions, 123 deletions
diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index ba08cebb..6f983855 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -459,7 +459,7 @@ void CGameContext::OnTick() /* zCatch - Allow voting from players in spectators (needed or the last 2 players ingame can kick the whole server), * but deny votes from players who are explicit in spec */ - if(!m_apPlayers[i] || m_apPlayers[i]->m_SpecExplicit == 1 || aVoteChecked[i]) // don't count in votes by spectators + if(!m_apPlayers[i] || m_apPlayers[i]->m_SpecExplicit || aVoteChecked[i]) // don't count in votes by spectators continue; int ActVote = m_apPlayers[i]->m_Vote; @@ -545,88 +545,56 @@ void CGameContext::OnClientPredictedInput(int ClientID, void *pInput) void CGameContext::OnClientEnter(int ClientID) { + CPlayer *p = m_apPlayers[ClientID]; //world.insert_entity(&players[client_id]); - m_apPlayers[ClientID]->Respawn(); + p->Respawn(); /* begin zCatch */ - int LeaderID = -1; - int StartTeam = m_pController->ClampTeam(1); + CPlayer *leader = NULL; - int Num = 0; - + int NumReady = 0; for(int i = 0; i < MAX_CLIENTS; i++) { if(IsClientReady(i)) - Num++; + NumReady++; } - if(Num < 3) - m_pController->EndRound(); + // sv_allow_join 1: Allow new players to join the game without need to wait for the next round if(g_Config.m_SvAllowJoin == 1) { - m_apPlayers[ClientID]->m_CaughtBy = CPlayer::ZCATCH_NOT_CAUGHT; - m_apPlayers[ClientID]->m_SpecExplicit = (Num < 3) ? 0 : 1; - StartTeam = (Num < 3) ? m_pController->ClampTeam(1) : TEAM_SPECTATORS; + p->m_SpecExplicit = (NumReady > 2); + p->SetTeamDirect(p->m_SpecExplicit ? TEAM_SPECTATORS : m_pController->ClampTeam(1)); SendBroadcast("You can join the game", ClientID); } + // sv_allow_join 2: The player will join when the player with the most kills dies else if(g_Config.m_SvAllowJoin == 2) { - int Num2 = 0, PrevNum = 0; - for(int i = 0; i < MAX_CLIENTS; i++) - { - if(m_apPlayers[i]) - { - Num2 = 0; - for(int j = 0; j < MAX_CLIENTS; j++) - if(m_apPlayers[j] && m_apPlayers[j]->m_CaughtBy == i) - Num2++; - - if(Num2 > PrevNum) - { - LeaderID = i; - PrevNum = Num2; - } - } - } - - if(LeaderID > -1) - { - m_apPlayers[ClientID]->m_CaughtBy = LeaderID; - m_apPlayers[ClientID]->m_SpecExplicit = 0; - m_apPlayers[ClientID]->m_SpectatorID = LeaderID; - StartTeam = TEAM_SPECTATORS; - } + if(m_apPlayers[i] && ((leader && m_apPlayers[i]->m_zCatchNumKillsInARow > leader->m_zCatchNumKillsInARow) || (!leader && m_apPlayers[i]->m_zCatchNumKillsInARow))) + leader = m_apPlayers[i]; + if(leader) + leader->AddZCatchVictim(ClientID); else - { - m_apPlayers[ClientID]->m_CaughtBy = CPlayer::ZCATCH_NOT_CAUGHT; - m_apPlayers[ClientID]->m_SpecExplicit = 0; - } + p->m_SpecExplicit = false; } - else - StartTeam = m_pController->GetAutoTeam(ClientID); - - m_apPlayers[ClientID]->SetTeamDirect(StartTeam); /* end zCatch */ char aBuf[512]; - str_format(aBuf, sizeof(aBuf), "'%s' entered and joined the %s", Server()->ClientName(ClientID), m_pController->GetTeamName(m_apPlayers[ClientID]->GetTeam())); + str_format(aBuf, sizeof(aBuf), "'%s' entered and joined the %s", Server()->ClientName(ClientID), m_pController->GetTeamName(p->GetTeam())); SendChat(-1, CGameContext::CHAT_ALL, aBuf); - str_format(aBuf, sizeof(aBuf), "team_join player='%d:%s' team=%d", ClientID, Server()->ClientName(ClientID), m_apPlayers[ClientID]->GetTeam()); + str_format(aBuf, sizeof(aBuf), "team_join player='%d:%s' team=%d", ClientID, Server()->ClientName(ClientID), p->GetTeam()); Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); m_VoteUpdate = true; /* zCatch begin */ - SendChatTarget(ClientID, "Welcome to zCatch!"); - SendChatTarget(ClientID, "type /cmdlist to get all commands"); - SendChatTarget(ClientID, "type /help for instructions"); - if(g_Config.m_SvAllowJoin == 2 && LeaderID > -1) + SendChatTarget(ClientID, "Welcome to zCatch! Type /info for more."); + if(g_Config.m_SvAllowJoin == 2 && leader) { char buf[128]; - str_format(buf, sizeof(buf), "You will join the game when %s dies", Server()->ClientName(LeaderID)); + str_format(buf, sizeof(buf), "You will join the game when '%s' dies", Server()->ClientName(leader->GetCID())); SendChatTarget(ClientID, buf); } /* zCatch end */ @@ -663,6 +631,9 @@ void CGameContext::OnClientConnected(int ClientID) void CGameContext::OnClientDrop(int ClientID, const char *pReason) { + if(m_apPlayers[ClientID]->m_CaughtBy > CPlayer::ZCATCH_NOT_CAUGHT) + m_apPlayers[m_apPlayers[ClientID]->m_CaughtBy]->ReleaseZCatchVictim(ClientID); + AbortVoteKickOnDisconnect(ClientID); m_apPlayers[ClientID]->OnDisconnect(pReason); delete m_apPlayers[ClientID]; @@ -763,7 +734,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) int64 Now = Server()->Tick(); pPlayer->m_LastVoteTry = Now; // zCatch - Only People who are explicit in Spectators can't vote! - if(pPlayer->m_SpecExplicit == 1) //zCatch + if(pPlayer->m_SpecExplicit) //zCatch { SendChatTarget(ClientID, "Spectators aren't allowed to start a vote."); return; @@ -840,7 +811,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) { int PlayerNum = 0; for(int i = 0; i < MAX_CLIENTS; ++i) - if(m_apPlayers[i] && m_apPlayers[i]->m_SpecExplicit != 1) // zCatch - Count all Players who are not explicit in spectator + if(m_apPlayers[i] && !m_apPlayers[i]->m_SpecExplicit) // zCatch - Count all Players who are not explicit in spectator ++PlayerNum; if(PlayerNum < g_Config.m_SvVoteKickMin) @@ -1149,11 +1120,21 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) { SendChatTarget(ClientID, "You can't kill yourself while you're frozen."); } + else if(pPlayer->HasZCatchVictims()) + { + int lastVictim = pPlayer->LastZCatchVictim(); + pPlayer->ReleaseZCatchVictim(CPlayer::ZCATCH_RELEASE_ALL, 1); + char aBuf[128]; + str_format(aBuf, sizeof(aBuf), "You released '%s'. (%d left)", Server()->ClientName(lastVictim), pPlayer->m_zCatchNumVictims); + SendChatTarget(ClientID, aBuf); + str_format(aBuf, sizeof(aBuf), "You were released by '%s'.", Server()->ClientName(ClientID)); + SendChatTarget(lastVictim, aBuf); + return; + } else { pPlayer->m_LastKill = Server()->Tick(); pPlayer->KillCharacter(WEAPON_SELF); - pPlayer->m_Deaths++; return; } pPlayer->m_LastKillTry = Server()->Tick(); diff --git a/src/game/server/gamemodes/zcatch.cpp b/src/game/server/gamemodes/zcatch.cpp index bb6f9ec3..dadfd19b 100644 --- a/src/game/server/gamemodes/zcatch.cpp +++ b/src/game/server/gamemodes/zcatch.cpp @@ -20,8 +20,6 @@ CGameController_zCatch::CGameController_zCatch(class CGameContext *pGameServer) void CGameController_zCatch::Tick() { IGameController::Tick(); - if(m_GameOverTick == -1) - CalcPlayerColor(); if(m_OldMode != g_Config.m_SvMode) { @@ -43,23 +41,31 @@ void CGameController_zCatch::DoWincheck() Players++; if(GameServer()->m_apPlayers[i]->GetTeam() == TEAM_SPECTATORS) Players_Spec++; - if(GameServer()->m_apPlayers[i]->m_SpecExplicit == 1) + if(GameServer()->m_apPlayers[i]->m_SpecExplicit) Players_SpecExplicit++; } } + int Players_Ingame = Players - Players_SpecExplicit; - if(Players == 1) + if(Players_Ingame <= 1) { //Do nothing } - else if((Players - Players_Spec == 1) && (Players != Players_Spec) && (Players - Players_SpecExplicit != 1)) + else if((Players - Players_Spec) == 1) { for(int i = 0; i < MAX_CLIENTS; i++) { if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS) + { GameServer()->m_apPlayers[i]->m_Score += g_Config.m_SvBonus; + if(Players_Ingame <= 4) + GameServer()->m_apPlayers[i]->ReleaseZCatchVictim(CPlayer::ZCATCH_RELEASE_ALL); + } } - EndRound(); + if(Players_Ingame <= 4) + GameServer()->SendChatTarget(-1, "Too less players to end round. All players have been released."); + else + EndRound(); } IGameController::DoWincheck(); //do also usual wincheck @@ -71,66 +77,50 @@ int CGameController_zCatch::OnCharacterDeath(class CCharacter *pVictim, class CP if(!pKiller) return 0; - int VictimID = pVictim->GetPlayer()->GetCID(); - - if(pKiller != pVictim->GetPlayer()) + CPlayer *victim = pVictim->GetPlayer(); + if(pKiller != victim) { - pKiller->m_Kills++; - pVictim->GetPlayer()->m_Deaths++; - - pKiller->m_Score++; - + pKiller->m_Score += victim->m_zCatchNumKillsInARow + 1; + ++pKiller->m_Kills; + ++victim->m_Deaths; /* Check if the killer is already killed and in spectator (victim may died through wallshot) */ if(pKiller->GetTeam() != TEAM_SPECTATORS) { - pVictim->GetPlayer()->m_CaughtBy = pKiller->GetCID(); - pVictim->GetPlayer()->SetTeamDirect(TEAM_SPECTATORS); - - pVictim->GetPlayer()->m_SpectatorID = pKiller->GetCID(); // Let the victim follow his catcher - + ++pKiller->m_zCatchNumKillsInARow; + pKiller->AddZCatchVictim(victim->GetCID()); char aBuf[256]; - str_format(aBuf, sizeof(aBuf), "Caught by \"%s\". You will join the game automatically when \"%s\" dies.", Server()->ClientName(pKiller->GetCID()), Server()->ClientName(pKiller->GetCID())); - GameServer()->SendChatTarget(VictimID, aBuf); + str_format(aBuf, sizeof(aBuf), "You are caught until '%s' dies.", Server()->ClientName(pKiller->GetCID())); + GameServer()->SendChatTarget(victim->GetCID(), aBuf); } } else { - //Punish selfkill/death + // selfkill/death if(WeaponID == WEAPON_SELF || WeaponID == WEAPON_WORLD) - pVictim->GetPlayer()->m_Score -= g_Config.m_SvKillPenalty; - } - - for(int i = 0; i < MAX_CLIENTS; i++) - { - if(GameServer()->m_apPlayers[i]) { - if(GameServer()->m_apPlayers[i]->m_CaughtBy == VictimID) - { - GameServer()->m_apPlayers[i]->m_CaughtBy = CPlayer::ZCATCH_NOT_CAUGHT; - GameServer()->m_apPlayers[i]->SetTeamDirect(GameServer()->m_pController->ClampTeam(1)); - - if(pKiller != pVictim->GetPlayer()) - pKiller->m_Score++; - } + victim->m_Score -= g_Config.m_SvKillPenalty; + ++victim->m_Deaths; } } + // release all the victim's victims + victim->ReleaseZCatchVictim(CPlayer::ZCATCH_RELEASE_ALL); + victim->m_zCatchNumKillsInARow = 0; + // Update colors - OnPlayerInfoChange(pVictim->GetPlayer()); + OnPlayerInfoChange(victim); + OnPlayerInfoChange(pKiller); return 0; } void CGameController_zCatch::OnPlayerInfoChange(class CPlayer *pP) { - if(g_Config.m_SvColorIndicator) + if(g_Config.m_SvColorIndicator && pP->m_zCatchNumKillsInARow <= 20) { - int Num = 161; - for(int i = 0; i < MAX_CLIENTS; i++) - if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_CaughtBy == pP->GetCID()) - Num -= 10; + int Num = max(0, 160 - pP->m_zCatchNumKillsInARow * 10); pP->m_TeeInfos.m_ColorBody = Num * 0x010000 + 0xff00; - pP->m_TeeInfos.m_ColorFeet = Num * 0x010000 + 0xff00; + pP->m_TeeInfos.m_ColorFeet = pP->m_zCatchNumKillsInARow == 20 ? 0x40ff00 : pP->m_TeeInfos.m_ColorBody; pP->m_TeeInfos.m_UseCustomColor = 1; } } @@ -143,7 +133,6 @@ void CGameController_zCatch::StartRound() { if(GameServer()->m_apPlayers[i]) { - GameServer()->m_apPlayers[i]->m_CaughtBy = CPlayer::ZCATCH_NOT_CAUGHT; GameServer()->m_apPlayers[i]->m_Kills = 0; GameServer()->m_apPlayers[i]->m_Deaths = 0; GameServer()->m_apPlayers[i]->m_TicksSpec = 0; @@ -194,7 +183,7 @@ void CGameController_zCatch::EndRound() if(GameServer()->m_apPlayers[i]) { - if(GameServer()->m_apPlayers[i]->m_SpecExplicit == 0) + if(!GameServer()->m_apPlayers[i]->m_SpecExplicit) { GameServer()->m_apPlayers[i]->SetTeamDirect(GameServer()->m_pController->ClampTeam(1)); @@ -208,7 +197,9 @@ void CGameController_zCatch::EndRound() str_format(aBuf, sizeof(aBuf), "Spec: %.2f%% | Ingame: %.2f%%", (double) TimeInSpec, (double) (100.0 - TimeInSpec)); GameServer()->SendChatTarget(i, aBuf); } - GameServer()->m_apPlayers[i]->m_CaughtBy = CPlayer::ZCATCH_NOT_CAUGHT; //Set all players in server as non-caught + // release all players + GameServer()->m_apPlayers[i]->ReleaseZCatchVictim(CPlayer::ZCATCH_RELEASE_ALL); + GameServer()->m_apPlayers[i]->m_zCatchNumKillsInARow = 0; } } } @@ -239,15 +230,3 @@ bool CGameController_zCatch::OnEntity(int Index, vec2 Pos) return false; } - -void CGameController_zCatch::CalcPlayerColor() -{ - for(int i = 0; i < MAX_CLIENTS; i++) - { - CPlayer *pP = GameServer()->m_apPlayers[i]; - if(!pP) - continue; - if(pP->GetTeam() != TEAM_SPECTATORS) - OnPlayerInfoChange(pP); - } -} diff --git a/src/game/server/gamemodes/zcatch.h b/src/game/server/gamemodes/zcatch.h index af776644..4f110a03 100644 --- a/src/game/server/gamemodes/zcatch.h +++ b/src/game/server/gamemodes/zcatch.h @@ -23,8 +23,6 @@ public: virtual bool OnEntity(int Index, vec2 Pos); virtual bool CanChangeTeam(CPlayer *pPlayer, int JoinTeam); virtual void EndRound(); - - void CalcPlayerColor(); }; #endif diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index 7e07c07f..d3e00f9c 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -23,18 +23,25 @@ CPlayer::CPlayer(CGameContext *pGameServer, int ClientID, int Team) m_TeamChangeTick = Server()->Tick(); //zCatch - m_CaughtBy = -1; - m_SpecExplicit = 0; + m_CaughtBy = ZCATCH_NOT_CAUGHT; + m_SpecExplicit = false; m_Kills = 0; m_Deaths = 0; m_LastKillTry = Server()->Tick(); m_TicksSpec = 0; m_TicksIngame = 0; m_ChatTicks = 0; + + // zCatch/TeeVi + m_ZCatchVictims = NULL; + m_zCatchNumVictims = 0; + m_zCatchNumKillsInARow = 0; } CPlayer::~CPlayer() { + ReleaseZCatchVictim(ZCATCH_RELEASE_ALL); + delete m_pCharacter; m_pCharacter = 0; } @@ -295,8 +302,6 @@ void CPlayer::SetTeam(int Team, bool DoChatMsg) str_format(aBuf, sizeof(aBuf), "team_join player='%d:%s' m_Team=%d", m_ClientID, Server()->ClientName(m_ClientID), m_Team); GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); - GameServer()->m_pController->OnPlayerInfoChange(GameServer()->m_apPlayers[m_ClientID]); - if(Team == TEAM_SPECTATORS) { // update spectator modes @@ -305,10 +310,10 @@ 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; } - m_SpecExplicit = 1; + m_SpecExplicit = true; } else - m_SpecExplicit = 0; + m_SpecExplicit = false; } void CPlayer::SetTeamDirect(int Team) @@ -377,3 +382,54 @@ int CPlayer::Anticamper() } return 0; } + +// catch another player +void CPlayer::AddZCatchVictim(int ClientID) +{ + CPlayer *victim = GameServer()->m_apPlayers[ClientID]; + if(victim) + { + // add to list of victims + CZCatchVictim *v = new CZCatchVictim; + v->ClientID = ClientID; + v->prev = m_ZCatchVictims; + m_ZCatchVictims = v; + ++m_zCatchNumVictims; + // set victim's status + victim->m_CaughtBy = m_ClientID; + victim->m_SpecExplicit = false; + victim->SetTeamDirect(TEAM_SPECTATORS); + victim->m_SpectatorID = m_ClientID; + } +} + +// release one or more of the victims +void CPlayer::ReleaseZCatchVictim(int ClientID, int limit) +{ + CZCatchVictim **v = &m_ZCatchVictims; + CZCatchVictim *tmp; + CPlayer *victim; + int count = 0; + while(*v != NULL) + { + if(ClientID == ZCATCH_RELEASE_ALL || (*v)->ClientID == ClientID) + { + victim = GameServer()->m_apPlayers[(*v)->ClientID]; + if(victim) + { + victim->m_CaughtBy = ZCATCH_NOT_CAUGHT; + victim->SetTeamDirect(GameServer()->m_pController->ClampTeam(1)); + victim->m_SpectatorID = SPEC_FREEVIEW; + } + // delete from list + tmp = (*v)->prev; + delete *v; + *v = tmp; + --m_zCatchNumVictims; + if (limit && ++count >= limit) + return; + } + else + v = &(*v)->prev; + } +} diff --git a/src/game/server/player.h b/src/game/server/player.h index a19209a8..51deaa5e 100644 --- a/src/game/server/player.h +++ b/src/game/server/player.h @@ -98,9 +98,8 @@ public: } m_Latency; //zCatch: - enum { ZCATCH_NOT_CAUGHT = -1 }; int m_CaughtBy; - int m_SpecExplicit; + bool m_SpecExplicit; int m_Deaths; int m_Kills; int m_LastKillTry; @@ -114,6 +113,25 @@ public: int m_CampTick; vec2 m_CampPos; + // zCatch/TeeVi + enum + { + ZCATCH_NOT_CAUGHT = -1, + ZCATCH_RELEASE_ALL = -1 + }; + struct CZCatchVictim + { + int ClientID; + CZCatchVictim *prev; + }; + CZCatchVictim *m_ZCatchVictims; + int m_zCatchNumVictims; + int m_zCatchNumKillsInARow; + void AddZCatchVictim(int ClientID); + void ReleaseZCatchVictim(int ClientID, int limit = 0); + bool HasZCatchVictims() { return (m_ZCatchVictims != NULL); } + int LastZCatchVictim() { return HasZCatchVictims() ? m_ZCatchVictims->ClientID : -1; } + private: CCharacter *m_pCharacter; CGameContext *m_pGameServer; |