made network clip flags. Closes #131

This commit is contained in:
oy 2011-03-04 17:08:10 +01:00
parent 4bede550be
commit 9811c2396b
19 changed files with 224 additions and 154 deletions

View file

@ -3,6 +3,7 @@ from datatypes import *
Emotes = ["NORMAL", "PAIN", "HAPPY", "SURPRISE", "ANGRY", "BLINK"] Emotes = ["NORMAL", "PAIN", "HAPPY", "SURPRISE", "ANGRY", "BLINK"]
PlayerFlags = ["PLAYING", "IN_MENU", "CHATTING", "SCOREBOARD"] PlayerFlags = ["PLAYING", "IN_MENU", "CHATTING", "SCOREBOARD"]
GameFlags = ["TEAMS", "FLAGS"] GameFlags = ["TEAMS", "FLAGS"]
GameStateFlags = ["GAMEOVER", "SUDDENDEATH", "PAUSED"]
Emoticons = [str(x) for x in range(0,16)] Emoticons = [str(x) for x in range(0,16)]
@ -21,7 +22,10 @@ enum
{ {
TEAM_SPECTATORS=-1, TEAM_SPECTATORS=-1,
TEAM_RED, TEAM_RED,
TEAM_BLUE TEAM_BLUE,
FLAG_ATSTAND=-2,
FLAG_TAKEN,
}; };
''' '''
@ -37,8 +41,9 @@ Enums = [
] ]
Flags = [ Flags = [
Enum("PLAYERFLAG", PlayerFlags), Flags("PLAYERFLAG", PlayerFlags),
Flags("GAMEFLAG", GameFlags) Flags("GAMEFLAG", GameFlags),
Flags("GAMESTATEFLAG", GameStateFlags)
] ]
Objects = [ Objects = [
@ -90,28 +95,28 @@ Objects = [
NetIntAny("m_X"), NetIntAny("m_X"),
NetIntAny("m_Y"), NetIntAny("m_Y"),
NetIntRange("m_Team", 'TEAM_RED', 'TEAM_BLUE'), NetIntRange("m_Team", 'TEAM_RED', 'TEAM_BLUE')
NetIntRange("m_CarriedBy", -2, 'MAX_CLIENTS-1')
]), ]),
NetObject("Game", [ NetObject("GameInfo", [
NetIntRange("m_Flags", 0, 256), NetIntRange("m_GameFlags", 0, 256),
NetIntRange("m_GameStateFlags", 0, 256),
NetTick("m_RoundStartTick"), NetTick("m_RoundStartTick"),
NetIntRange("m_WarmupTimer", 0, 'max_int'),
NetIntRange("m_GameOver", 0, 1),
NetIntRange("m_SuddenDeath", 0, 1),
NetIntRange("m_Paused", 0, 1),
NetIntRange("m_ScoreLimit", 0, 'max_int'), NetIntRange("m_ScoreLimit", 0, 'max_int'),
NetIntRange("m_TimeLimit", 0, 'max_int'), NetIntRange("m_TimeLimit", 0, 'max_int'),
NetIntRange("m_Warmup", 0, 'max_int'),
NetIntRange("m_RoundNum", 0, 'max_int'), NetIntRange("m_RoundNum", 0, 'max_int'),
NetIntRange("m_RoundCurrent", 0, 'max_int'), NetIntRange("m_RoundCurrent", 0, 'max_int'),
]),
NetObject("GameData", [
NetIntAny("m_TeamscoreRed"), NetIntAny("m_TeamscoreRed"),
NetIntAny("m_TeamscoreBlue"), NetIntAny("m_TeamscoreBlue"),
NetIntRange("m_FlagCarrierRed", 'FLAG_ATSTAND', 'MAX_CLIENTS-1'),
NetIntRange("m_FlagCarrierBlue", 'FLAG_ATSTAND', 'MAX_CLIENTS-1'),
]), ]),
NetObject("CharacterCore", [ NetObject("CharacterCore", [

View file

@ -235,7 +235,7 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
if(m_pClient->m_aClients[ClientID].m_Team == TEAM_SPECTATORS) if(m_pClient->m_aClients[ClientID].m_Team == TEAM_SPECTATORS)
m_aLines[m_CurrentLine].m_NameColor = 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) if(m_pClient->m_aClients[ClientID].m_Team == TEAM_RED)
m_aLines[m_CurrentLine].m_NameColor = TEAM_RED; m_aLines[m_CurrentLine].m_NameColor = TEAM_RED;

View file

@ -199,13 +199,13 @@ int CControls::SnapInput(int *pData)
void CControls::OnRender() void CControls::OnRender()
{ {
// update target pos // 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; m_TargetPos = m_pClient->m_LocalCharacterPos + m_MousePos;
} }
bool CControls::OnMouseMove(float x, float y) 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; return false;
m_MousePos += vec2(x, y); // TODO: ugly m_MousePos += vec2(x, y); // TODO: ugly

View file

@ -32,25 +32,25 @@ void CHud::RenderGameTimer()
float Half = 300.0f*Graphics()->ScreenAspect()/2.0f; float Half = 300.0f*Graphics()->ScreenAspect()/2.0f;
Graphics()->MapScreen(0, 0, 300.0f*Graphics()->ScreenAspect(), 300.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]; char Buf[32];
int Time = 0; 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; Time = 0;
} }
else 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); str_format(Buf, sizeof(Buf), "%d:%02d", Time/60, Time%60);
float FontSize = 10.0f; float FontSize = 10.0f;
float w = TextRender()->TextWidth(0, FontSize, Buf, -1); float w = TextRender()->TextWidth(0, FontSize, Buf, -1);
// last 60 sec red, last 10 sec blink // 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; float Alpha = Time <= 10 && (2*time_get()/time_freq()) % 2 ? 0.5f : 1.0f;
TextRender()->TextColor(1.0f, 0.25f, 0.25f, Alpha); TextRender()->TextColor(1.0f, 0.25f, 0.25f, Alpha);
@ -62,7 +62,7 @@ void CHud::RenderGameTimer()
void CHud::RenderSuddenDeath() 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; float Half = 300.0f*Graphics()->ScreenAspect()/2.0f;
const char *pText = Localize("Sudden Death"); const char *pText = Localize("Sudden Death");
@ -75,17 +75,18 @@ void CHud::RenderSuddenDeath()
void CHud::RenderScoreHud() void CHud::RenderScoreHud()
{ {
// render small score hud // 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(); float Whole = 300*Graphics()->ScreenAspect();
if(GameFlags&GAMEFLAG_TEAMS) if(GameFlags&GAMEFLAG_TEAMS && m_pClient->m_Snap.m_pGameDataObj)
{ {
char aScoreTeam[2][32]; 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_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_pGameobj->m_TeamscoreBlue); 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)}; 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 ScoreWidthMax = max(max(aScoreTeamWidth[TEAM_RED], aScoreTeamWidth[TEAM_BLUE]), TextRender()->TextWidth(0, 14.0f, "100", -1));
float Split = 3.0f; float Split = 3.0f;
float ImageSize = GameFlags&GAMEFLAG_FLAGS ? 16.0f : Split; float ImageSize = GameFlags&GAMEFLAG_FLAGS ? 16.0f : Split;
@ -106,9 +107,9 @@ void CHud::RenderScoreHud()
// draw score // draw score
TextRender()->Text(0, Whole-ScoreWidthMax+(ScoreWidthMax-aScoreTeamWidth[t])/2-Split, 245.0f+t*20, 14.0f, aScoreTeam[t], -1); 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 // draw flag
Graphics()->BlendNormal(); Graphics()->BlendNormal();
@ -119,10 +120,10 @@ void CHud::RenderScoreHud()
Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsDrawTL(&QuadItem, 1);
Graphics()->QuadsEnd(); 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 // 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; const char *pName = m_pClient->m_aClients[ID].m_aName;
float w = TextRender()->TextWidth(0, 10.0f, pName, -1); 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); 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() void CHud::RenderWarmupTimer()
{ {
// render warmup timer // render warmup timer
if(m_pClient->m_Snap.m_pGameobj->m_Warmup) if(m_pClient->m_Snap.m_pGameInfoObj->m_WarmupTimer)
{ {
char Buf[256]; char Buf[256];
float FontSize = 20.0f; float FontSize = 20.0f;
float w = TextRender()->TextWidth(0, FontSize, Localize("Warmup"), -1); float w = TextRender()->TextWidth(0, FontSize, Localize("Warmup"), -1);
TextRender()->Text(0, 150*Graphics()->ScreenAspect()+-w/2, 50, 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) 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 else
str_format(Buf, sizeof(Buf), "%d", Seconds); str_format(Buf, sizeof(Buf), "%d", Seconds);
w = TextRender()->TextWidth(0, FontSize, Buf, -1); w = TextRender()->TextWidth(0, FontSize, Buf, -1);
@ -268,7 +269,7 @@ void CHud::RenderTeambalanceWarning()
{ {
// render prompt about team-balance // render prompt about team-balance
bool Flash = time_get()/(time_freq()/2)%2 == 0; 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]; 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)) if (g_Config.m_ClWarningTeambalance && (TeamDiff >= 2 || TeamDiff <= -2))
@ -395,7 +396,7 @@ void CHud::RenderHealthAndAmmo()
void CHud::OnRender() void CHud::OnRender()
{ {
if(!m_pClient->m_Snap.m_pGameobj) if(!m_pClient->m_Snap.m_pGameInfoObj)
return; return;
m_Width = 300*Graphics()->ScreenAspect(); 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) if(m_pClient->m_Snap.m_pLocalInfo && m_pClient->m_Snap.m_pLocalInfo->m_Team == TEAM_SPECTATORS)
Spectate = true; 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(); RenderHealthAndAmmo();
RenderGameTimer(); RenderGameTimer();

View file

@ -152,7 +152,7 @@ void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCu
Graphics()->QuadsEnd(); 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 Angle = 0.0f;
float Size = 42.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()); vec2 Pos = mix(vec2(pPrev->m_X, pPrev->m_Y), vec2(pCurrent->m_X, pCurrent->m_Y), Client()->IntraGameTick());
if(pCurGameData)
{
// make sure that the flag isn't interpolated between capture and return // make sure that the flag isn't interpolated between capture and return
if(pPrev->m_CarriedBy != pCurrent->m_CarriedBy) 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); Pos = vec2(pCurrent->m_X, pCurrent->m_Y);
// make sure to use predicted position if we are the carrier // 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) 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; Pos = m_pClient->m_LocalCharacterPos;
}
IGraphics::CQuadItem QuadItem(Pos.x, Pos.y-Size*0.75f, Size, Size*2); IGraphics::CQuadItem QuadItem(Pos.x, Pos.y-Size*0.75f, Size, Size*2);
Graphics()->QuadsDraw(&QuadItem, 1); 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); const void *pPrev = Client()->SnapFindItem(IClient::SNAP_PREV, Item.m_Type, Item.m_ID);
if (pPrev) 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<const CNetObj_Flag *>(pPrev), static_cast<const CNetObj_Flag *>(pData),
static_cast<const CNetObj_GameData *>(pPrevGameData), m_pClient->m_Snap.m_pGameDataObj);
}
} }
} }

View file

@ -8,7 +8,7 @@ class CItems : public CComponent
{ {
void RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemID); void RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemID);
void RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCurrent); 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); void RenderLaser(const struct CNetObj_Laser *pCurrent);
public: public:

View file

@ -70,7 +70,7 @@ void CKillMessages::OnRender()
// render victim tee // render victim tee
x -= 24.0f; 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) 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_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) if(m_aKillmsgs[r].m_ModeSpecial&2)
{ {

View file

@ -35,7 +35,7 @@ void CMenus::RenderGame(CUIRect MainView)
if(DoButton_Menu(&s_DisconnectButton, Localize("Disconnect"), 0, &Button)) if(DoButton_Menu(&s_DisconnectButton, Localize("Disconnect"), 0, &Button))
Client()->Disconnect(); 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) 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) if(m_pClient->m_Snap.m_pLocalInfo->m_Team != TEAM_RED)
{ {
@ -248,6 +248,8 @@ void CMenus::RenderServerInfo(CUIRect MainView)
TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 32, Localize("Game info"), 250); TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 32, Localize("Game info"), 250);
y += 32.0f+5.0f; y += 32.0f+5.0f;
if(m_pClient->m_Snap.m_pGameInfoObj)
{
mem_zero(aBuf, sizeof(aBuf)); mem_zero(aBuf, sizeof(aBuf));
str_format( str_format(
aBuf, aBuf,
@ -261,11 +263,12 @@ void CMenus::RenderServerInfo(CUIRect MainView)
"%s: %d/%d\n", "%s: %d/%d\n",
Localize("Game type"), CurrentServerInfo.m_aGameType, Localize("Game type"), CurrentServerInfo.m_aGameType,
Localize("Map"), CurrentServerInfo.m_aMap, Localize("Map"), CurrentServerInfo.m_aMap,
Localize("Score limit"), m_pClient->m_Snap.m_pGameobj->m_ScoreLimit, Localize("Score limit"), m_pClient->m_Snap.m_pGameInfoObj->m_ScoreLimit,
Localize("Time limit"), m_pClient->m_Snap.m_pGameobj->m_TimeLimit, Localize("Time limit"), m_pClient->m_Snap.m_pGameInfoObj->m_TimeLimit,
Localize("Players"), m_pClient->m_Snap.m_NumPlayers, CurrentServerInfo.m_MaxPlayers Localize("Players"), m_pClient->m_Snap.m_NumPlayers, CurrentServerInfo.m_MaxPlayers
); );
TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 20, aBuf, 250); TextRender()->Text(0, GameInfo.x+x, GameInfo.y+y, 20, aBuf, 250);
}
// motd // motd
Motd.HSplitTop(10.0f, 0, &Motd); Motd.HSplitTop(10.0f, 0, &Motd);

View file

@ -33,7 +33,7 @@ void CNamePlates::RenderNameplate(
float tw = TextRender()->TextWidth(0, FontSize, pName, -1); float tw = TextRender()->TextWidth(0, FontSize, pName, -1);
TextRender()->TextColor(1.0f, 1.0f, 1.0f, a); 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) if(pPlayerInfo->m_Team == TEAM_RED)
TextRender()->TextColor(1.0f, 0.5f, 0.5f, a); TextRender()->TextColor(1.0f, 0.5f, 0.5f, a);

View file

@ -99,8 +99,8 @@ void CPlayers::RenderHook(
// check for teamplay modes // check for teamplay modes
bool IsTeamplay = false; bool IsTeamplay = false;
if(m_pClient->m_Snap.m_pGameobj) if(m_pClient->m_Snap.m_pGameInfoObj)
IsTeamplay = (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0; IsTeamplay = (m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS) != 0;
// check for ninja // check for ninja
if (Player.m_Weapon == WEAPON_NINJA) if (Player.m_Weapon == WEAPON_NINJA)
@ -129,7 +129,7 @@ void CPlayers::RenderHook(
// use preditect players if needed // use preditect players if needed
if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK) 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 else
@ -223,8 +223,8 @@ void CPlayers::RenderPlayer(
// check for teamplay modes // check for teamplay modes
bool IsTeamplay = false; bool IsTeamplay = false;
bool NewTick = m_pClient->m_NewTick; bool NewTick = m_pClient->m_NewTick;
if(m_pClient->m_Snap.m_pGameobj) if(m_pClient->m_Snap.m_pGameInfoObj)
IsTeamplay = (m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS) != 0; IsTeamplay = (m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS) != 0;
// check for ninja // check for ninja
if (Player.m_Weapon == WEAPON_NINJA) if (Player.m_Weapon == WEAPON_NINJA)
@ -284,7 +284,7 @@ void CPlayers::RenderPlayer(
// use preditect players if needed // use preditect players if needed
if(pInfo.m_Local && g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK) 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 else

View file

@ -51,24 +51,24 @@ void CScoreboard::RenderGoals(float x, float y, float w)
Graphics()->QuadsEnd(); Graphics()->QuadsEnd();
// render goals // 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]; 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); 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]; 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); 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]; 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); float tw = TextRender()->TextWidth(0, 20.0f, aBuf, -1);
TextRender()->Text(0, x+w-tw-20.0f, y, 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 // render title
if(!pTitle) 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"); pTitle = Localize("Game over");
else else
pTitle = Localize("Score board"); 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); float tw = TextRender()->TextWidth(0, 48, pTitle, -1);
TextRender()->Text(0, x+10, y, 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]; 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 = 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 = m_pClient->m_Snap.m_pLocalInfo->m_Score;
str_format(aBuf, sizeof(aBuf), "%d", Score); str_format(aBuf, sizeof(aBuf), "%d", Score);
tw = TextRender()->TextWidth(0, 48, aBuf, -1); tw = TextRender()->TextWidth(0, 48, aBuf, -1);
TextRender()->Text(0, x+w-tw-30, y, 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; --FontSizeResize;
TextRender()->Text(0, x+w-35.0f-Width, y+(FontSize-FontSizeResize)/2, FontSizeResize, aBuf, -1); TextRender()->Text(0, x+w-35.0f-Width, y+(FontSize-FontSizeResize)/2, FontSizeResize, aBuf, -1);
// render avatar // render flag
if((m_pClient->m_Snap.m_paFlags[0] && m_pClient->m_Snap.m_paFlags[0]->m_CarriedBy == pInfo->m_ClientID) || if(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS &&
(m_pClient->m_Snap.m_paFlags[1] && m_pClient->m_Snap.m_paFlags[1]->m_CarriedBy == pInfo->m_ClientID)) 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()->BlendNormal();
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id); Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
Graphics()->QuadsBegin(); Graphics()->QuadsBegin();
if(pInfo->m_Team == TEAM_RED) RenderTools()->SelectSprite(SPRITE_FLAG_BLUE, SPRITE_FLAG_FLIP_X); RenderTools()->SelectSprite(pInfo->m_Team==TEAM_RED ? SPRITE_FLAG_BLUE : SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
else RenderTools()->SelectSprite(SPRITE_FLAG_RED, SPRITE_FLAG_FLIP_X);
float size = 64.0f; float size = 64.0f;
IGraphics::CQuadItem QuadItem(x+55, y-15, size/2, size); 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(); Graphics()->QuadsEnd();
} }
// render avatar
CTeeRenderInfo TeeInfo = m_pClient->m_aClients[pInfo->m_ClientID].m_RenderInfo; CTeeRenderInfo TeeInfo = m_pClient->m_aClients[pInfo->m_ClientID].m_RenderInfo;
TeeInfo.m_Size *= TeeSizeMod; TeeInfo.m_Size *= TeeSizeMod;
RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28+TeeOffset)); RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1,0), vec2(x+90, y+28+TeeOffset));
@ -274,17 +286,19 @@ void CScoreboard::OnRender()
float w = 650.0f; float w = 650.0f;
if(m_pClient->m_Snap.m_pGameobj && !(m_pClient->m_Snap.m_pGameobj->m_Flags&GAMEFLAG_TEAMS)) if(m_pClient->m_Snap.m_pGameInfoObj)
{
if(!(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags&GAMEFLAG_TEAMS))
RenderScoreboard(Width/2-w/2, 150.0f, w, 0, 0); RenderScoreboard(Width/2-w/2, 150.0f, w, 0, 0);
else else
{ {
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 && m_pClient->m_Snap.m_pGameDataObj)
{ {
const char *pText = Localize("Draw!"); const char *pText = Localize("Draw!");
if(m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed > m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue) if(m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed > m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue)
pText = Localize("Red team wins!"); pText = Localize("Red team wins!");
else if(m_pClient->m_Snap.m_pGameobj->m_TeamscoreBlue > m_pClient->m_Snap.m_pGameobj->m_TeamscoreRed) else if(m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreBlue > m_pClient->m_Snap.m_pGameDataObj->m_TeamscoreRed)
pText = Localize("Blue team wins!"); pText = Localize("Blue team wins!");
float w = TextRender()->TextWidth(0, 86.0f, pText, -1); float w = TextRender()->TextWidth(0, 86.0f, pText, -1);
@ -294,6 +308,7 @@ void CScoreboard::OnRender()
RenderScoreboard(Width/2-w-20, 150.0f, w, TEAM_RED, Localize("Red team")); 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")); RenderScoreboard(Width/2 + 20, 150.0f, w, TEAM_BLUE, Localize("Blue team"));
} }
}
RenderGoals(Width/2-w/2, 150+750+25, w); RenderGoals(Width/2-w/2, 150+750+25, w);
RenderSpectators(Width/2-w/2, 150+750+25+50+25, w); RenderSpectators(Width/2-w/2, 150+750+25+50+25, w);
@ -314,7 +329,7 @@ bool CScoreboard::Active()
} }
// if the game is over // 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 true;
return false; return false;

View file

@ -340,7 +340,7 @@ void CGameClient::UpdateLocalCharacterPos()
{ {
if(g_Config.m_ClPredict && Client()->State() != IClient::STATE_DEMOPLAYBACK) 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 // don't use predicted
} }
@ -413,7 +413,7 @@ void CGameClient::OnRender()
// resend if client info differs // resend if client info differs
if(str_comp(g_Config.m_PlayerName, m_aClients[m_Snap.m_LocalClientID].m_aName) || 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) || 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_PlayerUseCustomColor != m_aClients[m_Snap.m_LocalClientID].m_UseCustomColor ||
g_Config.m_PlayerColorBody != m_aClients[m_Snap.m_LocalClientID].m_ColorBody || g_Config.m_PlayerColorBody != m_aClients[m_Snap.m_LocalClientID].m_ColorBody ||
g_Config.m_PlayerColorFeet != m_aClients[m_Snap.m_LocalClientID].m_ColorFeet))) 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()); 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; static bool s_GameOver = 0;
m_Snap.m_pGameobj = (CNetObj_Game *)pData; m_Snap.m_pGameInfoObj = (const CNetObj_GameInfo *)pData;
if(s_GameOver == 0 && m_Snap.m_pGameobj->m_GameOver != 0) if(!s_GameOver && m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)
OnGameOver(); 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(); 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) else if(Item.m_Type == NETOBJTYPE_FLAG)
m_Snap.m_paFlags[Item.m_ID%2] = (const CNetObj_Flag *)pData; m_Snap.m_paFlags[Item.m_ID%2] = (const CNetObj_Flag *)pData;
@ -803,7 +808,7 @@ void CGameClient::OnPredict()
return; return;
// don't predict anything if we are paused // 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) if(m_Snap.m_pLocalCharacter)
m_PredictedChar.Read(m_Snap.m_pLocalCharacter); m_PredictedChar.Read(m_Snap.m_pLocalCharacter);
@ -928,7 +933,7 @@ void CGameClient::CClientData::UpdateRenderInfo()
m_RenderInfo = m_SkinInfo; m_RenderInfo = m_SkinInfo;
// force team colors // 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}; const int TeamColors[2] = {65387, 10223467};
if(m_Team >= TEAM_RED && m_Team <= TEAM_BLUE) if(m_Team >= TEAM_RED && m_Team <= TEAM_BLUE)

View file

@ -110,7 +110,9 @@ public:
const CNetObj_Character *m_pLocalPrevCharacter; const CNetObj_Character *m_pLocalPrevCharacter;
const CNetObj_PlayerInfo *m_pLocalInfo; const CNetObj_PlayerInfo *m_pLocalInfo;
const CNetObj_Flag *m_paFlags[2]; 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_paPlayerInfos[MAX_CLIENTS];
const CNetObj_PlayerInfo *m_paInfoByScore[MAX_CLIENTS]; const CNetObj_PlayerInfo *m_paInfoByScore[MAX_CLIENTS];

View file

@ -25,6 +25,9 @@ void CFlag::Reset()
void CFlag::Snap(int SnappingClient) void CFlag::Snap(int SnappingClient)
{ {
if(NetworkClipped(SnappingClient))
return;
CNetObj_Flag *pFlag = (CNetObj_Flag *)Server()->SnapNewItem(NETOBJTYPE_FLAG, m_Team, sizeof(CNetObj_Flag)); CNetObj_Flag *pFlag = (CNetObj_Flag *)Server()->SnapNewItem(NETOBJTYPE_FLAG, m_Team, sizeof(CNetObj_Flag));
if(!pFlag) if(!pFlag)
return; return;
@ -32,10 +35,4 @@ void CFlag::Snap(int SnappingClient)
pFlag->m_X = (int)m_Pos.x; pFlag->m_X = (int)m_Pos.x;
pFlag->m_Y = (int)m_Pos.y; pFlag->m_Y = (int)m_Pos.y;
pFlag->m_Team = m_Team; 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();
} }

View file

@ -571,37 +571,26 @@ bool IGameController::IsTeamplay() const
void IGameController::Snap(int SnappingClient) void IGameController::Snap(int SnappingClient)
{ {
CNetObj_Game *pGameObj = (CNetObj_Game *)Server()->SnapNewItem(NETOBJTYPE_GAME, 0, sizeof(CNetObj_Game)); CNetObj_GameInfo *pGameInfoObj = (CNetObj_GameInfo *)Server()->SnapNewItem(NETOBJTYPE_GAMEINFO, 0, sizeof(CNetObj_GameInfo));
if(!pGameObj) if(!pGameInfoObj)
return; return;
pGameObj->m_Paused = GameServer()->m_World.m_Paused; pGameInfoObj->m_GameFlags = m_GameFlags;
pGameObj->m_GameOver = m_GameOverTick==-1?0:1; pGameInfoObj->m_GameStateFlags = 0;
pGameObj->m_SuddenDeath = m_SuddenDeath; 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;
pGameObj->m_ScoreLimit = g_Config.m_SvScorelimit; pGameInfoObj->m_ScoreLimit = g_Config.m_SvScorelimit;
pGameObj->m_TimeLimit = g_Config.m_SvTimelimit; pGameInfoObj->m_TimeLimit = g_Config.m_SvTimelimit;
pGameObj->m_RoundStartTick = m_RoundStartTick;
pGameObj->m_Flags = m_GameFlags;
pGameObj->m_Warmup = m_Warmup; pGameInfoObj->m_RoundNum = (str_length(g_Config.m_SvMaprotation) && g_Config.m_SvRoundsPerMap) ? g_Config.m_SvRoundsPerMap : 0;
pGameInfoObj->m_RoundCurrent = m_RoundCount+1;
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];
}
} }
int IGameController::GetAutoTeam(int NotThisID) int IGameController::GetAutoTeam(int NotThisID)

View file

@ -78,6 +78,31 @@ bool CGameControllerCTF::CanBeMovedOnBalance(int ClientID)
return true; 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() void CGameControllerCTF::Tick()
{ {
IGameController::Tick(); IGameController::Tick();

View file

@ -12,6 +12,7 @@ public:
CGameControllerCTF(class CGameContext *pGameServer); CGameControllerCTF(class CGameContext *pGameServer);
virtual bool CanBeMovedOnBalance(int ClientID); virtual bool CanBeMovedOnBalance(int ClientID);
virtual void Snap(int SnappingClient);
virtual void Tick(); virtual void Tick();
virtual bool OnEntity(int Index, vec2 Pos); virtual bool OnEntity(int Index, vec2 Pos);

View file

@ -27,6 +27,21 @@ int CGameControllerTDM::OnCharacterDeath(class CCharacter *pVictim, class CPlaye
return 0; 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() void CGameControllerTDM::Tick()
{ {
DoTeamScoreWincheck(); DoTeamScoreWincheck();

View file

@ -10,6 +10,7 @@ public:
CGameControllerTDM(class CGameContext *pGameServer); CGameControllerTDM(class CGameContext *pGameServer);
int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon); int OnCharacterDeath(class CCharacter *pVictim, class CPlayer *pKiller, int Weapon);
virtual void Snap(int SnappingClient);
virtual void Tick(); virtual void Tick();
}; };
#endif #endif