| 1 | /* |
| 2 | * LegacyClonk |
| 3 | * |
| 4 | * Copyright (c) 1998-2000, Matthes Bender (RedWolf Design) |
| 5 | * Copyright (c) 2017-2022, The LegacyClonk Team and contributors |
| 6 | * |
| 7 | * Distributed under the terms of the ISC license; see accompanying file |
| 8 | * "COPYING" for details. |
| 9 | * |
| 10 | * "Clonk" is a registered trademark of Matthes Bender, used with permission. |
| 11 | * See accompanying file "TRADEMARK" for details. |
| 12 | * |
| 13 | * To redistribute this file separately, substitute the full license texts |
| 14 | * for the above references. |
| 15 | */ |
| 16 | |
| 17 | /* Player data at runtime */ |
| 18 | |
| 19 | #pragma once |
| 20 | |
| 21 | #include "C4EnumeratedObjectPtr.h" |
| 22 | #include "C4MainMenu.h" |
| 23 | #include <C4ObjectInfoList.h> |
| 24 | #include <C4InfoCore.h> |
| 25 | #include <C4ObjectList.h> |
| 26 | |
| 27 | const int32_t C4PVM_Cursor = 0, |
| 28 | C4PVM_Target = 1, |
| 29 | C4PVM_Scrolling = 2; |
| 30 | |
| 31 | const int32_t C4P_Number_None = -5; |
| 32 | |
| 33 | const int32_t C4MaxPlayer = 5000; // ought to be enough for everybody (used to catch invalid player counts) |
| 34 | const int32_t C4MaxClient = 5000; // ought to be enough for everybody (used to catch invalid client counts) |
| 35 | |
| 36 | class C4Player : public C4PlayerInfoCore |
| 37 | { |
| 38 | public: |
| 39 | // possible player controls used for statistics |
| 40 | enum ControlType |
| 41 | { |
| 42 | PCID_None, // no control |
| 43 | PCID_Command, // mouse control |
| 44 | PCID_DirectCom, // menu or keyboard control |
| 45 | }; |
| 46 | // possible status |
| 47 | enum StatusTypes |
| 48 | { |
| 49 | PS_None = 0, // player disabled |
| 50 | PS_Normal = 1, // normal playing |
| 51 | PS_TeamSelection = 2, // team selection |
| 52 | PS_TeamSelectionPending = 3, // waiting for team selection packet to come through |
| 53 | }; |
| 54 | |
| 55 | friend class C4PlayerList; |
| 56 | |
| 57 | public: |
| 58 | C4Player(); |
| 59 | ~C4Player(); |
| 60 | |
| 61 | public: |
| 62 | char Filename[_MAX_PATH + 1]; |
| 63 | StdStrBuf Name; |
| 64 | int32_t Status; |
| 65 | int32_t Eliminated; |
| 66 | int32_t Surrendered; |
| 67 | bool Evaluated; |
| 68 | int32_t Number; |
| 69 | int32_t ID; // unique player ID |
| 70 | int32_t Team; // team ID - may be 0 for no teams |
| 71 | int32_t Color; // OldGfx color index |
| 72 | uint32_t ColorDw; // color as DWord for newgfx |
| 73 | int32_t Control; |
| 74 | int32_t MouseControl; |
| 75 | int32_t Position; |
| 76 | int32_t PlrStartIndex; |
| 77 | int32_t RetireDelay; |
| 78 | int32_t GameJoinTime; // Local-NoSave - set in Init; reset in LocalSync |
| 79 | int32_t AtClient; |
| 80 | char AtClientName[C4MaxTitle + 1]; |
| 81 | bool LocalControl; // Local-NoSave // |
| 82 | bool LeagueEvaluated; // Local-NoSave // |
| 83 | bool NoEliminationCheck; // Local-NoSave. Always set in init and restore by info // |
| 84 | // Menu |
| 85 | C4MainMenu ; // Local-NoSave // |
| 86 | // View |
| 87 | int32_t ViewMode; |
| 88 | int32_t ViewX, ViewY; |
| 89 | C4Object *ViewTarget; // NoSave // |
| 90 | int32_t ViewWealth, ViewValue; |
| 91 | bool ShowStartup; |
| 92 | int32_t ShowControl, ShowControlPos; |
| 93 | int32_t FlashCom; // NoSave // |
| 94 | bool fFogOfWar; |
| 95 | bool bForceFogOfWar; |
| 96 | bool fFogOfWarInitialized; // No Save // |
| 97 | C4ObjectList FoWViewObjs; // No Save // |
| 98 | // Game |
| 99 | int32_t Wealth, Points; |
| 100 | int32_t Value, InitialValue, ValueGain; |
| 101 | int32_t ObjectsOwned; |
| 102 | C4EnumeratedObjectPtr Captain; |
| 103 | C4IDList Hostility; |
| 104 | // Home Base |
| 105 | C4IDList HomeBaseMaterial; |
| 106 | C4IDList HomeBaseProduction; |
| 107 | int32_t ProductionDelay, ProductionUnit; |
| 108 | // Crew |
| 109 | C4ObjectInfoList CrewInfoList; // No Save // |
| 110 | C4ObjectList Crew; // Save new in 4.95.2 (for sync reasons) |
| 111 | int32_t CrewCnt; // No Save // |
| 112 | // Knowledge |
| 113 | C4IDList Knowledge; |
| 114 | C4IDList Magic; |
| 115 | // Control |
| 116 | int32_t ; |
| 117 | int32_t ControlStyle; |
| 118 | C4EnumeratedObjectPtr Cursor, ViewCursor; |
| 119 | int32_t SelectCount; |
| 120 | int32_t SelectFlash, CursorFlash; |
| 121 | int32_t LastCom; |
| 122 | int32_t LastComDelay; |
| 123 | int32_t LastComDownDouble; |
| 124 | int32_t PressedComs; |
| 125 | int32_t CursorSelection, CursorToggled; |
| 126 | class C4GamePadOpener *pGamepad; |
| 127 | // Message |
| 128 | int32_t MessageStatus; |
| 129 | char MessageBuf[256 + 1]; |
| 130 | class C4MessageBoardQuery *pMsgBoardQuery; |
| 131 | // BigIcon |
| 132 | C4FacetExSurface BigIcon; |
| 133 | // Dynamic list |
| 134 | C4Player *Next; |
| 135 | |
| 136 | // statistics |
| 137 | class C4TableGraph *pstatControls, *pstatActions; |
| 138 | int32_t ControlCount; // controls issued since value was last recorded |
| 139 | int32_t ActionCount; // non-doubled controls since value was last recorded |
| 140 | ControlType LastControlType; int32_t LastControlID; // last control to capture perma-pressers in stats |
| 141 | |
| 142 | public: |
| 143 | const char *GetName() const { return Name.getData(); } |
| 144 | C4PlayerType GetType() const; |
| 145 | |
| 146 | public: |
| 147 | void Eliminate(); |
| 148 | void SelectCrew(C4Object *pObj, bool fSelect); |
| 149 | void Default(); |
| 150 | void Clear(); |
| 151 | void ClearPointers(C4Object *tptr, bool fDeath); |
| 152 | void Execute(); |
| 153 | void ExecuteControl(); |
| 154 | void UpdateValue(); |
| 155 | void SetViewMode(int32_t iMode, C4Object *pTarget = nullptr); |
| 156 | void ResetCursorView(); // reset view to cursor if any cursor exists |
| 157 | void Evaluate(); |
| 158 | void Surrender(); |
| 159 | void ScrollView(int32_t iX, int32_t iY, int32_t ViewWdt, int32_t ViewHgt); |
| 160 | void SelectCrew(C4ObjectList &rList); |
| 161 | void SetCursor(C4Object *pObj, bool fSelectFlash, bool fSelectArrow); |
| 162 | void RemoveCrewObjects(); |
| 163 | void NotifyOwnedObjects(); |
| 164 | void DefaultRuntimeData(); |
| 165 | void DrawHostility(C4Facet &cgo, int32_t iIndex); |
| 166 | void AdjustCursorCommand(); |
| 167 | void CursorRight(); |
| 168 | void CursorLeft(); |
| 169 | void UnselectCrew(); |
| 170 | void SelectSingleByCursor(); |
| 171 | void CursorToggle(); |
| 172 | void SelectAllCrew(); |
| 173 | void UpdateSelectionToggleStatus(); |
| 174 | void DirectCom(uint8_t byCom, int32_t iData); |
| 175 | void InCom(uint8_t byCom, int32_t iData); |
| 176 | bool ObjectCom(uint8_t byCom, int32_t iData); |
| 177 | void ClearPressedComsSynced(); |
| 178 | bool ObjectCommand(int32_t iCommand, C4Object *pTarget, int32_t iTx, int32_t iTy, C4Object *pTarget2 = nullptr, int32_t iData = 0, int32_t iAddMode = C4P_Command_Set); |
| 179 | void ObjectCommand2Obj(C4Object *cObj, int32_t iCommand, C4Object *pTarget, int32_t iX, int32_t iY, C4Object *pTarget2, int32_t iData, int32_t iMode); |
| 180 | bool DoPoints(int32_t iChange); |
| 181 | bool Init(int32_t iNumber, int32_t iAtClient, const char *szAtClientName, const char *szFilename, bool fScenarioInit, class C4PlayerInfo *pInfo); |
| 182 | bool ScenarioAndTeamInit(int32_t idTeam); |
| 183 | bool ScenarioInit(); |
| 184 | bool FinalInit(bool fInitialValue); |
| 185 | bool Save(); |
| 186 | bool Save(C4Group &hGroup, bool fSavegame, bool fStoreTiny); |
| 187 | bool MakeCrewMember(C4Object *pObj, bool fForceInfo = true, bool fDoCalls = true); |
| 188 | bool Load(const char *szFilename, bool fSavegame, bool fLoadPortraits); |
| 189 | static bool Strip(const char *szFilename, bool fAggressive); |
| 190 | bool ObjectInCrew(C4Object *tobj); |
| 191 | C4Object *Buy(C4ID id, bool fShowErrors, int32_t iForPlr, C4Object *pBuyObj = nullptr); // buy object of player's wealth |
| 192 | bool Sell2Home(C4Object *tobj); |
| 193 | bool CanSell(C4Object *obj) const; |
| 194 | bool DoWealth(int32_t change); |
| 195 | bool SetHostility(int32_t iOpponent, int32_t iHostility, bool fSilent = false); |
| 196 | void CompileFunc(StdCompiler *pComp); |
| 197 | bool LoadRuntimeData(C4Group &hGroup); |
| 198 | bool ActivateMenuMain(); |
| 199 | bool (bool fFromMain); |
| 200 | void DoTeamSelection(int32_t idTeam); |
| 201 | C4Object *GetHiRankActiveCrew(bool fSelectedOnly); |
| 202 | void SetFoW(bool fEnable); |
| 203 | int32_t ActiveCrewCount(); |
| 204 | int32_t GetSelectedCrewCount(); |
| 205 | bool LocalSync(); // sync InAction et. al. back o local player file |
| 206 | bool SetObjectCrewStatus(C4Object *pCrew, bool fNewStatus); // add/remove object from crew |
| 207 | bool IsChosingTeam() const { return Status == PS_TeamSelection || Status == PS_TeamSelectionPending; } |
| 208 | bool IsInvisible() const; |
| 209 | void SyncHomebaseMaterialToTeam(); |
| 210 | void SyncHomebaseMaterialFromTeam(); |
| 211 | |
| 212 | protected: |
| 213 | void InitControl(); |
| 214 | void DenumeratePointers(); |
| 215 | void EnumeratePointers(); |
| 216 | void UpdateView(); |
| 217 | void CheckElimination(); |
| 218 | void UpdateCounts(); |
| 219 | void ExecHomeBaseProduction(); |
| 220 | void PlaceReadyBase(int32_t &tx, int32_t &ty, C4Object **pFirstBase); |
| 221 | void PlaceReadyVehic(int32_t tx1, int32_t tx2, int32_t ty, C4Object *FirstBase); |
| 222 | void PlaceReadyMaterial(int32_t tx1, int32_t tx2, int32_t ty, C4Object *FirstBase); |
| 223 | void PlaceReadyCrew(int32_t tx1, int32_t tx2, int32_t ty, C4Object *FirstBase); |
| 224 | |
| 225 | public: |
| 226 | void SetTeamHostility(); // if Team!=0: Set hostile to all players in other teams and allied to all others (both ways) |
| 227 | |
| 228 | void (); // close all player menus (keep sync object menus!) |
| 229 | |
| 230 | void EvaluateLeague(bool fDisconnected, bool fWon); |
| 231 | |
| 232 | void FoW2Map(CClrModAddMap &rMap, int iOffX, int iOffY); |
| 233 | void FoWGenerators2Map(CClrModAddMap &rMap, int iOffX, int iOffY); |
| 234 | bool FoWIsVisible(int32_t x, int32_t y); // check whether a point in the landscape is visible |
| 235 | |
| 236 | // runtime statistics |
| 237 | void CreateGraphs(); |
| 238 | void ClearGraphs(); |
| 239 | void CountControl(ControlType eType, int32_t iID, int32_t iCntAdd = 1); |
| 240 | |
| 241 | class C4PlayerInfo *GetInfo(); // search info by ID |
| 242 | |
| 243 | private: |
| 244 | // messageboard-calls for this player |
| 245 | void ExecMsgBoardQueries(); |
| 246 | |
| 247 | public: |
| 248 | void ToggleMouseControl(); |
| 249 | void CallMessageBoard(C4Object *pForObj, const StdStrBuf &sQueryString, bool fUppercase); |
| 250 | bool RemoveMessageBoardQuery(C4Object *pForObj); |
| 251 | bool MarkMessageBoardQueryAnswered(C4Object *pForObj); |
| 252 | bool HasMessageBoardQuery(); // return whether any object has a messageboard-query |
| 253 | |
| 254 | // callback by script execution of team selection: Restart team selection if the team turned out to be not available |
| 255 | void OnTeamSelectionFailed(); |
| 256 | |
| 257 | // when the player changes team, his color changes. Relfect this in player objects |
| 258 | void SetPlayerColor(uint32_t dwNewClr); |
| 259 | |
| 260 | void ApplyForcedControl(); |
| 261 | }; |
| 262 | |