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
27const int32_t C4PVM_Cursor = 0,
28 C4PVM_Target = 1,
29 C4PVM_Scrolling = 2;
30
31const int32_t C4P_Number_None = -5;
32
33const int32_t C4MaxPlayer = 5000; // ought to be enough for everybody (used to catch invalid player counts)
34const int32_t C4MaxClient = 5000; // ought to be enough for everybody (used to catch invalid client counts)
35
36class C4Player : public C4PlayerInfoCore
37{
38public:
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
57public:
58 C4Player();
59 ~C4Player();
60
61public:
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 Menu; // 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 AutoContextMenu;
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
142public:
143 const char *GetName() const { return Name.getData(); }
144 C4PlayerType GetType() const;
145
146public:
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 ActivateMenuTeamSelection(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
212protected:
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
225public:
226 void SetTeamHostility(); // if Team!=0: Set hostile to all players in other teams and allied to all others (both ways)
227
228 void CloseMenu(); // 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
243private:
244 // messageboard-calls for this player
245 void ExecMsgBoardQueries();
246
247public:
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