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 /* Main class to run the game */
19 
20 #ifndef INC_C4Game
21 #define INC_C4Game
22 
23 #include "c4group/C4Extra.h"
24 #include "control/C4PlayerControl.h"
25 #include "gui/C4Scoreboard.h"
26 #include "landscape/C4PathFinder.h"
27 #include "landscape/C4Scenario.h"
28 #include "landscape/C4TransferZone.h"
29 
30 class C4ScriptGuiWindow;
31 
32 class C4Game
33 {
34 public:
35 	// Initialization mode: Regular game start, section load or editor reload
36 	enum InitMode
37 	{
38 		IM_Normal = 0,
39 		IM_Section = 1,
40 		IM_ReInit = 2
41 	};
42 private:
43 	// used as StdCompiler-parameter
44 	struct CompileSettings
45 	{
46 		InitMode init_mode;
47 		bool fPlayers;
48 		bool fExact;
49 		bool fSync;
50 
CompileSettingsCompileSettings51 		CompileSettings(InitMode init_mode, bool fPlayers, bool fExact, bool fSync)
52 				: init_mode(init_mode), fPlayers(fPlayers), fExact(fExact), fSync(fSync) { }
53 	};
54 
55 	// struct of keyboard set and indexed control key
56 	struct C4KeySetCtrl
57 	{
58 		int32_t iKeySet, iCtrl;
59 
C4KeySetCtrlC4KeySetCtrl60 		C4KeySetCtrl(int32_t iKeySet, int32_t iCtrl) : iKeySet(iKeySet), iCtrl(iCtrl) {}
61 	};
62 
63 public:
64 	C4Game();
65 	~C4Game();
66 
67 	C4GameParameters   &Parameters;
68 	class C4ScenarioParameters &StartupScenarioParameters; // parameters given on command line or during startup UI
69 	C4ClientList       &Clients; // Shortcut
70 	C4TeamList         &Teams; // Shortcut
71 	C4PlayerInfoList   &PlayerInfos; // Shortcut
72 	C4PlayerInfoList   &RestorePlayerInfos; // Shortcut
73 	C4RoundResults      &RoundResults;
74 	C4Scenario          C4S;
75 	class C4ScenarioParameterDefs &ScenarioParameterDefs;
76 	C4ComponentHost     Info;
77 	C4ComponentHost     Title;
78 	C4ComponentHost     Names;
79 	C4ComponentHost     GameText;
80 	C4LangStringTable   MainSysLangStringTable, ScenarioLangStringTable;
81 	StdStrBuf           PlayerNames;
82 	C4Control          &Input; // shortcut
83 
84 	C4PathFinder        PathFinder;
85 	C4TransferZones     TransferZones;
86 	C4Group             ScenarioFile;
87 	C4GroupSet          GroupSet;
88 	C4Group             *pParentGroup;
89 	C4Extra             Extra;
90 	class C4ScenarioObjectsScriptHost *pScenarioObjectsScript;
91 	C4ScenarioSection   *pScenarioSections, *pCurrentScenarioSection;
92 	C4PlayerControlDefs PlayerControlDefs;
93 	C4PlayerControlAssignmentSets PlayerControlUserAssignmentSets, PlayerControlDefaultAssignmentSets;
94 	C4Scoreboard        Scoreboard;
95 	std::unique_ptr<C4Network2Stats> pNetworkStatistics; // may be nullptr if no statistics are recorded
96 	C4KeyboardInput &KeyboardInput;
97 	std::unique_ptr<C4FileMonitor> pFileMonitor;
98 	std::unique_ptr<C4GameSec1Timer> pSec1Timer;
99 	C4Value            &GlobalSoundModifier; // contains proplist for sound modifier to be applied to all new sounds played
100 
101 	char CurrentScenarioSection[C4MaxName+1];
102 	char ScenarioFilename[_MAX_PATH+1];
103 	StdCopyStrBuf ScenarioTitle;
104 	char PlayerFilenames[20*_MAX_PATH+1];
105 	char DefinitionFilenames[20*_MAX_PATH+1];
106 	char DirectJoinAddress[_MAX_PATH+1];
107 	char DirectJoinTempFilename[_MAX_PATH + 1];
108 	std::unique_ptr<C4Network2Reference> pJoinReference;
109 	int32_t StartupPlayerCount;
110 	int32_t StartupTeamCount;
111 	int32_t FPS,cFPS;
112 	int32_t HaltCount;
113 	bool InitialPlayersJoined; // true after the InitializeFinal callback has been made
114 	bool GameOver;
115 	bool EvaluateOnAbort; // set in Scenario.txt, copied here because of sections
116 	bool Evaluated;
117 	bool GameOverDlgShown;
118 	bool fScriptCreatedObjects;
119 	bool fLobby;
120 	int32_t iLobbyTimeout;
121 	bool fObserve;
122 	bool fReferenceDefinitionOverride;
123 	bool NetworkActive;
124 	bool Record;
125 	StdStrBuf RecordDumpFile;
126 	StdStrBuf RecordStream;
127 	StdStrBuf TempScenarioFile;
128 	bool fPreinited{false}; // set after PreInit has been called; unset by Clear and Default
129 	int32_t FrameCounter;
130 	int32_t iTick2,iTick3,iTick5,iTick10,iTick35,iTick255,iTick1000;
131 	bool TimeGo;
132 	int32_t Time;
133 	int32_t StartTime;
134 	int32_t InitProgress; int32_t LastInitProgress; int32_t LastInitProgressShowTime;
135 	int32_t RandomSeed;
136 	bool GameGo;
137 	bool FullSpeed;
138 	int32_t FrameSkip; bool DoSkipFrame;
139 	bool fResortAnyObject; // if set, object list will be checked for unsorted objects next frame
140 	bool IsRunning;        // (NoSave) if set, the game is running; if not, just the startup message board is painted
141 	bool PointersDenumerated; // (NoSave) set after object pointers have been denumerated
142 	size_t StartupLogPos{0}, QuitLogPos{0}; // current log positions when game was last started and cleared
143 	bool fQuitWithError{false}; // if set, game shut down irregularly
144 	// Show errors and allow debug commands?
145 	bool DebugMode;
146 	// next mission to be played after this one
147 	StdCopyStrBuf NextMission, NextMissionText, NextMissionDesc;
148 	// debug settings
149 	uint16_t DebugPort; StdStrBuf DebugPassword, DebugHost; int DebugWait;
150 
151 	// Init and execution
152 	void Clear();
153 	void Abort(bool fApproved = false); // hard-quit on Esc+Y (/J/O)
154 	void Evaluate();
155 	void ShowGameOverDlg();
156 	bool DoKeyboardInput(C4KeyCode vk_code, C4KeyEventType eEventType, bool fAlt, bool fCtrl, bool fShift, bool fRepeated, class C4GUI::Dialog *pForDialog=nullptr, bool fPlrCtrlOnly=false, int32_t iStrength=-1);
157 	bool DoKeyboardInput(C4KeyCodeEx Key, C4KeyEventType eEventType, class C4GUI::Dialog *pForDialog=nullptr, bool fPlrCtrlOnly=false, int32_t iStrength=-1);
158 	void DrawCrewOverheadText(C4TargetFacet &cgo, int32_t iPlayer);
159 	void FixRandom(uint64_t iSeed);
160 	bool Init();
161 	bool PreInit();
162 	void SetScenarioFilename(const char*);
HasScenario()163 	bool HasScenario() { return *DirectJoinAddress || *ScenarioFilename || RecordStream.getSize(); }
164 	bool Execute();
165 	C4Player *JoinPlayer(const char *szFilename, int32_t iAtClient, const char *szAtClientName, C4PlayerInfo *pInfo);
166 	void OnPlayerJoinFinished();
167 	bool DoGameOver();
168 	bool CanQuickSave();
169 	bool QuickSave(const char *strFilename, const char *strTitle, bool fForceSave=false);
170 	void SetInitProgress(float fToProgress);
171 	void OnResolutionChanged(unsigned int iXRes, unsigned int iYRes); // update anything that's dependant on screen resolution
172 	void OnKeyboardLayoutChanged();
173 	void InitFullscreenComponents(bool fRunning);
174 	bool ToggleChat();
175 	// Pause
176 	bool TogglePause();
177 	bool Pause();
178 	bool Unpause();
179 	bool IsPaused();
180 	// Network
181 	void Synchronize(bool fSavePlayerFiles);
182 	void SyncClearance();
183 	// Editing
184 	bool DropFile(const char *szFilename, float iX, float iY);
185 	bool DropDef(C4ID id, float iX, float iY);
186 	bool ReloadFile(const char *szPath);
187 	bool ReloadDef(C4ID id);
188 	bool ReloadParticle(const char *szName);
189 	// Object functions
190 	void ClearPointers(C4Object *cobj);
191 	C4Object *CreateObject(C4PropList * type, C4Object *pCreator, int32_t owner=NO_OWNER,
192 	                       int32_t x=50, int32_t y=50, int32_t r=0, bool grow_from_center=false,
193 	                       C4Real xdir=Fix0, C4Real ydir=Fix0, C4Real rdir=Fix0, int32_t iController=NO_OWNER);
194 	C4Object *CreateObject(C4ID type, C4Object *pCreator, int32_t owner=NO_OWNER,
195 	                       int32_t x=50, int32_t y=50, int32_t r=0, bool grow_from_center=false,
196 	                       C4Real xdir=Fix0, C4Real ydir=Fix0, C4Real rdir=Fix0, int32_t iController=NO_OWNER);
197 	C4Object *CreateObjectConstruction(C4PropList * type,
198 	                                   C4Object *pCreator,
199 	                                   int32_t owner,
200 	                                   int32_t ctx=0, int32_t bty=0,
201 	                                   int32_t con=1, bool terrain=false);
202 	C4Object *CreateInfoObject(C4ObjectInfo *cinf, int32_t owner,
203 	                           int32_t tx=50, int32_t ty=50);
204 	C4Object *FindConstuctionSiteBlock(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt);
205 	C4Object *FindObject(C4Def * pDef,
206 	                     int32_t iX=0, int32_t iY=0, int32_t iWdt=0, int32_t iHgt=0,
207 	                     DWORD ocf=OCF_All,
208 	                     C4Object *pFindNext=nullptr);
209 	C4Object *FindVisObject( // find object in view at pos, regarding parallaxity and visibility (but not distance)
210 	  float tx, float ty, int32_t iPlr, const C4Facet &fctViewportGame, const C4Facet &fctViewportGUI,
211 	  float iX, float iY,
212 	  DWORD category,
213 	  float gui_x, float gui_y);
214 	int32_t ObjectCount(C4ID id);
215 	void CastObjects(C4ID id, C4Object *pCreator, int32_t num, int32_t level, int32_t tx, int32_t ty, int32_t iOwner=NO_OWNER, int32_t iController=NO_OWNER, C4ValueArray *out_objects=nullptr);
216 	C4Object *PlaceVegetation(C4PropList *def, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iGrowth, C4PropList *shape_proplist, C4PropList * out_pos_proplist);
217 	C4Object *PlaceAnimal(C4PropList *def);
218 	C4Value GRBroadcast(const char *szFunction, C4AulParSet *pPars = nullptr, bool fPassError=false, bool fRejectTest=false);  // call function in scenario script and all goals/rules/environment objects
219 
220 	bool LoadScenarioSection(const char *szSection, DWORD dwFlags);
221 	bool CreateSectionFromTempFile(const char *section_name, const char *temp_filename);
222 
223 	bool DrawTextSpecImage(C4Facet& fctTarget, const char *szSpec, class C4DrawTransform* pTransform, uint32_t dwClr=0xff);
224 	float GetTextSpecImageAspect(const char* szSpec);
225 	bool DrawPropListSpecImage(C4Facet& fctTarget, C4PropList *pSpec);
226 	bool SpeedUp();
227 	bool SlowDown();
228 	bool InitKeyboard(); // register main keyboard input functions
229 	void UpdateLanguage();
230 	bool InitPlayerControlSettings();
231 	bool InitPlayerControlUserSettings(); // merge player control default settings and config overloads into user setting
232 	void SetDefaultGamma();
233 
234 	std::unique_ptr<C4ScriptGuiWindow> ScriptGuiRoot;
235 protected:
236 	void Default();
237 	void InitInEarth();
238 	void InitVegetation();
239 	void InitAnimals();
240 	void InitGoals();
241 	void InitRules();
242 	void InitValueOverloads();
243 	void InitEnvironment();
244 	void CloseScenario();
245 	void DeleteObjects(bool fDeleteInactive);
246 	void ExecObjects();
247 	void Ticks();
248 	bool CheckObjectEnumeration();
249 	bool LoadScenarioComponents();
250 public:
251 	bool LoadAdditionalSystemGroup(class C4Group &parent_group);
252 	bool SaveGameTitle(C4Group &hGroup);
253 protected:
254 	bool InitGame(C4Group &hGroup, InitMode init_mode, bool fLoadSky, C4ValueNumbers *);
255 	bool InitGameFinal(InitMode init_mode);
256 	bool InitNetworkFromAddress(const char *szAddress);
257 	bool InitNetworkFromReferenceFile(const char *temp_filename);
258 	bool InitNetworkFromReference(const C4Network2Reference &Reference);
259 	bool InitNetworkHost();
260 	bool InitControl();
261 	bool InitScriptEngine();
262 	bool LinkScriptEngine();
263 	bool ReLinkScriptEngine();
264 	bool InitPlayers(C4ValueNumbers *);
265 	bool OpenScenario();
266 	bool InitDefs();
267 	bool InitMaterialTexture();
268 	bool GameOverCheck();
269 	bool PlaceInEarth(C4ID id);
270 public:
271 	void CompileFunc(StdCompiler *pComp, CompileSettings comp, C4ValueNumbers *);
272 	bool SaveData(C4Group &hGroup, bool fSaveSection, bool fSaveExact, bool fSaveSync, C4ValueNumbers *);
273 protected:
274 	bool CompileRuntimeData(C4Group &hGroup, InitMode init_mode, bool exact, bool sync, C4ValueNumbers *);
275 
276 	// Object function internals
277 	C4Object *NewObject( C4PropList *ndef, C4Object *pCreator,
278 	                     int32_t owner, C4ObjectInfo *info,
279 	                     int32_t tx, int32_t ty, int32_t tr,
280 	                     C4Real xdir, C4Real ydir, C4Real rdir,
281 						 int32_t con, int32_t iController, bool grow_from_center);
282 	void ClearObjectPtrs(C4Object *tptr);
283 	void ObjectRemovalCheck();
284 
285 	bool ToggleDebugMode(); // dbg modeon/off if allowed
286 	bool ActivateMenu(const char *szCommand); // exec given menu command for first local player
287 
288 public:
289 	bool ToggleChart(); // chart dlg on/off
290 	void SetGlobalSoundModifier(C4PropList *modifier_props);
291 
292 	// Localized strings in editor props
293 	C4String *GetTranslatedString(const class C4Value &input_string, C4Value *selected_language, bool fail_silently) const;
294 	C4PropList *AllocateTranslatedString();
295 
296 	static constexpr const char * DirectJoinFilePrefix = "file:";
297 };
298 
299 extern C4Game         Game;
300 
301 // a global wrapper
302 inline StdStrBuf GetKeyboardInputName(const char *szKeyName, bool fShort = false, int32_t iIndex = 0)
303 {
304 	return Game.KeyboardInput.GetKeyCodeNameByKeyName(szKeyName, fShort, iIndex);
305 }
306 
307 
308 #endif
309