1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Player data at runtime */
19 
20 #ifndef INC_C4Player
21 #define INC_C4Player
22 
23 #include "control/C4PlayerControl.h"
24 #include "gui/C4MainMenu.h"
25 #include "object/C4InfoCore.h"
26 #include "object/C4ObjectInfoList.h"
27 #include "object/C4ObjectList.h"
28 #include "object/C4ObjectPtr.h"
29 #include "script/C4Value.h"
30 
31 const int32_t C4PVM_Cursor    = 0,
32               C4PVM_Target    = 1,
33               C4PVM_Scrolling = 2;
34 
35 const int32_t C4P_Number_None = -5;
36 
37 const int32_t C4MaxPlayer = 5000; // ought to be enough for everybody (used to catch invalid player counts)
38 const int32_t C4MaxClient = 5000; // ought to be enough for everybody (used to catch invalid client counts)
39 
40 // view ranges in "CR-pixels" covered by viewport
41 static const int C4VP_DefViewRangeX    = 300,
42                  C4VP_DefMinViewRangeX = 150,
43                  C4VP_DefMaxViewRangeX = 750;
44 
45 static const int C4FOW_DefLightRangeX = 300,
46                  C4FOW_DefLightFadeoutRangeX = 80;
47 
48 class C4Player: public C4PlayerInfoCore
49 {
50 	class HostilitySet : public std::set<const C4Player*>
51 	{
52 	public:
53 		void CompileFunc(StdCompiler *pComp);
54 	};
55 
56 public:
57 	// possible player controls used for statistics
58 	enum ControlType
59 	{
60 		PCID_None,      // no control
61 		PCID_Message,   // chat
62 		PCID_Special,   // goalruleinfo, etc.
63 		PCID_Command,   // mouse control
64 		PCID_DirectCom  // menu or keyboard control
65 	};
66 	// possible status
67 	enum StatusTypes
68 	{
69 		PS_None=0,            // player disabled
70 		PS_Normal=1,          // normal playing
71 		PS_TeamSelection = 2, // team selection
72 		PS_TeamSelectionPending = 3 // waiting for team selection packet to come through
73 	};
74 	friend class C4PlayerList;
75 
76 public:
77 	C4Player();
78 	~C4Player();
79 public:
80 	char Filename[_MAX_PATH+1];
81 	StdStrBuf Name;
82 	int32_t Status;
83 	int32_t Eliminated;
84 	int32_t Surrendered;
85 	bool Evaluated;
86 	int32_t Number;
87 	int32_t ID; // unique player ID
88 	int32_t Team; // team ID - may be 0 for no teams
89 	uint32_t ColorDw;
90 	class C4PlayerControlAssignmentSet *ControlSet;
91 	StdCopyStrBuf ControlSetName;
92 	int32_t MouseControl;
93 	int32_t Position;
94 	int32_t PlrStartIndex;
95 	int32_t RetireDelay;
96 	int32_t GameJoinTime; // Local-NoSave - set in Init; reset in LocalSync
97 	int32_t AtClient;
98 	char AtClientName[C4MaxTitle+1];
99 	bool LocalControl; // Local-NoSave //
100 	bool LeagueEvaluated; // Local-NoSave //
101 	bool NoEliminationCheck; // Local-NoSave. Always set in init and restore by info //
102 	// Menu
103 	C4MainMenu Menu; // Local-NoSave //
104 	// View
105 	int32_t ViewMode;
106 	C4Real ViewX,ViewY; // FIXED because this is saved/synchronized
107 	bool ViewLock; // if set, no scrolling is allowed
108 	C4Object *ViewTarget; // NoSave //
109 	bool ShowStartup;
110 	int32_t FlashCom; // NoSave //
111 	bool fFogOfWar;
112 	int32_t ZoomLimitMinWdt,ZoomLimitMinHgt,ZoomLimitMaxWdt,ZoomLimitMaxHgt,ZoomWdt,ZoomHgt; // zoom limits and last zoom set by script
113 	C4Real ZoomLimitMinVal,ZoomLimitMaxVal,ZoomVal; // direct zoom values.
114 	// Game
115 	int32_t Wealth;
116 	int32_t CurrentScore,InitialScore;
117 	int32_t ObjectsOwned;
118 	HostilitySet Hostility;
119 	// Home Base
120 	C4IDList BaseMaterial;
121 	C4IDList BaseProduction;
122 	int32_t ProductionDelay,ProductionUnit;
123 	// Crew
124 	C4ObjectInfoList CrewInfoList; // No Save //
125 	C4ObjectList Crew; // Save new in 4.95.2 (for sync reasons)
126 	// Knowledge
127 	C4IDList Knowledge;
128 	// Control
129 	C4PlayerControl Control;
130 	C4ObjectPtr Cursor, ViewCursor;
131 	int32_t CursorFlash;
132 	std::shared_ptr<class C4GamePadOpener> pGamepad;
133 	// Message
134 	int32_t MessageStatus;
135 	char MessageBuf[256+1];
136 	class C4MessageBoardQuery *pMsgBoardQuery;
137 	// BigIcon
138 	C4FacetSurface BigIcon;
139 	// Sound
140 	C4Value SoundModifier;
141 	// Dynamic list
142 	C4Player *Next;
143 
144 	// statistics
145 	class C4TableGraph *pstatControls, *pstatActions;
146 	int32_t ControlCount; // controls issued since value was last recorded
147 	int32_t ActionCount;  // non-doubled controls since value was last recorded
148 	ControlType LastControlType; int32_t LastControlID; // last control to capture perma-pressers in stats
149 
150 public:
GetName()151 	const char *GetName() const { return Name.getData(); }
152 	C4PlayerType GetType() const;
153 
154 public:
155 	void Eliminate();
156 	void ClearPointers(C4Object *tptr, bool fDeath);
157 	void Execute();
158 	void ExecuteControl();
159 	void SetViewMode(int32_t iMode, C4Object *pTarget=nullptr, bool immediate_position=false);
160 	void ResetCursorView(bool immediate_position = false); // reset view to cursor if any cursor exists
161 	void Evaluate();
162 	void Surrender();
163 	void ScrollView(float iX, float iY, float ViewWdt, float ViewHgt); // in landscape coordinates
164 	void SetCursor(C4Object *pObj, bool fSelectArrow);
165 	void RemoveCrewObjects();
166 	int32_t FindNewOwner() const;
167 	void NotifyOwnedObjects();
168 	void DefaultRuntimeData();
169 	void DrawHostility(C4Facet &cgo, int32_t iIndex);
170 	void AdjustCursorCommand();
171 
172 	bool DoScore(int32_t iChange);
173 	bool Init(int32_t iNumber, int32_t iAtClient, const char *szAtClientName, const char *szFilename, bool fScenarioInit, class C4PlayerInfo *pInfo, C4ValueNumbers *);
174 	bool ScenarioAndTeamInit(int32_t idTeam);
175 	bool ScenarioInit();
176 	bool FinalInit(bool fInitialScore);
177 	bool Save();
178 	bool Save(C4Group &hGroup, bool fSavegame, bool fStoreTiny);
179 	bool MakeCrewMember(C4Object *pObj, bool fForceInfo=true, bool fDoCalls=true);
180 	bool Load(const char *szFilename, bool fSavegame);
181 	static bool Strip(const char *szFilename, bool fAggressive);
182 	bool Message(const char *szMsg);
183 	bool ObjectInCrew(C4Object *tobj);
184 	bool DoWealth(int32_t change);
185 	bool SetWealth(int32_t val);
186 	bool SetKnowledge(C4ID id, bool fRemove);
187 	bool SetHostility(int32_t iOpponent, int32_t iHostility, bool fSilent=false);
188 	bool IsHostileTowards(const C4Player *opponent) const;
189 	void CompileFunc(StdCompiler *pComp, C4ValueNumbers *);
190 	void DenumeratePointers();
191 	bool LoadRuntimeData(C4Group &hGroup, C4ValueNumbers *);
192 	bool ActivateMenuMain();
193 	bool ActivateMenuTeamSelection(bool fFromMain);
194 	void DoTeamSelection(int32_t idTeam);
195 	C4Object *GetHiExpActiveCrew();
196 	C4Object *GetHiRankActiveCrew();
197 	void SetFoW(bool fEnable);
198 	int32_t ActiveCrewCount();
199 	int32_t GetSelectedCrewCount();
200 	bool LocalSync(); // sync InAction et. al. back o local player file
201 	bool SetObjectCrewStatus(C4Object *pCrew, bool fNewStatus); // add/remove object from crew
IsChosingTeam()202 	bool IsChosingTeam() const { return Status==PS_TeamSelection || Status==PS_TeamSelectionPending; }
203 	bool IsInvisible() const;
IsViewLocked()204 	bool IsViewLocked() const { return ViewLock; } // return if view is fixed to cursor, so scrolling is not allowed
205 	void SetViewLocked(bool to_val); // lock or unlock free scrolling for player
206 	void SetSoundModifier(C4PropList *new_modifier); // set modifier to be applied to all new sounds being played in a player's viewport
207 
208 protected:
209 	void ClearControl();
210 	void InitControl();
211 	void UpdateView();
212 	void CheckElimination();
213 	void ExecBaseProduction();
214 	void PlaceReadyBase(int32_t &tx, int32_t &ty, C4Object **pFirstBase);
215 	void PlaceReadyVehic(int32_t tx1, int32_t tx2, int32_t ty, C4Object *FirstBase);
216 	void PlaceReadyMaterial(int32_t tx1, int32_t tx2, int32_t ty, C4Object *FirstBase);
217 	void PlaceReadyCrew(int32_t tx1, int32_t tx2, int32_t ty, C4Object *FirstBase);
218 	void CheckCrewExPromotion();
219 
220 public:
221 	void SetTeamHostility(); // if Team!=0: Set hostile to all players in other teams and allied to all others (both ways)
222 
223 	void CloseMenu(); // close all player menus (keep sync object menus!)
224 
225 	void EvaluateLeague(bool fDisconnected, bool fWon);
226 
227 	// runtime statistics
228 	void CreateGraphs();
229 	void ClearGraphs();
230 	void CountControl(ControlType eType, int32_t iID, int32_t iCntAdd=1);
231 
232 	class C4PlayerInfo *GetInfo(); // search info by ID
233 
234 private:
235 	// messageboard-calls for this player
236 	class C4MessageBoardQuery *GetMessageboardQuery(C4Object *pForObj);
237 	void ExecMsgBoardQueries();
238 public:
239 	void ToggleMouseControl();
240 	void CallMessageBoard(C4Object *pForObj, const StdStrBuf &sQueryString, bool fUppercase);
241 	bool RemoveMessageBoardQuery(C4Object *pForObj);
242 	bool MarkMessageBoardQueryAnswered(C4Object *pForObj);
243 	bool HasMessageBoardQuery(); // return whether any object has a messageboard-query
244 
245 	// callback by script execution of team selection: Restart team selection if the team turned out to be not available
246 	void OnTeamSelectionFailed();
247 
248 	// when the player changes team, his color changes. Relfect this in player objects
249 	void SetPlayerColor(uint32_t dwNewClr);
250 
251 	// zoom and zoom limit changes
252 	void SetZoomByViewRange(int32_t range_wdt, int32_t range_hgt, bool direct, bool no_increase, bool no_decrease);
253 	void SetMinZoomByViewRange(int32_t range_wdt, int32_t range_hgt, bool no_increase, bool no_decrease);
254 	void SetMaxZoomByViewRange(int32_t range_wdt, int32_t range_hgt, bool no_increase, bool no_decrease);
255 	void SetZoom(C4Real zoom, bool direct, bool no_increase, bool no_decrease);
256 	void SetMinZoom(C4Real zoom, bool no_increase, bool no_decrease);
257 	void SetMaxZoom(C4Real zoom, bool no_increase, bool no_decrease);
258 	void ZoomToViewports(bool direct, bool no_increase=false, bool no_decrease=false);
259 	void ZoomToViewport(C4Viewport* vp, bool direct, bool no_increase=false, bool no_decrease=false);
260 	void ZoomLimitsToViewports();
261 	void ZoomLimitsToViewport(C4Viewport* vp);
262 
263 private:
264 	bool AdjustZoomParameter(int32_t *range_par, int32_t new_val, bool no_increase, bool no_decrease);
265 	bool AdjustZoomParameter(C4Real *zoom_par, C4Real new_val, bool no_increase, bool no_decrease);
266 
267 	// Finds a new gamepad to use, returning true on success.
268 	bool FindGamepad();
269 
270 public:
271 	// custom scenario achievements
272 	bool GainScenarioAchievement(const char *achievement_id, int32_t value, const char *scen_name_override=nullptr);
273 };
274 
275 #endif
276