diff options
Diffstat (limited to 'src/game/server/gamemodes')
| -rw-r--r-- | src/game/server/gamemodes/ctf.cpp | 41 | ||||
| -rw-r--r-- | src/game/server/gamemodes/ctf.h | 1 | ||||
| -rw-r--r-- | src/game/server/gamemodes/dm.cpp | 1 | ||||
| -rw-r--r-- | src/game/server/gamemodes/mod.cpp | 2 | ||||
| -rw-r--r-- | src/game/server/gamemodes/tdm.cpp | 1 | ||||
| -rw-r--r-- | src/game/server/gamemodes/zcatch.cpp | 230 | ||||
| -rw-r--r-- | src/game/server/gamemodes/zcatch.hpp | 33 |
7 files changed, 300 insertions, 9 deletions
diff --git a/src/game/server/gamemodes/ctf.cpp b/src/game/server/gamemodes/ctf.cpp index b1d3d2fa..66cc4c2c 100644 --- a/src/game/server/gamemodes/ctf.cpp +++ b/src/game/server/gamemodes/ctf.cpp @@ -1,6 +1,9 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ +#include <engine/shared/config.h> + #include <game/mapitems.h> + #include <game/server/entities/character.h> #include <game/server/entities/flag.h> #include <game/server/player.h> @@ -63,6 +66,30 @@ int CGameControllerCTF::OnCharacterDeath(class CCharacter *pVictim, class CPlaye return HadFlag; } +void CGameControllerCTF::DoWincheck() +{ + if(m_GameOverTick == -1 && !m_Warmup) + { + // check score win condition + if((g_Config.m_SvScorelimit > 0 && (m_aTeamscore[TEAM_RED] >= g_Config.m_SvScorelimit || m_aTeamscore[TEAM_BLUE] >= g_Config.m_SvScorelimit)) || + (g_Config.m_SvTimelimit > 0 && (Server()->Tick()-m_RoundStartTick) >= g_Config.m_SvTimelimit*Server()->TickSpeed()*60)) + { + if(m_SuddenDeath) + { + if(m_aTeamscore[TEAM_RED]/100 != m_aTeamscore[TEAM_BLUE]/100) + EndRound(); + } + else + { + if(m_aTeamscore[TEAM_RED] != m_aTeamscore[TEAM_BLUE]) + EndRound(); + else + m_SuddenDeath = 1; + } + } + } +} + bool CGameControllerCTF::CanBeMovedOnBalance(int ClientID) { CCharacter* Character = GameServer()->m_apPlayers[ClientID]->GetCharacter(); @@ -117,7 +144,8 @@ void CGameControllerCTF::Tick() { IGameController::Tick(); - DoTeamScoreWincheck(); + if(GameServer()->m_World.m_ResetRequested || GameServer()->m_World.m_Paused) + return; for(int fi = 0; fi < 2; fi++) { @@ -220,13 +248,16 @@ void CGameControllerCTF::Tick() for(int c = 0; c < MAX_CLIENTS; c++) { - if(!GameServer()->m_apPlayers[c]) + CPlayer *pPlayer = GameServer()->m_apPlayers[c]; + if(!pPlayer) continue; - if(GameServer()->m_apPlayers[c]->GetTeam() == fi) - GameServer()->CreateSoundGlobal(SOUND_CTF_GRAB_EN, GameServer()->m_apPlayers[c]->GetCID()); + if(pPlayer->GetTeam() == TEAM_SPECTATORS && pPlayer->m_SpectatorID != SPEC_FREEVIEW && GameServer()->m_apPlayers[pPlayer->m_SpectatorID] && GameServer()->m_apPlayers[pPlayer->m_SpectatorID]->GetTeam() == fi) + GameServer()->CreateSoundGlobal(SOUND_CTF_GRAB_EN, c); + else if(pPlayer->GetTeam() == fi) + GameServer()->CreateSoundGlobal(SOUND_CTF_GRAB_EN, c); else - GameServer()->CreateSoundGlobal(SOUND_CTF_GRAB_PL, GameServer()->m_apPlayers[c]->GetCID()); + GameServer()->CreateSoundGlobal(SOUND_CTF_GRAB_PL, c); } break; } diff --git a/src/game/server/gamemodes/ctf.h b/src/game/server/gamemodes/ctf.h index 44bd9e8e..72747ed7 100644 --- a/src/game/server/gamemodes/ctf.h +++ b/src/game/server/gamemodes/ctf.h @@ -11,6 +11,7 @@ public: class CFlag *m_apFlags[2]; CGameControllerCTF(class CGameContext *pGameServer); + virtual void DoWincheck(); virtual bool CanBeMovedOnBalance(int ClientID); virtual void Snap(int SnappingClient); virtual void Tick(); diff --git a/src/game/server/gamemodes/dm.cpp b/src/game/server/gamemodes/dm.cpp index d2b69b43..bdca4c9a 100644 --- a/src/game/server/gamemodes/dm.cpp +++ b/src/game/server/gamemodes/dm.cpp @@ -11,6 +11,5 @@ CGameControllerDM::CGameControllerDM(class CGameContext *pGameServer) void CGameControllerDM::Tick() { - DoPlayerScoreWincheck(); IGameController::Tick(); } diff --git a/src/game/server/gamemodes/mod.cpp b/src/game/server/gamemodes/mod.cpp index 127be2bc..eb8fd7c8 100644 --- a/src/game/server/gamemodes/mod.cpp +++ b/src/game/server/gamemodes/mod.cpp @@ -15,8 +15,6 @@ CGameControllerMOD::CGameControllerMOD(class CGameContext *pGameServer) void CGameControllerMOD::Tick() { // this is the main part of the gamemode, this function is run every tick - DoPlayerScoreWincheck(); // checks for winners, no teams version - //DoTeamScoreWincheck(); // checks for winners, two teams version IGameController::Tick(); } diff --git a/src/game/server/gamemodes/tdm.cpp b/src/game/server/gamemodes/tdm.cpp index 54e645b3..50ecd93e 100644 --- a/src/game/server/gamemodes/tdm.cpp +++ b/src/game/server/gamemodes/tdm.cpp @@ -48,6 +48,5 @@ void CGameControllerTDM::Snap(int SnappingClient) void CGameControllerTDM::Tick() { - DoTeamScoreWincheck(); IGameController::Tick(); } diff --git a/src/game/server/gamemodes/zcatch.cpp b/src/game/server/gamemodes/zcatch.cpp new file mode 100644 index 00000000..eac8a4d3 --- /dev/null +++ b/src/game/server/gamemodes/zcatch.cpp @@ -0,0 +1,230 @@ +/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ +/* If you are missing that file, acquire a complete release at teeworlds.com. */ +/* zCatch by erd and Teetime */ + +#include <engine/shared/config.h> +#include <game/server/gamecontext.h> +#include "zcatch.hpp" + +CGameController_zCatch::CGameController_zCatch(class CGameContext *pGameServer) +: IGameController(pGameServer) +{ + m_pGameType = "zCatch"; + m_OldMode = g_Config.m_SvMode; +} + +void CGameController_zCatch::Tick() +{ + DoWincheck(); + IGameController::Tick(); + + if(m_OldMode != g_Config.m_SvMode) + { + Server()->MapReload(); + m_OldMode = g_Config.m_SvMode; + } +} + +bool CGameController_zCatch::IsZCatch() +{ + return true; +} + +void CGameController_zCatch::DoWincheck() +{ + int Players = 0, Players_Spec = 0, Players_SpecExplicit = 0; + + for(int i = 0; i < MAX_CLIENTS; i++) + { + if(GameServer()->m_apPlayers[i]) + { + Players++; + if(GameServer()->m_apPlayers[i]->GetTeam() == TEAM_SPECTATORS) + Players_Spec++; + if(GameServer()->m_apPlayers[i]->m_SpecExplicit == 1) + Players_SpecExplicit++; + } + } + + if(Players == 1) + { + //Do nothing + } + else if((Players - Players_Spec == 1) && (Players != Players_Spec) && (Players - Players_SpecExplicit != 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; + } + EndRound(); + } + + IGameController::DoWincheck(); //do also usual wincheck +} + +int CGameController_zCatch::OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int WeaponID) +{ + int VictimID = pVictim->GetPlayer()->GetCID(); + char buf[256]; + if(pKiller != pVictim->GetPlayer()) + { + pKiller->m_Kills++; + pVictim->GetPlayer()->m_Deaths++; + + pKiller->m_Score++; + pVictim->GetPlayer()->m_Score--; + + /* Check if the killer is already killed and in spectator (victim may died through wallshot) */ + if(pKiller->GetTeam() != TEAM_SPECTATORS) + { + pVictim->GetPlayer()->m_CatchedBy = pKiller->GetCID(); + pVictim->GetPlayer()->SetTeamDirect(TEAM_SPECTATORS); + + if(pVictim->GetPlayer()->m_PlayerWantToFollowCatcher) + pVictim->GetPlayer()->m_SpectatorID = pKiller->GetCID(); // Let the victim follow his catcher + + str_format(buf, sizeof(buf), "Caught by \"%s\". You will join the game automatically when \"%s\" dies.", Server()->ClientName(pKiller->GetCID()), Server()->ClientName(pKiller->GetCID())); + GameServer()->SendChatTarget(VictimID, buf); + } + } + else + { + //Punish selfkill/death + if(WeaponID == WEAPON_SELF || WeaponID == WEAPON_WORLD) + pVictim->GetPlayer()->m_Score -= 15; + } + + for(int i=0; i < MAX_CLIENTS; i++) + { + if(GameServer()->m_apPlayers[i]) + { + if(GameServer()->m_apPlayers[i]->m_CatchedBy == VictimID) + { + GameServer()->m_apPlayers[i]->m_CatchedBy = ZCATCH_NOT_CATCHED; + GameServer()->m_apPlayers[i]->SetTeamDirect(GameServer()->m_pController->ClampTeam(1)); + + if(pKiller != pVictim->GetPlayer()) + pKiller->m_Score++; + } + } + } + + // Update color of the killer + OnPlayerInfoChange(pKiller); + + return 0; +} + +void CGameController_zCatch::OnPlayerInfoChange(class CPlayer *pP) +{ + if(g_Config.m_SvColorIndicator) + { + int Num = 161; + for(int i = 0; i < MAX_CLIENTS; i++) + if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_CatchedBy == pP->GetCID()) + Num -= 10; + pP->m_TeeInfos.m_ColorBody = Num * 0x010000 + 0xff00; + pP->m_TeeInfos.m_ColorFeet = Num * 0x010000 + 0xff00; + pP->m_TeeInfos.m_UseCustomColor = 1; + } +} + +void CGameController_zCatch::StartRound() +{ + ResetGame(); + + m_RoundStartTick = Server()->Tick(); + m_SuddenDeath = 0; + m_GameOverTick = -1; + GameServer()->m_World.m_Paused = false; + m_aTeamscore[TEAM_RED] = 0; + m_aTeamscore[TEAM_BLUE] = 0; + m_UnbalancedTick = -1; + m_ForceBalanced = false; + for(int i=0; i<MAX_CLIENTS; i++) + { + if(GameServer()->m_apPlayers[i]) + { + GameServer()->m_apPlayers[i]->m_CatchedBy = ZCATCH_NOT_CATCHED; + GameServer()->m_apPlayers[i]->m_Kills = 0; + GameServer()->m_apPlayers[i]->m_Deaths = 0; + GameServer()->m_apPlayers[i]->m_TicksSpec = 0; + GameServer()->m_apPlayers[i]->m_TicksIngame = 0; + } + } + char aBufMsg[256]; + str_format(aBufMsg, sizeof(aBufMsg), "start round type='%s' teamplay='%d'", m_pGameType, m_GameFlags&GAMEFLAG_TEAMS); + GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBufMsg); +} + +void CGameController_zCatch::OnCharacterSpawn(class CCharacter *pChr) +{ + // default health and armor + pChr->IncreaseHealth(10); + if(g_Config.m_SvMode == 2) + pChr->IncreaseArmor(10); + // give default weapons + switch(g_Config.m_SvMode) + { + case 0: + pChr->GiveWeapon(WEAPON_HAMMER, -1); + pChr->GiveWeapon(WEAPON_GUN, 10); + break; + case 1: + pChr->GiveWeapon(WEAPON_RIFLE, -1); + break; + case 2: + pChr->GiveWeapon(WEAPON_HAMMER, -1); + pChr->GiveWeapon(WEAPON_GUN, -1); + pChr->GiveWeapon(WEAPON_GRENADE, -1); + pChr->GiveWeapon(WEAPON_SHOTGUN, -1); + pChr->GiveWeapon(WEAPON_RIFLE, -1); + break; + case 3: + pChr->GiveWeapon(WEAPON_HAMMER, -1); + break; + case 4: + pChr->GiveWeapon(WEAPON_GRENADE, -1); + break; + case 5: + pChr->GiveNinja(); + break; + } + //Update color of spawning tees + OnPlayerInfoChange(pChr->GetPlayer()); +} + +void CGameController_zCatch::EndRound() +{ + for(int i = 0; i < MAX_CLIENTS; i++) + { + if(GameServer()->m_apPlayers[i]) + { + + if(GameServer()->m_apPlayers[i]->m_SpecExplicit == 0) + { + GameServer()->m_apPlayers[i]->SetTeamDirect(GameServer()->m_pController->ClampTeam(1)); + + char abuf[128]; + str_format(abuf, sizeof(abuf), "Kills: %d | Deaths: %d", GameServer()->m_apPlayers[i]->m_Kills, GameServer()->m_apPlayers[i]->m_Deaths); + GameServer()->SendChatTarget(i, abuf); + + if(GameServer()->m_apPlayers[i]->m_TicksSpec != 0 || GameServer()->m_apPlayers[i]->m_TicksIngame != 0) + { + double TimeInSpec = (GameServer()->m_apPlayers[i]->m_TicksSpec*100.0) / (GameServer()->m_apPlayers[i]->m_TicksIngame + GameServer()->m_apPlayers[i]->m_TicksSpec); + str_format(abuf, sizeof(abuf), "Spec: %.2f%% | Ingame: %.2f%%", (double)TimeInSpec, (double)(100.0 - TimeInSpec)); + GameServer()->SendChatTarget(i, abuf); + } + GameServer()->m_apPlayers[i]->m_CatchedBy = ZCATCH_NOT_CATCHED; //Set all players in server as non-catched + } + } + } + + if(m_Warmup) // game can't end when we are running warmup + return; + + GameServer()->m_World.m_Paused = true; + m_GameOverTick = Server()->Tick(); + m_SuddenDeath = 0; +} diff --git a/src/game/server/gamemodes/zcatch.hpp b/src/game/server/gamemodes/zcatch.hpp new file mode 100644 index 00000000..58e43f61 --- /dev/null +++ b/src/game/server/gamemodes/zcatch.hpp @@ -0,0 +1,33 @@ +/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ +/* If you are missing that file, acquire a complete release at teeworlds.com. */ +/* zCatch by erd and Teetime */ + +#ifndef GAME_SERVER_GAMEMODES_ZCATCH_H +#define GAME_SERVER_GAMEMODES_ZCATCH_H + +#include <game/server/gamecontroller.h> + +class CGameController_zCatch : public IGameController +{ + private: + int m_OldMode; + + public: + CGameController_zCatch(class CGameContext *pGameServer); + virtual void Tick(); + virtual void DoWincheck(); + virtual bool IsZCatch(); + + enum + { + ZCATCH_NOT_CATCHED = -1, + }; + + virtual int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int WeaponID); + virtual void StartRound(); + virtual void OnCharacterSpawn(class CCharacter *pChr); + virtual void OnPlayerInfoChange(class CPlayer *pP); + virtual void EndRound(); +}; + +#endif |