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"]
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", [

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)
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;

View file

@ -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

View file

@ -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();

View file

@ -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<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 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:

View file

@ -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)
{

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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)

View file

@ -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];

View file

@ -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();
}

View file

@ -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)

View file

@ -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();

View file

@ -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);

View file

@ -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();

View file

@ -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