bool C4PlayerList::HasPlayerInTeamSelection() { for (C4Player *pPlr = First; pPlr; pPlr = pPlr->Next) if (pPlr->IsChosingTeam()) return true; return false; }
void C4Team::AddPlayer(C4PlayerInfo &rInfo, bool fAdjustPlayer) { // must not happen! assert(rInfo.GetID()); if (!rInfo.GetID()) return; // add player; grow vector if necessary if (iPlayerCount >= iPlayerCapacity) { int32_t *piNewPlayers = new int32_t[iPlayerCapacity = (iPlayerCount+4)&~3]; if (iPlayerCount) memcpy(piNewPlayers, piPlayers, iPlayerCount*sizeof(int32_t)); delete [] piPlayers; piPlayers = piNewPlayers; } // store new player piPlayers[iPlayerCount++] = rInfo.GetID(); if (!fAdjustPlayer) return; // set values in info rInfo.SetTeam(GetID()); if (Game.Teams.IsTeamColors()) rInfo.SetColor(GetColor()); // and in actual player, if it is joined already if (rInfo.IsJoined()) { C4Player *pJoinedPlr = ::Players.GetByInfoID(rInfo.GetID()); assert(pJoinedPlr || (rInfo.GetType() == C4PT_Script)); if (pJoinedPlr) { pJoinedPlr->Team = GetID(); if (Game.Teams.IsTeamColors()) pJoinedPlr->SetPlayerColor(GetColor()); } } }
C4Network2Stats::C4Network2Stats() : pSec1Timer(NULL) { // set self (needed in CreateGraph-fns) Game.pNetworkStatistics = this; // init callback timer pSec1Timer = new C4Sec1TimerCallback<C4Network2Stats>(this); SecondCounter = 0; ControlCounter = 0; // init graphs statObjCount.SetTitle(LoadResStr("IDS_MSG_OBJCOUNT")); statFPS.SetTitle(LoadResStr("IDS_MSG_FPS")); statNetI.SetTitle(LoadResStr("IDS_NET_INPUT")); statNetI.SetColorDw(0x00ff00); statNetO.SetTitle(LoadResStr("IDS_NET_OUTPUT")); statNetO.SetColorDw(0xff0000); graphNetIO.AddGraph(&statNetI); graphNetIO.AddGraph(&statNetO); statControls.SetTitle(LoadResStr("IDS_NET_CONTROL")); statControls.SetAverageTime(100); statActions.SetTitle(LoadResStr("IDS_NET_APM")); statActions.SetAverageTime(100); for (C4Player *pPlr = Game.Players.First; pPlr; pPlr = pPlr->Next) pPlr->CreateGraphs(); C4Network2Client *pClient = NULL; while (pClient = Game.Network.Clients.GetNextClient(pClient)) pClient->CreateGraphs(); }
C4Network2Stats::~C4Network2Stats() { for (C4Player *pPlr = Game.Players.First; pPlr; pPlr = pPlr->Next) pPlr->ClearGraphs(); C4Network2Client *pClient = NULL; while (pClient = Game.Network.Clients.GetNextClient(pClient)) pClient->ClearGraphs(); pSec1Timer->Release(); }
void C4GameOverDlg::OnShown() { // close some other dialogs Game.Scoreboard.HideDlg(); FullScreen.CloseMenu(); for (C4Player *plr = Game.Players.First; plr; plr = plr->Next) plr->CloseMenu(); // pause game when round results dlg is shown Game.Pause(); }
void C4PlayerList::Execute() { C4Player *pPlr; // Execute for (pPlr=First; pPlr; pPlr=pPlr->Next) pPlr->Execute(); // Check retirement for (pPlr=First; pPlr; pPlr=pPlr->Next) if (pPlr->Eliminated && !pPlr->RetireDelay) { Retire(pPlr); break; } }
bool C4PlayerList::RemoveAtRemoteClient(bool fDisconnect, bool fNoCalls) { C4Player *pPlr; // Get players while ((pPlr = GetAtRemoteClient())) { // Log Log(FormatString(LoadResStr("IDS_PRC_REMOVEPLR"),pPlr->GetName()).getData()); // Remove Remove(pPlr, fDisconnect, fNoCalls); } return true; }
bool C4PlayerList::RemoveAtClient(const char *szName, bool fDisconnect) { C4Player *pPlr; // Get players while ((pPlr = GetAtClient(szName))) { // Log Log(FormatString(LoadResStr("IDS_PRC_REMOVEPLR"),pPlr->GetName()).getData()); // Remove Remove(pPlr, fDisconnect, false); } return true; }
C4GUI::Edit::InputResult C4ChatInputDialog::OnChatInput(C4GUI::Edit *edt, bool fPasting, bool fPastingMore) { // no double processing if (fProcessed) return C4GUI::Edit::IR_CloseDlg; // get edit text C4GUI::Edit *pEdt = reinterpret_cast<C4GUI::Edit *>(edt); char *szInputText = const_cast<char *>(pEdt->GetText()); // Store to back buffer Game.MessageInput.StoreBackBuffer(szInputText); // script queried input? if (fObjInput) { fProcessed = true; // check if the target input is still valid C4Player *pPlr = Game.Players.Get(iPlr); if (!pPlr) return C4GUI::Edit::IR_CloseDlg; if (!pPlr->MarkMessageBoardQueryAnswered(pTarget)) { // there was no associated query! return C4GUI::Edit::IR_CloseDlg; } // then do a script callback, incorporating the input into the answer if (fUppercase) SCapitalize(szInputText); StdStrBuf sInput; sInput.Copy(szInputText); sInput.EscapeString(); Game.Control.DoInput( CID_Script, new C4ControlScript( FormatString("OnMessageBoardAnswer(Object(%d), %d, \"%s\")", pTarget ? pTarget->Number : 0, iPlr, sInput.getData()).getData()), CDT_Decide); return C4GUI::Edit::IR_CloseDlg; } else // reroute to message input class Game.MessageInput.ProcessInput(szInputText); // safety: message board commands may do strange things if (!C4GUI::IsGUIValid() || this != pInstance) return C4GUI::Edit::IR_Abort; // select all text to be removed with next keypress // just for pasting mode; usually the dlg will be closed now anyway pEdt->SelectAll(); // avoid dlg close, if more content is to be pasted if (fPastingMore) return C4GUI::Edit::IR_None; fProcessed = true; return C4GUI::Edit::IR_CloseDlg; }
bool C4ChatInputDialog::KeyCompleteNick() { if (!pEdit) return false; char IncompleteNick[256 + 1]; // get current word in edit if (!pEdit->GetCurrentWord(IncompleteNick, 256)) return false; if (!*IncompleteNick) return false; C4Player *plr = Game.Players.First; while (plr) { // Compare name and input if (SEqualNoCase(plr->GetName(), IncompleteNick, SLen(IncompleteNick))) { pEdit->InsertText(plr->GetName() + SLen(IncompleteNick), true); return true; } else plr = plr->Next; } // no match found return false; }
bool C4PlayerList::RemoveLocal(bool fDisconnect, bool fNoCalls) { // (used by league system the set local fate) C4Player *pPlr; do for (pPlr = First; pPlr; pPlr = pPlr->Next) if (pPlr->LocalControl) { // Log Log(FormatString(LoadResStr("IDS_PRC_REMOVEPLR"),pPlr->GetName()).getData()); // Remove Remove(pPlr, fDisconnect, fNoCalls); break; } while (pPlr); return true; }
void C4ChatInputDialog::OnChatCancel() { // abort chat: Make sure msg board query is aborted fProcessed = true; if (fObjInput) { // check if the target input is still valid C4Player *pPlr = Game.Players.Get(iPlr); if (!pPlr) return; if (pPlr->MarkMessageBoardQueryAnswered(pTarget)) { // there was an associated query - it must be removed on all clients // synchronized via queue // do this by calling OnMessageBoardAnswer without an answer Game.Control.DoInput( CID_Script, new C4ControlScript( FormatString("OnMessageBoardAnswer(Object(%d), %d, 0)", pTarget ? pTarget->Number : 0, iPlr).getData()), CDT_Decide); } } }
C4Player* C4PlayerList::Join(const char *szFilename, bool fScenarioInit, int iAtClient, const char *szAtClientName, C4PlayerInfo *pInfo, C4ValueNumbers * numbers) { assert(pInfo); assert(fScenarioInit || numbers); // safeties if (szFilename && !*szFilename) szFilename = NULL; // Log LogF(LoadResStr(fScenarioInit ? "IDS_PRC_JOINPLR" : "IDS_PRC_RECREATE"),pInfo->GetName()); // Too many players if (1) // replay needs to check, too! if (GetCount()+1>Game.Parameters.MaxPlayers) { LogF(LoadResStr("IDS_PRC_TOOMANYPLRS"),Game.Parameters.MaxPlayers); return NULL; } // Check duplicate file usage if (szFilename) if (FileInUse(szFilename)) { Log(LoadResStr("IDS_PRC_PLRFILEINUSE")); return NULL; } // Create C4Player *pPlr = new C4Player; // Append to player list C4Player *pLast=First; while (pLast && pLast->Next) pLast=pLast->Next; if (pLast) pLast->Next=pPlr; else First = pPlr; // Init if (!pPlr->Init(GetFreeNumber(),iAtClient,szAtClientName,szFilename,fScenarioInit,pInfo, numbers)) { Remove(pPlr, false, false); Log(LoadResStr("IDS_PRC_JOINFAIL")); return NULL; } // Done return pPlr; }
bool C4MainMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand) { // Determine player C4Player *pPlr = ::Players.Get(Player); // Activate if (SEqual2(szCommand,"ActivateMenu:")) { if (C4GameOverDlg::IsShown()) return false; // no new menus during game over dlg if (SEqual(szCommand+13,"Main")) return ActivateMain(Player); if (SEqual(szCommand+13,"Hostility")) return ActivateHostility(Player); if (SEqual(szCommand+13,"NewPlayer")) return ActivateNewPlayer(Player); if (SEqual(szCommand+13,"Goals")) { ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::ActivateGoalMenu(::Players.Get(Player)), CDT_Queue); return true; } if (SEqual(szCommand+13,"Rules")) return ActivateRules(Player); if (SEqual(szCommand+13,"Host")) return ActivateHost(Player); if (SEqual(szCommand+13,"Client")) return ActivateClient(Player); if (SEqual(szCommand+13,"Options")) return ActivateOptions(Player); if (SEqual(szCommand+13,"Display")) return ActivateDisplay(Player); if (SEqual(szCommand+13,"Save:Game")) return ActivateSavegame(Player); if (SEqual(szCommand+13,"TeamSel")) return pPlr ? pPlr->ActivateMenuTeamSelection(true) : false; if (SEqual(szCommand+13,"Surrender")) return ActivateSurrender(Player); if (SEqual(szCommand+13,"Observer")) return ActivateObserver(); } // JoinPlayer if (SEqual2(szCommand,"JoinPlayer:")) { // not in league or replay mode if (Game.Parameters.isLeague() || Game.C4S.Head.Replay) return false; // join player // 2do: not for observers and such? Players.JoinNew(szCommand+11); return true; } // SetHostility if (SEqual2(szCommand,"SetHostility:")) { // only if allowed if (!Game.Teams.IsHostilityChangeAllowed()) return false; int32_t iOpponent; sscanf(szCommand+13,"%i",&iOpponent); C4Player *pOpponent = ::Players.Get(iOpponent); if (!pOpponent || pOpponent->GetType() != C4PT_User) return false; ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::SetHostility(::Players.Get(Player), pOpponent, !::Players.HostilityDeclared(Player, pOpponent->Number)), CDT_Queue); return true; } // Abort if (SEqual2(szCommand,"Abort")) { FullScreen.ShowAbortDlg(); return true; } // Surrender if (SEqual2(szCommand,"Surrender")) { ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::Surrender(::Players.Get(Player)), CDT_Queue); return true; } // Save game if (SEqual2(szCommand, "Save:Game:")) { char strFilename[_MAX_PATH + 1]; SCopySegment(szCommand, 2, strFilename, ':', _MAX_PATH); char strTitle[_MAX_PATH + 1]; SCopy(szCommand + SCharPos(':', szCommand, 2) + 1, strTitle, _MAX_PATH); Game.QuickSave(strFilename, strTitle); ActivateSavegame(Player); return true; } // Kick if (SEqual2(szCommand,"Host:Kick:")) { int iClientID = atoi(szCommand+10); if (iClientID && ::Network.isEnabled()) { if (Game.Parameters.isLeague() && ::Players.GetAtClient(iClientID)) ::Network.Vote(VT_Kick, true, iClientID); else { C4Client *pClient = Game.Clients.getClientByID(iClientID); if (pClient) Game.Clients.CtrlRemove(pClient, LoadResStr("IDS_MSG_KICKBYMENU")); Close(true); } } return true; } // Part if (SEqual2(szCommand,"Part")) { if (::Network.isEnabled()) { if (Game.Parameters.isLeague() && ::Players.GetLocalByIndex(0)) ::Network.Vote(VT_Kick, true, ::Control.ClientID()); else { Game.RoundResults.EvaluateNetwork(C4RoundResults::NR_NetError, LoadResStr("IDS_ERR_GAMELEFTVIAPLAYERMENU")); ::Network.Clear(); } } return true; } // Options if (SEqual2(szCommand,"Options:")) { // Music if (SEqual(szCommand + 8, "Music")) { Application.MusicSystem.ToggleOnOff(); } // Sound if (SEqual(szCommand + 8, "Sound")) { if (Config.Sound.RXSound) { Application.SoundSystem.Clear(); Config.Sound.RXSound = false; } else { Config.Sound.RXSound = true; if (!Application.SoundSystem.Init()) { Log(LoadResStr("IDS_PRC_NOSND")); } } } // Reopen with updated options ActivateOptions(Player, GetSelection()); return true; } // Display if (SEqual2(szCommand,"Display:")) { // Upper board if (SEqual(szCommand + 8, "UpperBoard")) { Config.Graphics.UpperBoard = !Config.Graphics.UpperBoard; ::Viewports.RecalculateViewports(); } // FPS if (SEqual(szCommand + 8, "FPS")) Config.General.FPS = !Config.General.FPS; // Player names if (SEqual(szCommand + 8, "PlayerNames")) Config.Graphics.ShowCrewNames = !Config.Graphics.ShowCrewNames; // Clonk names if (SEqual(szCommand + 8, "ClonkNames")) Config.Graphics.ShowCrewCNames = !Config.Graphics.ShowCrewCNames; // Clock if (SEqual(szCommand + 8, "Clock")) Config.Graphics.ShowClock = !Config.Graphics.ShowClock; // Reopen with updated options ActivateDisplay(Player, GetSelection()); return true; } // Goal info if (SEqual2(szCommand,"Player:Goal:") || SEqual2(szCommand,"Player:Rule:")) { if (!ValidPlr(Player)) return false; // observers may not look at goal/rule info, because it requires queue activation Close(true); C4Object *pObj; C4ID idItem(szCommand+12); C4Def * pDef = C4Id2Def(idItem); if (pDef && (pObj = ::Objects.Find(pDef))) ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::ActivateGoal(::Players.Get(Player), pObj), CDT_Queue); else return false; return true; } // Team selection if (SEqual2(szCommand, "TeamSel:")) { Close(true); int32_t idTeam = atoi(szCommand+8); // OK, join this team if (pPlr) pPlr->DoTeamSelection(idTeam); return true; } // Team switch if (SEqual2(szCommand, "TeamSwitch:")) { Close(true); int32_t idTeam = atoi(szCommand+11); // check if it's still allowed if (!Game.Teams.IsTeamSwitchAllowed()) return false; // OK, join this team ::Control.DoInput(CID_PlrAction, C4ControlPlayerAction::SetTeam(::Players.Get(Player), idTeam), CDT_Queue); return true; } // Observe if (SEqual2(szCommand, "Observe:")) { const char *szObserverTarget = szCommand+8; C4Viewport *pVP = ::Viewports.GetViewport(NO_OWNER); if (pVP) // viewport may have closed meanwhile { if (SEqual(szObserverTarget, "Free")) { // free view pVP->Init(NO_OWNER, true); return true; } else { // view following player int32_t iPlr = atoi(szObserverTarget); if (ValidPlr(iPlr)) { pVP->Init(iPlr, true); return true; } } } return false; } // No valid command return false; }
bool C4MainMenu::DoRefillInternal(bool &rfRefilled) { // Variables C4FacetSurface fctSymbol; C4Player *pPlayer; C4IDList ListItems; C4Facet fctTarget; bool fWasEmpty = !GetItemCount(); // Refill switch (Identification) { // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MN_Hostility: { // Clear items ClearItems(); // Refill player if (!(pPlayer = ::Players.Get(Player))) return false; // Refill items C4Player *pPlr; int32_t iIndex; for (iIndex=0; (pPlr = ::Players.GetByIndex(iIndex)); iIndex++) // Ignore player self and invisible if (pPlr != pPlayer) if (!pPlr->IsInvisible()) { // Symbol fctSymbol.Create(C4SymbolSize,C4SymbolSize); pPlayer->DrawHostility(fctSymbol,iIndex); // Message StdStrBuf sMsg; bool isFriendly = pPlayer->Hostility.find(pPlr) == pPlayer->Hostility.end(); if (isFriendly) sMsg.Format(LoadResStr("IDS_MENU_ATTACK"),pPlr->GetName()); else sMsg.Format(LoadResStr("IDS_MENU_NOATTACK"),pPlr->GetName()); // Command char szCommand[1000]; sprintf(szCommand,"SetHostility:%i",pPlr->Number); // Info caption char szInfoCaption[C4MaxTitle+1],szFriendly[50],szNot[30]=""; SCopy(LoadResStr(isFriendly ? "IDS_MENU_ATTACKHOSTILE" : "IDS_MENU_ATTACKFRIENDLY"),szFriendly); if (!isFriendly) SCopy(LoadResStr("IDS_MENU_ATTACKNOT"),szNot); sprintf(szInfoCaption,LoadResStr("IDS_MENU_ATTACKINFO"),pPlr->GetName(),szFriendly,szNot); if (iIndex==pPlayer->Number) SCopy(LoadResStr("IDS_MENU_ATTACKSELF"),szInfoCaption); // Add item Add(sMsg.getData(),fctSymbol,szCommand,C4MN_Item_NoCount,NULL,szInfoCaption); fctSymbol.Default(); } break; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MN_TeamSelection: case C4MN_TeamSwitch: { // Clear items ClearItems(); // add all teams as menu items // 2do: Icon C4Team *pTeam; int32_t i=0; bool fAddNewTeam=Game.Teams.IsAutoGenerateTeams(); for (;;) { pTeam = Game.Teams.GetTeamByIndex(i); if (pTeam) { // next regular team ++i; // do not add a new team if an empty team exists if (!pTeam->GetPlayerCount()) fAddNewTeam = false; } else if (fAddNewTeam) { // join new team fAddNewTeam = false; } else { // all teams done break; } // create team symbol: Icon spec if specified; otherwise flag for empty and crew for nonempty team fctSymbol.Create(C4SymbolSize,C4SymbolSize); const char *szIconSpec = pTeam ? pTeam->GetIconSpec() : NULL; bool fHasIcon = false; if (szIconSpec && *szIconSpec) { fHasIcon = Game.DrawTextSpecImage(fctSymbol, szIconSpec, NULL, pTeam->GetColor()); } if (!fHasIcon) { if (pTeam && pTeam->GetPlayerCount()) ::GraphicsResource.fctCrewClr.DrawClr(fctSymbol, true, pTeam->GetColor()); else C4GUI::Icon::GetIconFacet(C4GUI::Ico_Team).Draw(fctSymbol, true); } StdStrBuf sTeamName; if (pTeam) { sTeamName.Take(pTeam->GetNameWithParticipants()); } else sTeamName.Ref(LoadResStr("IDS_PRC_NEWTEAM")); const char *szOperation = (Identification == C4MN_TeamSwitch) ? "TeamSwitch" : "TeamSel"; Add(sTeamName.getData(), fctSymbol,FormatString("%s:%d", szOperation, pTeam ? pTeam->GetID() : TEAMID_New).getData(), C4MN_Item_NoCount,NULL,FormatString(LoadResStr("IDS_MSG_JOINTEAM"), sTeamName.getData()).getData(), C4ID(pTeam ? pTeam->GetID() : 0)); fctSymbol.Default(); } break; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - case C4MN_Observer: // observer menu { // Clear items ClearItems(); // Check validity C4Viewport *pVP = ::Viewports.GetViewport(NO_OWNER); if (!pVP) return false; int32_t iInitialSelection = 0; // Add free view AddRefSym(LoadResStr("IDS_MSG_FREEVIEW"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Star), "Observe:Free", C4MN_Item_NoCount, NULL, LoadResStr("IDS_MSG_FREELYSCROLLAROUNDTHEMAP")); // Add players C4Player *pPlr; int32_t iIndex; for (iIndex=0; (pPlr = ::Players.GetByIndex(iIndex)); iIndex++) { // Ignore invisible if (!pPlr->IsInvisible()) { // Symbol fctSymbol.Create(C4SymbolSize,C4SymbolSize); ::GraphicsResource.fctPlayerClr.DrawClr(fctSymbol, true, pPlr->ColorDw); // Message StdStrBuf sMsg; DWORD dwClr = pPlr->ColorDw; sMsg.Format("<c %x>%s</c>", (unsigned int)C4GUI::MakeColorReadableOnBlack(dwClr), pPlr->GetName()); // Command StdStrBuf sCommand; sCommand.Format("Observe:%d", (int)pPlr->Number); // Info caption StdStrBuf sInfo; sInfo.Format(LoadResStr("IDS_TEXT_FOLLOWVIEWOFPLAYER"), pPlr->GetName()); // Add item Add(sMsg.getData(),fctSymbol,sCommand.getData(),C4MN_Item_NoCount,NULL,sInfo.getData()); fctSymbol.Default(); // check if this is the currently selected player if (pVP->GetPlayer() == pPlr->Number) iInitialSelection = GetItemCount()-1; } // Initial selection on followed player if (fWasEmpty) SetSelection(iInitialSelection, false, true); } } break; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - default: // No internal refill needed return true; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } // Successfull internal refill rfRefilled = true; return true; }