diff --git a/datasrc/network.py b/datasrc/network.py index 2489b1316..3b1afa779 100644 --- a/datasrc/network.py +++ b/datasrc/network.py @@ -3,6 +3,7 @@ from datatypes import * Emotes = ["NORMAL", "PAIN", "HAPPY", "SURPRISE", "ANGRY", "BLINK"] PlayerFlags = ["PLAYING", "IN_MENU", "CHATTING", "SCOREBOARD"] GameFlags = ["TEAMS", "FLAGS"] +GameStateFlags = ["GAMEOVER", "SUDDENDEATH", "PAUSED"] Emoticons = [str(x) for x in range(0,16)] @@ -21,7 +22,10 @@ enum { TEAM_SPECTATORS=-1, TEAM_RED, - TEAM_BLUE + TEAM_BLUE, + + FLAG_ATSTAND=-2, + FLAG_TAKEN, }; ''' @@ -37,8 +41,9 @@ Enums = [ ] Flags = [ - Enum("PLAYERFLAG", PlayerFlags), - Flags("GAMEFLAG", GameFlags) + Flags("PLAYERFLAG", PlayerFlags), + Flags("GAMEFLAG", GameFlags), + Flags("GAMESTATEFLAG", GameStateFlags) ] Objects = [ @@ -90,28 +95,28 @@ Objects = [ NetIntAny("m_X"), NetIntAny("m_Y"), - NetIntRange("m_Team", 'TEAM_RED', 'TEAM_BLUE'), - NetIntRange("m_CarriedBy", -2, 'MAX_CLIENTS-1') + NetIntRange("m_Team", 'TEAM_RED', 'TEAM_BLUE') ]), - NetObject("Game", [ - NetIntRange("m_Flags", 0, 256), + NetObject("GameInfo", [ + NetIntRange("m_GameFlags", 0, 256), + NetIntRange("m_GameStateFlags", 0, 256), NetTick("m_RoundStartTick"), - - NetIntRange("m_GameOver", 0, 1), - NetIntRange("m_SuddenDeath", 0, 1), - NetIntRange("m_Paused", 0, 1), + NetIntRange("m_WarmupTimer", 0, 'max_int'), NetIntRange("m_ScoreLimit", 0, 'max_int'), NetIntRange("m_TimeLimit", 0, 'max_int'), - NetIntRange("m_Warmup", 0, 'max_int'), - NetIntRange("m_RoundNum", 0, 'max_int'), NetIntRange("m_RoundCurrent", 0, 'max_int'), + ]), + NetObject("GameData", [ NetIntAny("m_TeamscoreRed"), NetIntAny("m_TeamscoreBlue"), + + NetIntRange("m_FlagCarrierRed", 'FLAG_ATSTAND', 'MAX_CLIENTS-1'), + NetIntRange("m_FlagCarrierBlue", 'FLAG_ATSTAND', 'MAX_CLIENTS-1'), ]), NetObject("CharacterCore", [ diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp index 79b9720e2..e90e8579c 100644 --- a/src/game/client/components/chat.cpp +++ b/src/game/client/components/chat.cpp @@ -235,7 +235,7 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine) if(m_pClient->m_aClients[ClientID].m_Team == TEAM_SPECTATORS) m_aLines[m_CurrentLine].m_NameColor = TEAM_SPECTATORS; - if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) + if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS) { if(m_pClient->m_aClients[ClientID].m_Team == TEAM_RED) m_aLines[m_CurrentLine].m_NameColor = TEAM_RED; diff --git a/src/game/client/components/controls.cpp b/src/game/client/components/controls.cpp index 479bba22a..df9a6bf0d 100644 --- a/src/game/client/components/controls.cpp +++ b/src/game/client/components/controls.cpp @@ -199,13 +199,13 @@ int CControls::SnapInput(int *pData) void CControls::OnRender() { // update target pos - if(m_pClient->m_Snap.m_pGameobj && !(m_pClient->m_Snap.m_pGameobj->m_Paused || m_pClient->m_Snap.m_Spectate)) + if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED || m_pClient->m_Snap.m_Spectate)) m_TargetPos = m_pClient->m_LocalCharacterPos + m_MousePos; } bool CControls::OnMouseMove(float x, float y) { - if((m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Paused) || (m_pClient->m_Snap.m_Spectate && m_pClient->m_pChat->IsActive())) + if((m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED) || (m_pClient->m_Snap.m_Spectate && m_pClient->m_pChat->IsActive())) return false; m_MousePos += vec2(x, y); // TODO: ugly diff --git a/src/game/client/components/hud.cpp b/src/game/client/components/hud.cpp index b87cf650f..ca100f9d9 100644 --- a/src/game/client/components/hud.cpp +++ b/src/game/client/components/hud.cpp @@ -32,25 +32,25 @@ void CHud::RenderGameTimer() float Half = 300.0f*Graphics()->ScreenAspect()/2.0f; Graphics()->MapScreen(0, 0, 300.0f*Graphics()->ScreenAspect(), 300.0f); - if(!m_pClient->m_Snap.m_pGameobj->m_SuddenDeath) + if(!(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_SUDDENDEATH)) { char Buf[32]; int Time = 0; - if(m_pClient->m_Snap.m_pGameobj->m_TimeLimit) + if(m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit) { - Time = m_pClient->m_Snap.m_pGameobj->m_TimeLimit*60 - ((Client()->GameTick()-m_pClient->m_Snap.m_pGameobj->m_RoundStartTick)/Client()->GameTickSpeed()); + Time = m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit*60 - ((Client()->GameTick()-m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick)/Client()->GameTickSpeed()); - if(m_pClient->m_Snap.m_pGameobj->m_GameOver) + if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER) Time = 0; } else - Time = (Client()->GameTick()-m_pClient->m_Snap.m_pGameobj->m_RoundStartTick)/Client()->GameTickSpeed(); + Time = (Client()->GameTick()-m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick)/Client()->GameTickSpeed(); str_format(Buf, sizeof(Buf), "%d:%02d", Time/60, Time%60); float FontSize = 10.0f; float w = TextRender()->TextWidth(0, FontSize, Buf, -1); // last 60 sec red, last 10 sec blink - if(m_pClient->m_Snap.m_pGameobj->m_TimeLimit && Time <= 60) + if(m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit && Time <= 60) { float Alpha = Time <= 10 && (2*time_get()/time_freq()) % 2 ? 0.5f : 1.0f; TextRender()->TextColor(1.0f, 0.25f, 0.25f, Alpha); @@ -62,7 +62,7 @@ void CHud::RenderGameTimer() void CHud::RenderSuddenDeath() { - if(m_pClient->m_Snap.m_pGameobj->m_SuddenDeath) + if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_SUDDENDEATH) { float Half = 300.0f*Graphics()->ScreenAspect()/2.0f; const char *pText = Localize("Sudden Death"); @@ -75,17 +75,18 @@ void CHud::RenderSuddenDeath() void CHud::RenderScoreHud() { // render small score hud - if(!(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver)) + if(!(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)) { - int GameFlags = m_pClient->m_Snap.m_pGameobj->m_Flags; + int GameFlags = m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags; float Whole = 300*Graphics()->ScreenAspect(); - if(GameFlags&GAMEFLAG_TEAMS) + if(GameFlags&GAMEFLAG_TEAMS && m_pClient->m_Snap.m_pGameDataObj) { char aScoreTeam[2][32]; - str_format(aScoreTeam[TEAM_RED], sizeof(aScoreTeam)/2, "%d", m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed); - str_format(aScoreTeam[TEAM_BLUE], sizeof(aScoreTeam)/2, "%d", m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue); - float aScoreTeamWidth[2] = {TextRender()->TextWidth(0, 14.0f, aScoreTeam[TEAM_RED], -1), TextRender()->TextWidth(0, 14.0f, aScoreTeam[TEAM_BLUE], -1)}; + str_format(aScoreTeam[TEAM_RED], sizeof(aScoreTeam)/2, "%d", m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed); + str_format(aScoreTeam[TEAM_BLUE], sizeof(aScoreTeam)/2, "%d", m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue); + float aScoreTeamWidth[2] = { TextRender()->TextWidth(0, 14.0f, aScoreTeam[TEAM_RED], -1), TextRender()->TextWidth(0, 14.0f, aScoreTeam[TEAM_BLUE], -1) }; + int FlagCarrier[2] = { m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierRed, m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue }; float ScoreWidthMax = max(max(aScoreTeamWidth[TEAM_RED], aScoreTeamWidth[TEAM_BLUE]), TextRender()->TextWidth(0, 14.0f, "100", -1)); float Split = 3.0f; float ImageSize = GameFlags&GAMEFLAG_FLAGS ? 16.0f : Split; @@ -106,9 +107,9 @@ void CHud::RenderScoreHud() // draw score TextRender()->Text(0, Whole-ScoreWidthMax+(ScoreWidthMax-aScoreTeamWidth[t])/2-Split, 245.0f+t*20, 14.0f, aScoreTeam[t], -1); - if(GameFlags&GAMEFLAG_FLAGS && m_pClient->m_Snap.m_paFlags[t]) + if(GameFlags&GAMEFLAG_FLAGS) { - if(m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy == -2 || (m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy == -1 && ((Client()->GameTick()/10)&1))) + if(FlagCarrier[t] == FLAG_ATSTAND || (FlagCarrier[t] == FLAG_TAKEN && ((Client()->GameTick()/10)&1))) { // draw flag Graphics()->BlendNormal(); @@ -119,10 +120,10 @@ void CHud::RenderScoreHud() Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); } - else if(m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy >= 0) + else if(FlagCarrier[t] >= 0) { // draw name of the flag holder - int ID = m_pClient->m_Snap.m_paFlags[t]->m_CarriedBy%MAX_CLIENTS; + int ID = FlagCarrier[t]%MAX_CLIENTS; const char *pName = m_pClient->m_aClients[ID].m_aName; float w = TextRender()->TextWidth(0, 10.0f, pName, -1); TextRender()->Text(0, Whole-ScoreWidthMax-ImageSize-3*Split-w, 247.0f+t*20, 10.0f, pName, -1); @@ -216,16 +217,16 @@ void CHud::RenderScoreHud() void CHud::RenderWarmupTimer() { // render warmup timer - if(m_pClient->m_Snap.m_pGameobj->m_Warmup) + if(m_pClient->m_Snap.m_pGameInfoObj->m_WarmupTimer) { char Buf[256]; float FontSize = 20.0f; float w = TextRender()->TextWidth(0, FontSize, Localize("Warmup"), -1); TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 50, FontSize, Localize("Warmup"), -1); - int Seconds = m_pClient->m_Snap.m_pGameobj->m_Warmup/SERVER_TICK_SPEED; + int Seconds = m_pClient->m_Snap.m_pGameInfoObj->m_WarmupTimer/SERVER_TICK_SPEED; if(Seconds < 5) - str_format(Buf, sizeof(Buf), "%d.%d", Seconds, (m_pClient->m_Snap.m_pGameobj->m_Warmup*10/SERVER_TICK_SPEED)%10); + str_format(Buf, sizeof(Buf), "%d.%d", Seconds, (m_pClient->m_Snap.m_pGameInfoObj->m_WarmupTimer*10/SERVER_TICK_SPEED)%10); else str_format(Buf, sizeof(Buf), "%d", Seconds); w = TextRender()->TextWidth(0, FontSize, Buf, -1); @@ -268,7 +269,7 @@ void CHud::RenderTeambalanceWarning() { // render prompt about team-balance bool Flash = time_get()/(time_freq()/2)%2 == 0; - if (m_pClient->m_Snap.m_pGameobj && (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0) + if(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS) { int TeamDiff = m_pClient->m_Snap.m_aTeamSize[TEAM_RED]-m_pClient->m_Snap.m_aTeamSize[TEAM_BLUE]; if (g_Config.m_ClWarningTeambalance && (TeamDiff >= 2 || TeamDiff <= -2)) @@ -395,7 +396,7 @@ void CHud::RenderHealthAndAmmo() void CHud::OnRender() { - if(!m_pClient->m_Snap.m_pGameobj) + if(!m_pClient->m_Snap.m_pGameInfoObj) return; m_Width = 300*Graphics()->ScreenAspect(); @@ -404,7 +405,7 @@ void CHud::OnRender() if(m_pClient->m_Snap.m_pLocalInfo && m_pClient->m_Snap.m_pLocalInfo->m_Team == TEAM_SPECTATORS) Spectate = true; - if(m_pClient->m_Snap.m_pLocalCharacter && !Spectate && !(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver)) + if(m_pClient->m_Snap.m_pLocalCharacter && !Spectate && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)) RenderHealthAndAmmo(); RenderGameTimer(); diff --git a/src/game/client/components/items.cpp b/src/game/client/components/items.cpp index fe14a339a..526c94d68 100644 --- a/src/game/client/components/items.cpp +++ b/src/game/client/components/items.cpp @@ -152,7 +152,7 @@ void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCu Graphics()->QuadsEnd(); } -void CItems::RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent) +void CItems::RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent, const CNetObj_GameData *pPrevGameData, const CNetObj_GameData *pCurGameData) { float Angle = 0.0f; float Size = 42.0f; @@ -170,13 +170,20 @@ void CItems::RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent) vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pCurrent->m_X, pCurrent->m_Y), Client()->IntraGameTick()); - // make sure that the flag isn't interpolated between capture and return - if(pPrev->m_CarriedBy != pCurrent->m_CarriedBy) - Pos = vec2(pCurrent->m_X, pCurrent->m_Y); + if(pCurGameData) + { + // make sure that the flag isn't interpolated between capture and return + if(pPrevGameData && + ((pCurrent->m_Team == TEAM_RED && pPrevGameData->m_FlagCarrierRed != pCurGameData->m_FlagCarrierRed) || + (pCurrent->m_Team == TEAM_BLUE && pPrevGameData->m_FlagCarrierBlue != pCurGameData->m_FlagCarrierBlue))) + Pos = vec2(pCurrent->m_X, pCurrent->m_Y); - // make sure to use predicted position if we are the carrier - if(m_pClient->m_Snap.m_pLocalInfo && pCurrent->m_CarriedBy == m_pClient->m_Snap.m_pLocalInfo->m_ClientID) - Pos = m_pClient->m_LocalCharacterPos; + // make sure to use predicted position if we are the carrier + if(m_pClient->m_Snap.m_pLocalInfo && + ((pCurrent->m_Team == TEAM_RED && pCurGameData->m_FlagCarrierRed == m_pClient->m_Snap.m_LocalClientID) || + (pCurrent->m_Team == TEAM_BLUE && pCurGameData->m_FlagCarrierBlue == m_pClient->m_Snap.m_LocalClientID))) + Pos = m_pClient->m_LocalCharacterPos; + } IGraphics::CQuadItem QuadItem(Pos.x, Pos.y-Size*0.75f, Size, Size*2); Graphics()->QuadsDraw(&QuadItem, 1); @@ -286,7 +293,11 @@ void CItems::OnRender() { const void *pPrev = Client()->SnapFindItem(IClient::SNAP_PREV, Item.m_Type, Item.m_ID); if (pPrev) - RenderFlag((const CNetObj_Flag *)pPrev, (const CNetObj_Flag *)pData); + { + const void *pPrevGameData = Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_GAMEDATA, m_pClient->m_Snap.m_GameDataSnapID); + RenderFlag(static_cast(pPrev), static_cast(pData), + static_cast(pPrevGameData), m_pClient->m_Snap.m_pGameDataObj); + } } } diff --git a/src/game/client/components/items.h b/src/game/client/components/items.h index 2fd188eb5..177023941 100644 --- a/src/game/client/components/items.h +++ b/src/game/client/components/items.h @@ -8,7 +8,7 @@ class CItems : public CComponent { void RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemID); void RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCurrent); - void RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent); + void RenderFlag(const CNetObj_Flag *pPrev, const CNetObj_Flag *pCurrent, const CNetObj_GameData *pPrevGameData, const CNetObj_GameData *pCurGameData); void RenderLaser(const struct CNetObj_Laser *pCurrent); public: diff --git a/src/game/client/components/killmessages.cpp b/src/game/client/components/killmessages.cpp index d57d7fd39..7745bcb2b 100644 --- a/src/game/client/components/killmessages.cpp +++ b/src/game/client/components/killmessages.cpp @@ -70,7 +70,7 @@ void CKillMessages::OnRender() // render victim tee x -= 24.0f; - if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_FLAGS) + if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_FLAGS) { if(m_aKillmsgs[r].m_ModeSpecial&1) { @@ -107,7 +107,7 @@ void CKillMessages::OnRender() if(m_aKillmsgs[r].m_VictimID != m_aKillmsgs[r].m_KillerID) { - if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_FLAGS) + if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_FLAGS) { if(m_aKillmsgs[r].m_ModeSpecial&2) { diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp index ffb4bdfee..9a4ee5dcf 100644 --- a/src/game/client/components/menus_ingame.cpp +++ b/src/game/client/components/menus_ingame.cpp @@ -35,7 +35,7 @@ void CMenus::RenderGame(CUIRect MainView) if(DoButton_Menu(&s_DisconnectButton, Localize("Disconnect"), 0, &Button)) Client()->Disconnect(); - if(m_pClient->m_Snap.m_pLocalInfo && m_pClient->m_Snap.m_pGameobj) + if(m_pClient->m_Snap.m_pLocalInfo && m_pClient->m_Snap.m_pGameInfoObj) { if(m_pClient->m_Snap.m_pLocalInfo->m_Team != TEAM_SPECTATORS) { @@ -49,7 +49,7 @@ void CMenus::RenderGame(CUIRect MainView) } } - if(m_pClient->m_Snap.m_pGameobj->m_Flags & GAMEFLAG_TEAMS) + if(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS) { if(m_pClient->m_Snap.m_pLocalInfo->m_Team != TEAM_RED) { @@ -248,24 +248,27 @@ void CMenus::RenderServerInfo(CUIRect MainView) TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 32, Localize("Game info"), 250); y += 32.0f+5.0f; - mem_zero(aBuf, sizeof(aBuf)); - str_format( - aBuf, - sizeof(aBuf), - "\n\n" - "%s: %s\n" - "%s: %s\n" - "%s: %d\n" - "%s: %d\n" - "\n" - "%s: %d/%d\n", - Localize("Game type"), CurrentServerInfo.m_aGameType, - Localize("Map"), CurrentServerInfo.m_aMap, - Localize("Score limit"), m_pClient->m_Snap.m_pGameobj->m_ScoreLimit, - Localize("Time limit"), m_pClient->m_Snap.m_pGameobj->m_TimeLimit, - Localize("Players"), m_pClient->m_Snap.m_NumPlayers, CurrentServerInfo.m_MaxPlayers - ); - TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 20, aBuf, 250); + if(m_pClient->m_Snap.m_pGameInfoObj) + { + mem_zero(aBuf, sizeof(aBuf)); + str_format( + aBuf, + sizeof(aBuf), + "\n\n" + "%s: %s\n" + "%s: %s\n" + "%s: %d\n" + "%s: %d\n" + "\n" + "%s: %d/%d\n", + Localize("Game type"), CurrentServerInfo.m_aGameType, + Localize("Map"), CurrentServerInfo.m_aMap, + Localize("Score limit"), m_pClient->m_Snap.m_pGameInfoObj->m_ScoreLimit, + Localize("Time limit"), m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit, + Localize("Players"), m_pClient->m_Snap.m_NumPlayers, CurrentServerInfo.m_MaxPlayers + ); + TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 20, aBuf, 250); + } // motd Motd.HSplitTop(10.0f, 0, &Motd); diff --git a/src/game/client/components/nameplates.cpp b/src/game/client/components/nameplates.cpp index ee67eb824..5664cb4ee 100644 --- a/src/game/client/components/nameplates.cpp +++ b/src/game/client/components/nameplates.cpp @@ -33,7 +33,7 @@ void CNamePlates::RenderNameplate( float tw = TextRender()->TextWidth(0, FontSize, pName, -1); TextRender()->TextColor(1.0f, 1.0f, 1.0f, a); - if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) + if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS) { if(pPlayerInfo->m_Team == TEAM_RED) TextRender()->TextColor(1.0f, 0.5f, 0.5f, a); diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index cbbc8d99a..74a48503d 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -99,8 +99,8 @@ void CPlayers::RenderHook( // check for teamplay modes bool IsTeamplay = false; - if(m_pClient->m_Snap.m_pGameobj) - IsTeamplay = (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0; + if(m_pClient->m_Snap.m_pGameInfoObj) + IsTeamplay = (m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS) != 0; // check for ninja if (Player.m_Weapon == WEAPON_NINJA) @@ -129,7 +129,7 @@ void CPlayers::RenderHook( // use preditect players if needed if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK) { - if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver)) + if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)) { } else @@ -223,8 +223,8 @@ void CPlayers::RenderPlayer( // check for teamplay modes bool IsTeamplay = false; bool NewTick = m_pClient->m_NewTick; - if(m_pClient->m_Snap.m_pGameobj) - IsTeamplay = (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0; + if(m_pClient->m_Snap.m_pGameInfoObj) + IsTeamplay = (m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS) != 0; // check for ninja if (Player.m_Weapon == WEAPON_NINJA) @@ -284,7 +284,7 @@ void CPlayers::RenderPlayer( // use preditect players if needed if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK) { - if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver)) + if(!m_pClient->m_Snap.m_pLocalCharacter || (m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)) { } else diff --git a/src/game/client/components/scoreboard.cpp b/src/game/client/components/scoreboard.cpp index d5588c10b..a9b249ede 100644 --- a/src/game/client/components/scoreboard.cpp +++ b/src/game/client/components/scoreboard.cpp @@ -51,24 +51,24 @@ void CScoreboard::RenderGoals(float x, float y, float w) Graphics()->QuadsEnd(); // render goals - if(m_pClient->m_Snap.m_pGameobj) + if(m_pClient->m_Snap.m_pGameInfoObj) { - if(m_pClient->m_Snap.m_pGameobj->m_ScoreLimit) + if(m_pClient->m_Snap.m_pGameInfoObj->m_ScoreLimit) { char aBuf[64]; - str_format(aBuf, sizeof(aBuf), "%s: %d", Localize("Score limit"), m_pClient->m_Snap.m_pGameobj->m_ScoreLimit); + str_format(aBuf, sizeof(aBuf), "%s: %d", Localize("Score limit"), m_pClient->m_Snap.m_pGameInfoObj->m_ScoreLimit); TextRender()->Text(0, x, y, 20.0f, aBuf, -1); } - if(m_pClient->m_Snap.m_pGameobj->m_TimeLimit) + if(m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit) { char aBuf[64]; - str_format(aBuf, sizeof(aBuf), Localize("Time limit: %d min"), m_pClient->m_Snap.m_pGameobj->m_TimeLimit); + str_format(aBuf, sizeof(aBuf), Localize("Time limit: %d min"), m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit); TextRender()->Text(0, x+220.0f, y, 20.0f, aBuf, -1); } - if(m_pClient->m_Snap.m_pGameobj->m_RoundNum && m_pClient->m_Snap.m_pGameobj->m_RoundCurrent) + if(m_pClient->m_Snap.m_pGameInfoObj->m_RoundNum && m_pClient->m_Snap.m_pGameInfoObj->m_RoundCurrent) { char aBuf[64]; - str_format(aBuf, sizeof(aBuf), "%s %d/%d", Localize("Round"), m_pClient->m_Snap.m_pGameobj->m_RoundCurrent, m_pClient->m_Snap.m_pGameobj->m_RoundNum); + str_format(aBuf, sizeof(aBuf), "%s %d/%d", Localize("Round"), m_pClient->m_Snap.m_pGameInfoObj->m_RoundCurrent, m_pClient->m_Snap.m_pGameInfoObj->m_RoundNum); float tw = TextRender()->TextWidth(0, 20.0f, aBuf, -1); TextRender()->Text(0, x+w-tw-20.0f, y, 20.0f, aBuf, -1); } @@ -129,7 +129,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch // render title if(!pTitle) { - if(m_pClient->m_Snap.m_pGameobj->m_GameOver) + if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER) pTitle = Localize("Game over"); else pTitle = Localize("Score board"); @@ -138,10 +138,21 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch float tw = TextRender()->TextWidth(0, 48, pTitle, -1); TextRender()->Text(0, x+10, y, 48, pTitle, -1); - if(m_pClient->m_Snap.m_pGameobj) + if(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS) + { + if(m_pClient->m_Snap.m_pGameDataObj) + { + char aBuf[128]; + int Score = Team == TEAM_RED ? m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed : m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue; + str_format(aBuf, sizeof(aBuf), "%d", Score); + tw = TextRender()->TextWidth(0, 48, aBuf, -1); + TextRender()->Text(0, x+w-tw-30, y, 48, aBuf, -1); + } + } + else { char aBuf[128]; - int Score = Team == TEAM_RED ? m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed : m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue; + int Score = m_pClient->m_Snap.m_pLocalInfo->m_Score; str_format(aBuf, sizeof(aBuf), "%d", Score); tw = TextRender()->TextWidth(0, 48, aBuf, -1); TextRender()->Text(0, x+w-tw-30, y, 48, aBuf, -1); @@ -208,16 +219,16 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch --FontSizeResize; TextRender()->Text(0, x+w-35.0f-Width, y+(FontSize-FontSizeResize)/2, FontSizeResize, aBuf, -1); - // render avatar - if((m_pClient->m_Snap.m_paFlags[0] && m_pClient->m_Snap.m_paFlags[0]->m_CarriedBy == pInfo->m_ClientID) || - (m_pClient->m_Snap.m_paFlags[1] && m_pClient->m_Snap.m_paFlags[1]->m_CarriedBy == pInfo->m_ClientID)) + // render flag + if(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS && + m_pClient->m_Snap.m_pGameDataObj && (m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierRed == pInfo->m_ClientID || + m_pClient->m_Snap.m_pGameDataObj->m_FlagCarrierBlue == pInfo->m_ClientID)) { Graphics()->BlendNormal(); Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->QuadsBegin(); - if(pInfo->m_Team == TEAM_RED) RenderTools()->SelectSprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X); - else RenderTools()->SelectSprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X); + RenderTools()->SelectSprite(pInfo->m_Team==TEAM_RED ? SPRITE_FLAG_BLUE : SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X); float size = 64.0f; IGraphics::CQuadItem QuadItem(x+55, y-15, size/2, size); @@ -225,6 +236,7 @@ void CScoreboard::RenderScoreboard(float x, float y, float w, int Team, const ch Graphics()->QuadsEnd(); } + // render avatar CTeeRenderInfo TeeInfo = m_pClient->m_aClients[pInfo->m_ClientID].m_RenderInfo; TeeInfo.m_Size *= TeeSizeMod; RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28+TeeOffset)); @@ -274,25 +286,28 @@ void CScoreboard::OnRender() float w = 650.0f; - if(m_pClient->m_Snap.m_pGameobj && !(m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS)) - RenderScoreboard(Width/2-w/2, 150.0f, w, 0, 0); - else + if(m_pClient->m_Snap.m_pGameInfoObj) { - - if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver) + if(!(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS)) + RenderScoreboard(Width/2-w/2, 150.0f, w, 0, 0); + else { - const char *pText = Localize("Draw!"); - if(m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed > m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue) - pText = Localize("Red team wins!"); - else if(m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue > m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed) - pText = Localize("Blue team wins!"); - - float w = TextRender()->TextWidth(0, 86.0f, pText, -1); - TextRender()->Text(0, Width/2-w/2, 39, 86.0f, pText, -1); - } - RenderScoreboard(Width/2-w-20, 150.0f, w, TEAM_RED, Localize("Red team")); - RenderScoreboard(Width/2 + 20, 150.0f, w, TEAM_BLUE, Localize("Blue team")); + if(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER && m_pClient->m_Snap.m_pGameDataObj) + { + const char *pText = Localize("Draw!"); + if(m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed > m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue) + pText = Localize("Red team wins!"); + else if(m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue > m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed) + pText = Localize("Blue team wins!"); + + float w = TextRender()->TextWidth(0, 86.0f, pText, -1); + TextRender()->Text(0, Width/2-w/2, 39, 86.0f, pText, -1); + } + + RenderScoreboard(Width/2-w-20, 150.0f, w, TEAM_RED, Localize("Red team")); + RenderScoreboard(Width/2 + 20, 150.0f, w, TEAM_BLUE, Localize("Blue team")); + } } RenderGoals(Width/2-w/2, 150+750+25, w); @@ -314,7 +329,7 @@ bool CScoreboard::Active() } // if the game is over - if(m_pClient->m_Snap.m_pGameobj && m_pClient->m_Snap.m_pGameobj->m_GameOver) + if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER) return true; return false; diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index 0aaf40b44..f80d02660 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -340,7 +340,7 @@ void CGameClient::UpdateLocalCharacterPos() { if(g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK) { - if(!m_Snap.m_pLocalCharacter || (m_Snap.m_pGameobj && m_Snap.m_pGameobj->m_GameOver)) + if(!m_Snap.m_pLocalCharacter || (m_Snap.m_pGameInfoObj && m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)) { // don't use predicted } @@ -413,7 +413,7 @@ void CGameClient::OnRender() // resend if client info differs if(str_comp(g_Config.m_PlayerName, m_aClients[m_Snap.m_LocalClientID].m_aName) || str_comp(g_Config.m_PlayerSkin, m_aClients[m_Snap.m_LocalClientID].m_aSkinName) || - (g_GameClient.m_Snap.m_pGameobj && !(g_GameClient.m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) && // no teamgame? + (m_Snap.m_pGameInfoObj && !(m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS) && // no teamgame? (g_Config.m_PlayerUseCustomColor != m_aClients[m_Snap.m_LocalClientID].m_UseCustomColor || g_Config.m_PlayerColorBody != m_aClients[m_Snap.m_LocalClientID].m_ColorBody || g_Config.m_PlayerColorFeet != m_aClients[m_Snap.m_LocalClientID].m_ColorFeet))) @@ -728,15 +728,20 @@ void CGameClient::OnNewSnapshot() Evolve(&m_Snap.m_aCharacters[Item.m_ID].m_Cur, Client()->GameTick()); } } - else if(Item.m_Type == NETOBJTYPE_GAME) + else if(Item.m_Type == NETOBJTYPE_GAMEINFO) { - static int s_GameOver = 0; - m_Snap.m_pGameobj = (CNetObj_Game *)pData; - if(s_GameOver == 0 && m_Snap.m_pGameobj->m_GameOver != 0) + static bool s_GameOver = 0; + m_Snap.m_pGameInfoObj = (const CNetObj_GameInfo *)pData; + if(!s_GameOver && m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER) OnGameOver(); - else if(s_GameOver != 0 && m_Snap.m_pGameobj->m_GameOver == 0) + else if(s_GameOver && !(m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)) OnStartGame(); - s_GameOver = m_Snap.m_pGameobj->m_GameOver; + s_GameOver = m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER; + } + else if(Item.m_Type == NETOBJTYPE_GAMEDATA) + { + m_Snap.m_pGameDataObj = (const CNetObj_GameData *)pData; + m_Snap.m_GameDataSnapID = Item.m_ID; } else if(Item.m_Type == NETOBJTYPE_FLAG) m_Snap.m_paFlags[Item.m_ID%2] = (const CNetObj_Flag *)pData; @@ -803,7 +808,7 @@ void CGameClient::OnPredict() return; // don't predict anything if we are paused - if(m_Snap.m_pGameobj && m_Snap.m_pGameobj->m_Paused) + if(m_Snap.m_pGameInfoObj && m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED) { if(m_Snap.m_pLocalCharacter) m_PredictedChar.Read(m_Snap.m_pLocalCharacter); @@ -928,7 +933,7 @@ void CGameClient::CClientData::UpdateRenderInfo() m_RenderInfo = m_SkinInfo; // force team colors - if(g_GameClient.m_Snap.m_pGameobj && g_GameClient.m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) + if(g_GameClient.m_Snap.m_pGameInfoObj && g_GameClient.m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS) { const int TeamColors[2] = {65387, 10223467}; if(m_Team >= TEAM_RED && m_Team <= TEAM_BLUE) diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index e6650d442..3681b3018 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -110,7 +110,9 @@ public: const CNetObj_Character *m_pLocalPrevCharacter; const CNetObj_PlayerInfo *m_pLocalInfo; const CNetObj_Flag *m_paFlags[2]; - const CNetObj_Game *m_pGameobj; + const CNetObj_GameInfo *m_pGameInfoObj; + const CNetObj_GameData *m_pGameDataObj; + int m_GameDataSnapID; const CNetObj_PlayerInfo *m_paPlayerInfos[MAX_CLIENTS]; const CNetObj_PlayerInfo *m_paInfoByScore[MAX_CLIENTS]; diff --git a/src/game/server/entities/flag.cpp b/src/game/server/entities/flag.cpp index 13109b077..5ac3de473 100644 --- a/src/game/server/entities/flag.cpp +++ b/src/game/server/entities/flag.cpp @@ -25,6 +25,9 @@ void CFlag::Reset() void CFlag::Snap(int SnappingClient) { + if(NetworkClipped(SnappingClient)) + return; + CNetObj_Flag *pFlag = (CNetObj_Flag *)Server()->SnapNewItem(NETOBJTYPE_FLAG, m_Team, sizeof(CNetObj_Flag)); if(!pFlag) return; @@ -32,10 +35,4 @@ void CFlag::Snap(int SnappingClient) pFlag->m_X = (int)m_Pos.x; pFlag->m_Y = (int)m_Pos.y; pFlag->m_Team = m_Team; - pFlag->m_CarriedBy = -1; - - if(m_AtStand) - pFlag->m_CarriedBy = -2; - else if(m_pCarryingCharacter && m_pCarryingCharacter->GetPlayer()) - pFlag->m_CarriedBy = m_pCarryingCharacter->GetPlayer()->GetCID(); } diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp index e51b503c7..e37bde659 100644 --- a/src/game/server/gamecontroller.cpp +++ b/src/game/server/gamecontroller.cpp @@ -571,37 +571,26 @@ bool IGameController::IsTeamplay() const void IGameController::Snap(int SnappingClient) { - CNetObj_Game *pGameObj = (CNetObj_Game *)Server()->SnapNewItem(NETOBJTYPE_GAME, 0, sizeof(CNetObj_Game)); - if(!pGameObj) + CNetObj_GameInfo *pGameInfoObj = (CNetObj_GameInfo *)Server()->SnapNewItem(NETOBJTYPE_GAMEINFO, 0, sizeof(CNetObj_GameInfo)); + if(!pGameInfoObj) return; - pGameObj->m_Paused = GameServer()->m_World.m_Paused; - pGameObj->m_GameOver = m_GameOverTick==-1?0:1; - pGameObj->m_SuddenDeath = m_SuddenDeath; + pGameInfoObj->m_GameFlags = m_GameFlags; + pGameInfoObj->m_GameStateFlags = 0; + if(m_GameOverTick != -1) + pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_GAMEOVER; + if(m_SuddenDeath) + pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_SUDDENDEATH; + if(GameServer()->m_World.m_Paused) + pGameInfoObj->m_GameStateFlags |= GAMESTATEFLAG_PAUSED; + pGameInfoObj->m_RoundStartTick = m_RoundStartTick; + pGameInfoObj->m_WarmupTimer = m_Warmup; + + pGameInfoObj->m_ScoreLimit = g_Config.m_SvScorelimit; + pGameInfoObj->m_TimeLimit = g_Config.m_SvTimelimit; - pGameObj->m_ScoreLimit = g_Config.m_SvScorelimit; - pGameObj->m_TimeLimit = g_Config.m_SvTimelimit; - pGameObj->m_RoundStartTick = m_RoundStartTick; - pGameObj->m_Flags = m_GameFlags; - - pGameObj->m_Warmup = m_Warmup; - - pGameObj->m_RoundNum = (str_length(g_Config.m_SvMaprotation) && g_Config.m_SvRoundsPerMap) ? g_Config.m_SvRoundsPerMap : 0; - pGameObj->m_RoundCurrent = m_RoundCount+1; - - - if(SnappingClient == -1) - { - // we are recording a demo, just set the scores - pGameObj->m_TeamscoreRed = m_aTeamscore[TEAM_RED]; - pGameObj->m_TeamscoreBlue = m_aTeamscore[TEAM_BLUE]; - } - else - { - // TODO: this little hack should be removed - pGameObj->m_TeamscoreRed = IsTeamplay() ? m_aTeamscore[TEAM_RED] : GameServer()->m_apPlayers[SnappingClient]->m_Score; - pGameObj->m_TeamscoreBlue = m_aTeamscore[TEAM_BLUE]; - } + pGameInfoObj->m_RoundNum = (str_length(g_Config.m_SvMaprotation) && g_Config.m_SvRoundsPerMap) ? g_Config.m_SvRoundsPerMap : 0; + pGameInfoObj->m_RoundCurrent = m_RoundCount+1; } int IGameController::GetAutoTeam(int NotThisID) diff --git a/src/game/server/gamemodes/ctf.cpp b/src/game/server/gamemodes/ctf.cpp index 92fc90c99..490067dd8 100644 --- a/src/game/server/gamemodes/ctf.cpp +++ b/src/game/server/gamemodes/ctf.cpp @@ -78,6 +78,31 @@ bool CGameControllerCTF::CanBeMovedOnBalance(int ClientID) return true; } +void CGameControllerCTF::Snap(int SnappingClient) +{ + IGameController::Snap(SnappingClient); + + CNetObj_GameData *pGameDataObj = (CNetObj_GameData *)Server()->SnapNewItem(NETOBJTYPE_GAMEDATA, 0, sizeof(CNetObj_GameData)); + if(!pGameDataObj) + return; + + pGameDataObj->m_TeamscoreRed = m_aTeamscore[TEAM_RED]; + pGameDataObj->m_TeamscoreBlue = m_aTeamscore[TEAM_BLUE]; + + if(m_apFlags[TEAM_RED]->m_AtStand) + pGameDataObj->m_FlagCarrierRed = FLAG_ATSTAND; + else if(m_apFlags[TEAM_RED]->m_pCarryingCharacter && m_apFlags[TEAM_RED]->m_pCarryingCharacter->GetPlayer()) + pGameDataObj->m_FlagCarrierRed = m_apFlags[TEAM_RED]->m_pCarryingCharacter->GetPlayer()->GetCID(); + else + pGameDataObj->m_FlagCarrierRed = FLAG_TAKEN; + if(m_apFlags[TEAM_BLUE]->m_AtStand) + pGameDataObj->m_FlagCarrierBlue = FLAG_ATSTAND; + else if(m_apFlags[TEAM_BLUE]->m_pCarryingCharacter && m_apFlags[TEAM_BLUE]->m_pCarryingCharacter->GetPlayer()) + pGameDataObj->m_FlagCarrierBlue = m_apFlags[TEAM_BLUE]->m_pCarryingCharacter->GetPlayer()->GetCID(); + else + pGameDataObj->m_FlagCarrierBlue = FLAG_TAKEN; +} + void CGameControllerCTF::Tick() { IGameController::Tick(); diff --git a/src/game/server/gamemodes/ctf.h b/src/game/server/gamemodes/ctf.h index e6fb9c89a..b9868e700 100644 --- a/src/game/server/gamemodes/ctf.h +++ b/src/game/server/gamemodes/ctf.h @@ -12,6 +12,7 @@ public: CGameControllerCTF(class CGameContext *pGameServer); virtual bool CanBeMovedOnBalance(int ClientID); + virtual void Snap(int SnappingClient); virtual void Tick(); virtual bool OnEntity(int Index, vec2 Pos); diff --git a/src/game/server/gamemodes/tdm.cpp b/src/game/server/gamemodes/tdm.cpp index 581fca2fb..ef5302c64 100644 --- a/src/game/server/gamemodes/tdm.cpp +++ b/src/game/server/gamemodes/tdm.cpp @@ -27,6 +27,21 @@ int CGameControllerTDM::OnCharacterDeath(class CCharacter *pVictim, class CPlaye return 0; } +void CGameControllerTDM::Snap(int SnappingClient) +{ + IGameController::Snap(SnappingClient); + + CNetObj_GameData *pGameDataObj = (CNetObj_GameData *)Server()->SnapNewItem(NETOBJTYPE_GAMEDATA, 0, sizeof(CNetObj_GameData)); + if(!pGameDataObj) + return; + + pGameDataObj->m_TeamscoreRed = m_aTeamscore[TEAM_RED]; + pGameDataObj->m_TeamscoreBlue = m_aTeamscore[TEAM_BLUE]; + + pGameDataObj->m_FlagCarrierRed = 0; + pGameDataObj->m_FlagCarrierBlue = 0; +} + void CGameControllerTDM::Tick() { DoTeamScoreWincheck(); diff --git a/src/game/server/gamemodes/tdm.h b/src/game/server/gamemodes/tdm.h index 806e799a4..c8d3f3286 100644 --- a/src/game/server/gamemodes/tdm.h +++ b/src/game/server/gamemodes/tdm.h @@ -10,6 +10,7 @@ public: CGameControllerTDM(class CGameContext *pGameServer); int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon); + virtual void Snap(int SnappingClient); virtual void Tick(); }; #endif