void CGameClient::OnNewSnapshot() { m_NewTick = true; // clear out the invalid pointers mem_zero(&g_GameClient.m_Snap, sizeof(g_GameClient.m_Snap)); m_Snap.m_LocalClientID = -1; // secure snapshot { int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); for(int Index = 0; Index < Num; Index++) { IClient::CSnapItem Item; void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, Index, &Item); if(m_NetObjHandler.ValidateObj(Item.m_Type, pData, Item.m_DataSize) != 0) { if(g_Config.m_Debug) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "invalidated index=%d type=%d (%s) size=%d id=%d", Index, Item.m_Type, m_NetObjHandler.GetObjName(Item.m_Type), Item.m_DataSize, Item.m_ID); Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", aBuf); } Client()->SnapInvalidateItem(IClient::SNAP_CURRENT, Index); } } } ProcessEvents(); if(g_Config.m_DbgStress) { if((Client()->GameTick()%100) == 0) { char aMessage[64]; int MsgLen = rand()%(sizeof(aMessage)-1); for(int i = 0; i < MsgLen; i++) aMessage[i] = 'a'+(rand()%('z'-'a')); aMessage[MsgLen] = 0; CNetMsg_Cl_Say Msg; Msg.m_Team = rand()&1; Msg.m_pMessage = aMessage; Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); } } // go trough all the items in the snapshot and gather the info we want { m_Snap.m_aTeamSize[TEAM_RED] = m_Snap.m_aTeamSize[TEAM_BLUE] = 0; int Num = Client()->SnapNumItems(IClient::SNAP_CURRENT); for(int i = 0; i < Num; i++) { IClient::CSnapItem Item; const void *pData = Client()->SnapGetItem(IClient::SNAP_CURRENT, i, &Item); if(Item.m_Type == NETOBJTYPE_CLIENTINFO) { const CNetObj_ClientInfo *pInfo = (const CNetObj_ClientInfo *)pData; int ClientID = Item.m_ID; IntsToStr(&pInfo->m_Name0, 4, m_aClients[ClientID].m_aName); IntsToStr(&pInfo->m_Clan0, 3, m_aClients[ClientID].m_aClan); m_aClients[ClientID].m_Country = pInfo->m_Country; IntsToStr(&pInfo->m_Skin0, 6, m_aClients[ClientID].m_aSkinName); m_aClients[ClientID].m_UseCustomColor = pInfo->m_UseCustomColor; m_aClients[ClientID].m_ColorBody = pInfo->m_ColorBody; m_aClients[ClientID].m_ColorFeet = pInfo->m_ColorFeet; // prepare the info if(m_aClients[ClientID].m_aSkinName[0] == 'x' || m_aClients[ClientID].m_aSkinName[1] == '_') str_copy(m_aClients[ClientID].m_aSkinName, "default", 64); m_aClients[ClientID].m_SkinInfo.m_ColorBody = m_pSkins->GetColorV4(m_aClients[ClientID].m_ColorBody); m_aClients[ClientID].m_SkinInfo.m_ColorFeet = m_pSkins->GetColorV4(m_aClients[ClientID].m_ColorFeet); m_aClients[ClientID].m_SkinInfo.m_Size = 64; // find new skin m_aClients[ClientID].m_SkinID = g_GameClient.m_pSkins->Find(m_aClients[ClientID].m_aSkinName); if(m_aClients[ClientID].m_SkinID < 0) { m_aClients[ClientID].m_SkinID = g_GameClient.m_pSkins->Find("default"); if(m_aClients[ClientID].m_SkinID < 0) m_aClients[ClientID].m_SkinID = 0; } if(m_aClients[ClientID].m_UseCustomColor) m_aClients[ClientID].m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(m_aClients[ClientID].m_SkinID)->m_ColorTexture; else { m_aClients[ClientID].m_SkinInfo.m_Texture = g_GameClient.m_pSkins->Get(m_aClients[ClientID].m_SkinID)->m_OrgTexture; m_aClients[ClientID].m_SkinInfo.m_ColorBody = vec4(1,1,1,1); m_aClients[ClientID].m_SkinInfo.m_ColorFeet = vec4(1,1,1,1); } m_aClients[ClientID].UpdateRenderInfo(); } else if(Item.m_Type == NETOBJTYPE_PLAYERINFO) { const CNetObj_PlayerInfo *pInfo = (const CNetObj_PlayerInfo *)pData; m_aClients[pInfo->m_ClientID].m_Team = pInfo->m_Team; m_aClients[pInfo->m_ClientID].m_Active = true; m_Snap.m_paPlayerInfos[pInfo->m_ClientID] = pInfo; m_Snap.m_NumPlayers++; if(pInfo->m_Local) { m_Snap.m_LocalClientID = Item.m_ID; m_Snap.m_pLocalInfo = pInfo; if(pInfo->m_Team == TEAM_SPECTATORS) { m_Snap.m_SpecInfo.m_Active = true; m_Snap.m_SpecInfo.m_SpectatorID = SPEC_FREEVIEW; } } // calculate team-balance if(pInfo->m_Team != TEAM_SPECTATORS) m_Snap.m_aTeamSize[pInfo->m_Team]++; } else if(Item.m_Type == NETOBJTYPE_CHARACTER) { const void *pOld = Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_CHARACTER, Item.m_ID); m_Snap.m_aCharacters[Item.m_ID].m_Cur = *((const CNetObj_Character *)pData); if(pOld) { m_Snap.m_aCharacters[Item.m_ID].m_Active = true; m_Snap.m_aCharacters[Item.m_ID].m_Prev = *((const CNetObj_Character *)pOld); if(m_Snap.m_aCharacters[Item.m_ID].m_Prev.m_Tick) Evolve(&m_Snap.m_aCharacters[Item.m_ID].m_Prev, Client()->PrevGameTick()); if(m_Snap.m_aCharacters[Item.m_ID].m_Cur.m_Tick) Evolve(&m_Snap.m_aCharacters[Item.m_ID].m_Cur, Client()->GameTick()); } } else if(Item.m_Type == NETOBJTYPE_SPECTATORINFO) { m_Snap.m_pSpectatorInfo = (const CNetObj_SpectatorInfo *)pData; m_Snap.m_pPrevSpectatorInfo = (const CNetObj_SpectatorInfo *)Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_SPECTATORINFO, Item.m_ID); m_Snap.m_SpecInfo.m_SpectatorID = m_Snap.m_pSpectatorInfo->m_SpectatorID; } else if(Item.m_Type == NETOBJTYPE_GAMEINFO) { 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 && !(m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_GAMEOVER)) OnStartGame(); 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; if(m_Snap.m_pGameDataObj->m_FlagCarrierRed == FLAG_TAKEN) { if(m_FlagDropTick[TEAM_RED] == 0) m_FlagDropTick[TEAM_RED] = Client()->GameTick(); } else if(m_FlagDropTick[TEAM_RED] != 0) m_FlagDropTick[TEAM_RED] = 0; if(m_Snap.m_pGameDataObj->m_FlagCarrierBlue == FLAG_TAKEN) { if(m_FlagDropTick[TEAM_BLUE] == 0) m_FlagDropTick[TEAM_BLUE] = Client()->GameTick(); } else if(m_FlagDropTick[TEAM_BLUE] != 0) m_FlagDropTick[TEAM_BLUE] = 0; } else if(Item.m_Type == NETOBJTYPE_FLAG) m_Snap.m_paFlags[Item.m_ID%2] = (const CNetObj_Flag *)pData; } } // setup local pointers if(m_Snap.m_LocalClientID >= 0) { CSnapState::CCharacterInfo *c = &m_Snap.m_aCharacters[m_Snap.m_LocalClientID]; if(c->m_Active) { m_Snap.m_pLocalCharacter = &c->m_Cur; m_Snap.m_pLocalPrevCharacter = &c->m_Prev; m_LocalCharacterPos = vec2(m_Snap.m_pLocalCharacter->m_X, m_Snap.m_pLocalCharacter->m_Y); } else if(Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_CHARACTER, m_Snap.m_LocalClientID)) { // player died m_pControls->OnPlayerDeath(); } } else { m_Snap.m_SpecInfo.m_Active = true; if(Client()->State() == IClient::STATE_DEMOPLAYBACK && DemoPlayer()->GetDemoType() == IDemoPlayer::DEMOTYPE_SERVER && m_DemoSpecID != SPEC_FREEVIEW && m_Snap.m_aCharacters[m_DemoSpecID].m_Active) m_Snap.m_SpecInfo.m_SpectatorID = m_DemoSpecID; else m_Snap.m_SpecInfo.m_SpectatorID = SPEC_FREEVIEW; } // clear out unneeded client data for(int i = 0; i < MAX_CLIENTS; ++i) { if(!m_Snap.m_paPlayerInfos[i] && m_aClients[i].m_Active) m_aClients[i].Reset(); } // update friend state for(int i = 0; i < MAX_CLIENTS; ++i) { if(i == m_Snap.m_LocalClientID || !m_Snap.m_paPlayerInfos[i] || !Friends()->IsFriend(m_aClients[i].m_aName, m_aClients[i].m_aClan, true)) m_aClients[i].m_Friend = false; else m_aClients[i].m_Friend = true; } // sort player infos by score mem_copy(m_Snap.m_paInfoByScore, m_Snap.m_paPlayerInfos, sizeof(m_Snap.m_paInfoByScore)); for(int k = 0; k < MAX_CLIENTS-1; k++) // ffs, bubblesort { for(int i = 0; i < MAX_CLIENTS-k-1; i++) { if(m_Snap.m_paInfoByScore[i+1] && (!m_Snap.m_paInfoByScore[i] || m_Snap.m_paInfoByScore[i]->m_Score < m_Snap.m_paInfoByScore[i+1]->m_Score)) { const CNetObj_PlayerInfo *pTmp = m_Snap.m_paInfoByScore[i]; m_Snap.m_paInfoByScore[i] = m_Snap.m_paInfoByScore[i+1]; m_Snap.m_paInfoByScore[i+1] = pTmp; } } } // sort player infos by team int Teams[3] = { TEAM_RED, TEAM_BLUE, TEAM_SPECTATORS }; int Index = 0; for(int Team = 0; Team < 3; ++Team) { for(int i = 0; i < MAX_CLIENTS && Index < MAX_CLIENTS; ++i) { if(m_Snap.m_paPlayerInfos[i] && m_Snap.m_paPlayerInfos[i]->m_Team == Teams[Team]) m_Snap.m_paInfoByTeam[Index++] = m_Snap.m_paPlayerInfos[i]; } } CTuningParams StandardTuning; CServerInfo CurrentServerInfo; Client()->GetServerInfo(&CurrentServerInfo); if(CurrentServerInfo.m_aGameType[0] != '0') { if(str_comp(CurrentServerInfo.m_aGameType, "DM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "TDM") != 0 && str_comp(CurrentServerInfo.m_aGameType, "CTF") != 0) m_ServerMode = SERVERMODE_MOD; else if(mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) == 0) m_ServerMode = SERVERMODE_PURE; else m_ServerMode = SERVERMODE_PUREMOD; } // add tuning to demo if(DemoRecorder()->IsRecording() && mem_comp(&StandardTuning, &m_Tuning, sizeof(CTuningParams)) != 0) { CMsgPacker Msg(NETMSGTYPE_SV_TUNEPARAMS); int *pParams = (int *)&m_Tuning; for(unsigned i = 0; i < sizeof(m_Tuning)/sizeof(int); i++) Msg.AddInt(pParams[i]); Client()->SendMsg(&Msg, MSGFLAG_RECORD|MSGFLAG_NOSEND); } if(!m_DDRaceMsgSent && m_Snap.m_pLocalInfo) { CNetMsg_Cl_IsDDRace Msg; Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); m_DDRaceMsgSent = true; } if(m_ShowOthers == -1 || (m_ShowOthers != -1 && m_ShowOthers != g_Config.m_ClShowOthers)) { // no need to send, default settings //if(!(m_ShowOthers == -1 && g_Config.m_ClShowOthers)) { CNetMsg_Cl_ShowOthers Msg; Msg.m_Show = g_Config.m_ClShowOthers; Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); } // update state m_ShowOthers = g_Config.m_ClShowOthers; } }
void CMenus::RenderGame(CUIRect MainView) { if(m_pClient->m_LocalClientID == -1) return; char aBuf[128]; CSwitchTeamInfo Info; GetSwitchTeamInfo(&Info); CUIRect Button, BottomView, Left, Middle, Right; // cut view MainView.HSplitBottom(80.0f, &MainView, &BottomView); // MainView not used for now BottomView.HSplitTop(20.f, 0, &BottomView); float Spacing = 3.0f; float ButtonWidth = (BottomView.w/6.0f)-(Spacing*5.0)/6.0f; BottomView.VSplitLeft(ButtonWidth*3.0f+Spacing*2.0f, &Left, &Middle); Middle.VSplitLeft(Spacing, 0, &Middle); Middle.VSplitLeft(ButtonWidth, &Middle, &Right); Right.VSplitRight(ButtonWidth, 0, &Right); if(!(m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_TEAMS)) Left.VSplitLeft(ButtonWidth, &Left, 0); // do backgrounds RenderTools()->DrawUIRect4(&Left, vec4(0.0f, 0.0f, 0.0f, 0.25f), vec4(0.0f, 0.0f, 0.0f, 0.25f), vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f), CUI::CORNER_T, 5.0f); RenderTools()->DrawUIRect4(&Middle, vec4(0.0f, 0.0f, 0.0f, 0.25f), vec4(0.0f, 0.0f, 0.0f, 0.25f), vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f), CUI::CORNER_T, 5.0f); RenderTools()->DrawUIRect4(&Right, vec4(0.0f, 0.0f, 0.0f, 0.25f), vec4(0.0f, 0.0f, 0.0f, 0.25f), vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f), CUI::CORNER_T, 5.0f); // do buttons Left.HSplitTop(25.0f, &Left, 0); Middle.HSplitTop(25.0f, &Middle, 0); Right.HSplitTop(25.0f, &Right, 0); if(Info.m_aNotification[0] != 0) { // print notice CUIRect Bar; MainView.HSplitTop(45.0f, &Bar, &MainView); RenderTools()->DrawUIRect(&Bar, vec4(0.0f, 0.0f, 0.0f, 0.25f), CUI::CORNER_B, 10.0f); Bar.HMargin(15.0f, &Bar); UI()->DoLabelScaled(&Bar, Info.m_aNotification, 14.0f, CUI::ALIGN_CENTER); } // join buttons { // specator button int Team = m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team; if(Info.m_aNotification[0] && Team != TEAM_SPECTATORS) { if(Info.m_TimeLeft) str_format(aBuf, sizeof(aBuf), "(%d)", Info.m_TimeLeft); else str_copy(aBuf, Localize("locked"), sizeof(aBuf)); } else str_copy(aBuf, Localize(Team != TEAM_SPECTATORS ? "Spectate" : "Spectating"), sizeof(aBuf)); // Localize("Spectating"); Left.VSplitLeft(ButtonWidth, &Button, &Left); Left.VSplitLeft(Spacing, 0, &Left); static CButtonContainer s_SpectateButton; if(DoButton_Menu(&s_SpectateButton, aBuf, Team == TEAM_SPECTATORS, &Button) && Team != TEAM_SPECTATORS && Info.m_AllowSpec && !(Info.m_aNotification[0])) { m_pClient->SendSwitchTeam(TEAM_SPECTATORS); SetActive(false); } // team button if(m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_TEAMS) { if(Info.m_aNotification[0] && Team != TEAM_RED) { if(Info.m_TimeLeft) str_format(aBuf, sizeof(aBuf), "(%d)", Info.m_TimeLeft); else str_copy(aBuf, Localize("locked"), sizeof(aBuf)); } else str_copy(aBuf, Localize(Team != TEAM_RED ? "Join red" : "Joined red"), sizeof(aBuf)); // Localize("Join red");Localize("Joined red"); Left.VSplitLeft(ButtonWidth, &Button, &Left); Left.VSplitLeft(Spacing, 0, &Left); static CButtonContainer s_RedButton; if(DoButton_Menu(&s_RedButton, aBuf, Team == TEAM_RED, &Button, 0, CUI::CORNER_ALL, 5.0f, 0.0f, vec4(0.975f, 0.17f, 0.17f, 0.75f), false) && Team != TEAM_RED && !(Info.m_aNotification[0])) { m_pClient->SendSwitchTeam(TEAM_RED); SetActive(false); } if(Info.m_aNotification[0] && Team != TEAM_BLUE) { if(Info.m_TimeLeft) str_format(aBuf, sizeof(aBuf), "(%d)", Info.m_TimeLeft); else str_copy(aBuf, Localize("locked"), sizeof(aBuf)); } else str_copy(aBuf, Localize(Team != TEAM_BLUE ? "Join blue" : "Joined blue"), sizeof(aBuf)); // Localize("Join blue");Localize("Joined blue"); Left.VSplitLeft(ButtonWidth, &Button, &Left); static CButtonContainer s_BlueButton; if(DoButton_Menu(&s_BlueButton, aBuf, Team == TEAM_BLUE, &Button, 0, CUI::CORNER_ALL, 5.0f, 0.0f, vec4(0.17f, 0.46f, 0.975f, 0.75f), false) && Team != TEAM_BLUE && !(Info.m_aNotification[0])) { m_pClient->SendSwitchTeam(TEAM_BLUE); SetActive(false); } } else { if(Info.m_aNotification[0] && Team != TEAM_RED) { if(Info.m_TimeLeft) str_format(aBuf, sizeof(aBuf), "(%d)", Info.m_TimeLeft); else str_copy(aBuf, Localize("locked"), sizeof(aBuf)); } else str_copy(aBuf, Localize(Team != TEAM_RED ? "Join" : "Joined"), sizeof(aBuf)); //Localize("Join");Localize("Joined"); Left.VSplitLeft(ButtonWidth, &Button, &Left); static CButtonContainer s_JoinButton; if(DoButton_Menu(&s_JoinButton, aBuf, Team == TEAM_RED, &Button) && Team != TEAM_RED && !(Info.m_aNotification[0])) { m_pClient->SendSwitchTeam(TEAM_RED); SetActive(false); } } } // Record button static CButtonContainer s_DemoButton; bool Recording = DemoRecorder()->IsRecording(); if(DoButton_Menu(&s_DemoButton, Localize(Recording ? "Stop record" : "Record"), Recording, &Middle)) // Localize("Stop record");Localize("Record"); { if(!Recording) Client()->DemoRecorder_Start("demo", true); else Client()->DemoRecorder_Stop(); } // disconnect button static CButtonContainer s_DisconnectButton; if(DoButton_Menu(&s_DisconnectButton, Localize("Disconnect"), 0, &Right)) Client()->Disconnect(); }
void CMenus::RenderGame(CUIRect MainView) { if(m_pClient->m_LocalClientID == -1) return; char aBuf[128]; const char *pNotification = 0; int TeamMod = m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team != TEAM_SPECTATORS ? -1 : 0; bool AllowSpec = true; int TimeLeft = 0; if(TeamMod+m_pClient->m_GameInfo.m_aTeamSize[TEAM_RED]+m_pClient->m_GameInfo.m_aTeamSize[TEAM_BLUE] >= m_pClient->m_ServerSettings.m_PlayerSlots) { str_format(aBuf, sizeof(aBuf), Localize("Only %d active players are allowed"), m_pClient->m_ServerSettings.m_PlayerSlots); pNotification = aBuf; } else if(m_pClient->m_ServerSettings.m_TeamLock) pNotification = Localize("Teams are locked"); else if(m_pClient->m_TeamCooldownTick+1 >= Client()->GameTick()) { TimeLeft = (m_pClient->m_TeamCooldownTick-Client()->GameTick())/Client()->GameTickSpeed()+1; str_format(aBuf, sizeof(aBuf), Localize("Teams are locked. Time to wait before changing team: %02d:%02d"), TimeLeft/60, TimeLeft%60); pNotification = aBuf; AllowSpec = false; } CUIRect Button, BottomView, Left, Middle, Right; // cut view MainView.HSplitBottom(80.0f, &MainView, &BottomView); // MainView not used for now BottomView.HSplitTop(20.f, 0, &BottomView); float Spacing = 3.0f; float ButtonWidth = (BottomView.w/6.0f)-(Spacing*5.0)/6.0f; BottomView.VSplitLeft(ButtonWidth*3.0f+Spacing*2.0f, &Left, &Middle); Middle.VSplitLeft(Spacing, 0, &Middle); Middle.VSplitLeft(ButtonWidth, &Middle, &Right); Right.VSplitRight(ButtonWidth, 0, &Right); if(!(m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_TEAMS)) Left.VSplitLeft(ButtonWidth, &Left, 0); // do backgrounds RenderTools()->DrawUIRect4(&Left, vec4(0.0f, 0.0f, 0.0f, 0.25f), vec4(0.0f, 0.0f, 0.0f, 0.25f), vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f), CUI::CORNER_T, 5.0f); RenderTools()->DrawUIRect4(&Middle, vec4(0.0f, 0.0f, 0.0f, 0.25f), vec4(0.0f, 0.0f, 0.0f, 0.25f), vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f), CUI::CORNER_T, 5.0f); RenderTools()->DrawUIRect4(&Right, vec4(0.0f, 0.0f, 0.0f, 0.25f), vec4(0.0f, 0.0f, 0.0f, 0.25f), vec4(0.0f, 0.0f, 0.0f, 0.0f), vec4(0.0f, 0.0f, 0.0f, 0.0f), CUI::CORNER_T, 5.0f); // do buttons Left.HSplitTop(25.0f, &Left, 0); Middle.HSplitTop(25.0f, &Middle, 0); Right.HSplitTop(25.0f, &Right, 0); if(pNotification != 0) { // print notice CUIRect Bar; MainView.HSplitTop(45.0f, &Bar, &MainView); RenderTools()->DrawUIRect(&Bar, vec4(0.0f, 0.0f, 0.0f, 0.25f), CUI::CORNER_B, 10.0f); Bar.HMargin(15.0f, &Bar); UI()->DoLabelScaled(&Bar, pNotification, 14.0f, 0); } // join buttons { // specator button int Team = m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team; if(pNotification && Team != TEAM_SPECTATORS) { if(TimeLeft) str_format(aBuf, sizeof(aBuf), "(%d)", TimeLeft); else str_copy(aBuf, Localize("locked"), sizeof(aBuf)); } else str_copy(aBuf, Localize(Team != TEAM_SPECTATORS ? "Spectate" : "Spactating"), sizeof(aBuf)); // Localize("Spectating"); Left.VSplitLeft(ButtonWidth, &Button, &Left); Left.VSplitLeft(Spacing, 0, &Left); static int s_SpectateButton = 0; if(DoButton_Menu(&s_SpectateButton, aBuf, Team == TEAM_SPECTATORS, &Button) && Team != TEAM_SPECTATORS && AllowSpec && !pNotification) { m_pClient->SendSwitchTeam(TEAM_SPECTATORS); SetActive(false); } // team button if(m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_TEAMS) { if(pNotification && Team != TEAM_RED) { if(TimeLeft) str_format(aBuf, sizeof(aBuf), "(%d)", TimeLeft); else str_copy(aBuf, Localize("locked"), sizeof(aBuf)); } else str_copy(aBuf, Localize(Team != TEAM_RED ? "Join red" : "Joined red"), sizeof(aBuf)); // Localize("Join red");Localize("Joined red"); Left.VSplitLeft(ButtonWidth, &Button, &Left); Left.VSplitLeft(Spacing, 0, &Left); static int s_RedButton = 0; if(DoButton_Menu(&s_RedButton, aBuf, Team == TEAM_RED, &Button, CUI::CORNER_ALL, 5.0f, 0.0f, vec4(0.975f, 0.17f, 0.17f, 0.75f), false) && Team != TEAM_RED && !pNotification) { m_pClient->SendSwitchTeam(TEAM_RED); SetActive(false); } if(pNotification && Team != TEAM_BLUE) { if(TimeLeft) str_format(aBuf, sizeof(aBuf), "(%d)", TimeLeft); else str_copy(aBuf, Localize("locked"), sizeof(aBuf)); } else str_copy(aBuf, Localize(Team != TEAM_BLUE ? "Join blue" : "Joined blue"), sizeof(aBuf)); // Localize("Join blue");Localize("Joined blue"); Left.VSplitLeft(ButtonWidth, &Button, &Left); static int s_BlueButton = 0; if(DoButton_Menu(&s_BlueButton, aBuf, Team == TEAM_BLUE, &Button, CUI::CORNER_ALL, 5.0f, 0.0f, vec4(0.17f, 0.46f, 0.975f, 0.75f), false) && Team != TEAM_BLUE && !pNotification) { m_pClient->SendSwitchTeam(TEAM_BLUE); SetActive(false); } } else { if(pNotification && Team != TEAM_RED) { if(TimeLeft) str_format(aBuf, sizeof(aBuf), "(%d)", TimeLeft); else str_copy(aBuf, Localize("locked"), sizeof(aBuf)); } else str_copy(aBuf, Localize(Team != TEAM_RED ? "Join" : "Joined"), sizeof(aBuf)); //Localize("Join");Localize("Joined"); Left.VSplitLeft(ButtonWidth, &Button, &Left); static int s_JoinButton = 0; if(DoButton_Menu(&s_JoinButton, aBuf, Team == TEAM_RED, &Button) && Team != TEAM_RED && !pNotification) { m_pClient->SendSwitchTeam(0); SetActive(false); } } } // Record button static int s_DemoButton = 0; bool Recording = DemoRecorder()->IsRecording(); if(DoButton_Menu(&s_DemoButton, Localize(Recording ? "Stop record" : "Record"), Recording, &Middle)) // Localize("Stop record");Localize("Record"); { if(!Recording) Client()->DemoRecorder_Start("demo", true); else Client()->DemoRecorder_Stop(); } // disconnect button static int s_DisconnectButton = 0; if(DoButton_Menu(&s_DisconnectButton, Localize("Disconnect"), 0, &Right)) Client()->Disconnect(); }
void CMenus::RenderGame(CUIRect MainView) { CUIRect Button, ButtonBar; MainView.HSplitTop(45.0f, &ButtonBar, &MainView); RenderTools()->DrawUIRect(&ButtonBar, ms_ColorTabbarActive, CUI::CORNER_ALL, 10.0f); // button bar ButtonBar.HSplitTop(10.0f, 0, &ButtonBar); ButtonBar.HSplitTop(25.0f, &ButtonBar, 0); ButtonBar.VMargin(10.0f, &ButtonBar); ButtonBar.VSplitRight(120.0f, &ButtonBar, &Button); static int s_DisconnectButton = 0; if(DoButton_Menu(&s_DisconnectButton, Localize("Disconnect"), 0, &Button)) Client()->Disconnect(); if(m_pClient->m_Snap.m_pLocalInfo && m_pClient->m_Snap.m_pGameInfoObj) { if(m_pClient->m_Snap.m_pLocalInfo->m_Team != TEAM_SPECTATORS) { ButtonBar.VSplitLeft(10.0f, 0, &ButtonBar); ButtonBar.VSplitLeft(120.0f, &Button, &ButtonBar); static int s_SpectateButton = 0; if(DoButton_Menu(&s_SpectateButton, Localize("Spectate"), 0, &Button)) { m_pClient->SendSwitchTeam(TEAM_SPECTATORS); SetActive(false); } } if(m_pClient->m_Snap.m_pGameInfoObj->m_GameFlags & GAMEFLAG_TEAMS) { if(m_pClient->m_Snap.m_pLocalInfo->m_Team != TEAM_RED) { ButtonBar.VSplitLeft(10.0f, 0, &ButtonBar); ButtonBar.VSplitLeft(120.0f, &Button, &ButtonBar); static int s_SpectateButton = 0; if(DoButton_Menu(&s_SpectateButton, Localize("Join red"), 0, &Button)) { m_pClient->SendSwitchTeam(TEAM_RED); SetActive(false); } } if(m_pClient->m_Snap.m_pLocalInfo->m_Team != TEAM_BLUE) { ButtonBar.VSplitLeft(10.0f, 0, &ButtonBar); ButtonBar.VSplitLeft(120.0f, &Button, &ButtonBar); static int s_SpectateButton = 0; if(DoButton_Menu(&s_SpectateButton, Localize("Join blue"), 0, &Button)) { m_pClient->SendSwitchTeam(TEAM_BLUE); SetActive(false); } } } else { if(m_pClient->m_Snap.m_pLocalInfo->m_Team != 0) { ButtonBar.VSplitLeft(10.0f, 0, &ButtonBar); ButtonBar.VSplitLeft(120.0f, &Button, &ButtonBar); static int s_SpectateButton = 0; if(DoButton_Menu(&s_SpectateButton, Localize("Join game"), 0, &Button)) { m_pClient->SendSwitchTeam(0); SetActive(false); } } } } ButtonBar.VSplitLeft(100.0f, 0, &ButtonBar); ButtonBar.VSplitLeft(150.0f, &Button, &ButtonBar); static int s_DemoButton = 0; bool Recording = DemoRecorder()->IsRecording(); if(DoButton_Menu(&s_DemoButton, Localize(Recording ? "Stop record" : "Record demo"), 0, &Button)) // Localize("Stop record");Localize("Record demo"); { if(!Recording) Client()->DemoRecorder_Start("demo", true); else Client()->DemoRecorder_Stop(); } }
void CMenus::RenderGame(CUIRect MainView) { if(m_pClient->m_LocalClientID == -1) return; char aBuf[128]; CSwitchTeamInfo Info = { 0 }; GetSwitchTeamInfo(&Info); CUIRect Button, ButtonRow, Label; float Spacing = 3.0f; float ButtonWidth = (MainView.w/6.0f)-(Spacing*5.0)/6.0f; // cut view MainView.HSplitTop(20.0f, 0, &MainView); float NoteHeight = !Info.m_aNotification[0] ? 0.0f : 45.0f; MainView.HSplitTop(20.0f+20.0f+2*Spacing+ NoteHeight, &MainView, 0); RenderTools()->DrawUIRect(&MainView, vec4(0.0f, 0.0f, 0.0f, ms_BackgroundAlpha), CUI::CORNER_ALL, 5.0f); // game options MainView.HSplitTop(20.0f, &Label, &MainView); Label.y += 2.0f; UI()->DoLabel(&Label, Localize("Game options"), 20.0f*ms_FontmodHeight*0.8f, CUI::ALIGN_CENTER); RenderTools()->DrawUIRect(&MainView, vec4(0.0, 0.0, 0.0, 0.25f), CUI::CORNER_ALL, 5.0f); if(Info.m_aNotification[0] != 0) { // print notice CUIRect Bar; MainView.HSplitBottom(NoteHeight, &MainView, &Bar); Bar.HMargin(15.0f, &Bar); UI()->DoLabelScaled(&Bar, Info.m_aNotification, 14.0f, CUI::ALIGN_CENTER); } // buttons { MainView.HSplitTop(Spacing, 0, &MainView); MainView.HSplitTop(20.0f, &ButtonRow, 0); ButtonRow.VMargin(Spacing, &ButtonRow); // specator button int Team = m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team; if(Info.m_aNotification[0] && Team != TEAM_SPECTATORS) { if(Info.m_TimeLeft) str_format(aBuf, sizeof(aBuf), "(%d)", Info.m_TimeLeft); else str_copy(aBuf, Localize("locked"), sizeof(aBuf)); } else str_copy(aBuf, Localize(Team != TEAM_SPECTATORS ? "Spectate" : "Spectating"), sizeof(aBuf)); // Localize("Spectating"); ButtonRow.VSplitLeft(ButtonWidth, &Button, &ButtonRow); ButtonRow.VSplitLeft(Spacing, 0, &ButtonRow); static CButtonContainer s_SpectateButton; if(DoButton_Menu(&s_SpectateButton, aBuf, Team == TEAM_SPECTATORS, &Button) && Team != TEAM_SPECTATORS && Info.m_AllowSpec && !(Info.m_aNotification[0])) { m_pClient->SendSwitchTeam(TEAM_SPECTATORS); SetActive(false); } // team button if(m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_TEAMS) { int RedTeamSizeNew = m_pClient->m_GameInfo.m_aTeamSize[TEAM_RED]; if(Team != TEAM_RED) ++RedTeamSizeNew; else if(Team == TEAM_RED) --RedTeamSizeNew; int BlueTeamSizeNew = m_pClient->m_GameInfo.m_aTeamSize[TEAM_BLUE]; if(Team != TEAM_BLUE) ++BlueTeamSizeNew; else if(Team == TEAM_BLUE) --BlueTeamSizeNew; bool BlockRed = m_pClient->m_ServerSettings.m_TeamBalance && (RedTeamSizeNew - BlueTeamSizeNew >= NUM_TEAMS); bool BlockBlue = m_pClient->m_ServerSettings.m_TeamBalance && (BlueTeamSizeNew - RedTeamSizeNew >= NUM_TEAMS); if((Info.m_aNotification[0] && Team != TEAM_RED) || BlockRed) { if(Info.m_TimeLeft) str_format(aBuf, sizeof(aBuf), "(%d)", Info.m_TimeLeft); else str_copy(aBuf, Localize("locked"), sizeof(aBuf)); } else str_copy(aBuf, Localize(Team != TEAM_RED ? "Join red" : "Joined red"), sizeof(aBuf)); // Localize("Join red");Localize("Joined red"); ButtonRow.VSplitLeft(ButtonWidth, &Button, &ButtonRow); ButtonRow.VSplitLeft(Spacing, 0, &ButtonRow); static CButtonContainer s_RedButton; if(DoButton_Menu(&s_RedButton, aBuf, Team == TEAM_RED, &Button, 0, CUI::CORNER_ALL, 5.0f, 0.0f, vec4(0.975f, 0.17f, 0.17f, 0.75f), false) && Team != TEAM_RED && !(Info.m_aNotification[0]) && !BlockRed) { m_pClient->SendSwitchTeam(TEAM_RED); SetActive(false); } if((Info.m_aNotification[0] && Team != TEAM_BLUE) || BlockBlue) { if(Info.m_TimeLeft) str_format(aBuf, sizeof(aBuf), "(%d)", Info.m_TimeLeft); else str_copy(aBuf, Localize("locked"), sizeof(aBuf)); } else str_copy(aBuf, Localize(Team != TEAM_BLUE ? "Join blue" : "Joined blue"), sizeof(aBuf)); // Localize("Join blue");Localize("Joined blue"); ButtonRow.VSplitLeft(ButtonWidth, &Button, &ButtonRow); ButtonRow.VSplitLeft(Spacing, 0, &ButtonRow); static CButtonContainer s_BlueButton; if(DoButton_Menu(&s_BlueButton, aBuf, Team == TEAM_BLUE, &Button, 0, CUI::CORNER_ALL, 5.0f, 0.0f, vec4(0.17f, 0.46f, 0.975f, 0.75f), false) && Team != TEAM_BLUE && !(Info.m_aNotification[0]) && !BlockBlue) { m_pClient->SendSwitchTeam(TEAM_BLUE); SetActive(false); } } else { if(Info.m_aNotification[0] && Team != TEAM_RED) { if(Info.m_TimeLeft) str_format(aBuf, sizeof(aBuf), "(%d)", Info.m_TimeLeft); else str_copy(aBuf, Localize("locked"), sizeof(aBuf)); } else str_copy(aBuf, Localize(Team != TEAM_RED ? "Join" : "Joined"), sizeof(aBuf)); //Localize("Join");Localize("Joined"); ButtonRow.VSplitLeft(ButtonWidth, &Button, &ButtonRow); static CButtonContainer s_JoinButton; if(DoButton_Menu(&s_JoinButton, aBuf, Team == TEAM_RED, &Button) && Team != TEAM_RED && !(Info.m_aNotification[0])) { m_pClient->SendSwitchTeam(TEAM_RED); SetActive(false); } } // disconnect button ButtonRow.VSplitRight(ButtonWidth, &ButtonRow, &Button); static CButtonContainer s_DisconnectButton; if(DoButton_Menu(&s_DisconnectButton, Localize("Disconnect"), 0, &Button)) Client()->Disconnect(); // Record button ButtonRow.VSplitRight(50.0f, &ButtonRow, 0); ButtonRow.VSplitRight(ButtonWidth, &ButtonRow, &Button); static CButtonContainer s_DemoButton; bool Recording = DemoRecorder()->IsRecording(); if(DoButton_Menu(&s_DemoButton, Localize(Recording ? "Stop record" : "Record"), Recording, &Button)) // Localize("Stop record");Localize("Record"); { if(!Recording) Client()->DemoRecorder_Start("demo", true); else Client()->DemoRecorder_Stop(); } } }