1/*
2 * LegacyClonk
3 *
4 * Copyright (c) 1998-2000, Matthes Bender (RedWolf Design)
5 * Copyright (c) 2017-2021, 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/* Main class to run the game */
18
19#pragma once
20
21#include <C4Def.h>
22#include <C4Texture.h>
23#include <C4RankSystem.h>
24#include <C4GraphicsSystem.h>
25#include <C4GraphicsResource.h>
26#include <C4GameMessage.h>
27#include <C4MouseControl.h>
28#include <C4MessageInput.h>
29#include <C4Weather.h>
30#include <C4Material.h>
31#include <C4GameObjects.h>
32#include <C4Landscape.h>
33#include <C4Scenario.h>
34#include <C4MassMover.h>
35#include <C4PXS.h>
36#include <C4PlayerList.h>
37#include <C4Teams.h>
38#include <C4PlayerInfo.h>
39#include <C4Control.h>
40#include <C4PathFinder.h>
41#include <C4ComponentHost.h>
42#include <C4ScriptHost.h>
43#include <C4Particles.h>
44#include <C4GroupSet.h>
45#include <C4Extra.h>
46#include <C4GameControl.h>
47#include <C4Effects.h>
48#include <C4Fonts.h>
49#include "C4LangStringTable.h"
50#include "C4Scoreboard.h"
51#include <C4Network2.h>
52#include <C4Scenario.h>
53#include <C4Client.h>
54#include <C4Network2Reference.h>
55#include <C4RoundResults.h>
56#include <C4NetworkRestartInfos.h>
57#include "C4FileMonitor.h"
58
59class C4Game
60{
61private:
62 // used as StdCompiler-parameter
63 struct CompileSettings
64 {
65 bool fScenarioSection;
66 bool fPlayers;
67 bool fExact;
68
69 CompileSettings(bool fScenarioSection, bool fPlayers, bool fExact)
70 : fScenarioSection(fScenarioSection), fPlayers(fPlayers), fExact(fExact) {}
71 };
72
73 // struct of keyboard set and indexed control key
74 struct C4KeySetCtrl
75 {
76 int32_t iKeySet, iCtrl;
77
78 C4KeySetCtrl(int32_t iKeySet, int32_t iCtrl) : iKeySet(iKeySet), iCtrl(iCtrl) {}
79 };
80
81public:
82 C4Game();
83 ~C4Game();
84
85public:
86 C4DefList Defs;
87 C4TextureMap TextureMap;
88 C4RankSystem Rank;
89 C4GraphicsSystem GraphicsSystem;
90 C4MessageInput MessageInput;
91 C4GraphicsResource GraphicsResource;
92 C4Network2 Network;
93 C4ClientList &Clients; // Shortcut
94 C4GameParameters Parameters;
95 C4TeamList &Teams; // Shortcut
96 C4PlayerInfoList &PlayerInfos; // Shortcut
97 C4PlayerInfoList &RestorePlayerInfos; // Shortcut
98 C4RoundResults RoundResults;
99 C4GameMessageList Messages;
100 C4MouseControl MouseControl;
101 C4Weather Weather;
102 C4MaterialMap Material;
103 C4GameObjects Objects;
104 C4ObjectList BackObjects; // objects in background (C4D_Background)
105 C4ObjectList ForeObjects; // objects in foreground (C4D_Foreground)
106 C4Landscape Landscape;
107 C4Scenario C4S;
108 C4ComponentHost Info;
109 C4ComponentHost Title;
110 C4ComponentHost Names;
111 C4ComponentHost GameText;
112 C4AulScriptEngine ScriptEngine;
113 C4GameScriptHost Script;
114 C4LangStringTable MainSysLangStringTable, ScenarioLangStringTable, ScenarioSysLangStringTable;
115 C4MassMoverSet MassMover;
116 C4PXSSystem PXS;
117 C4ParticleSystem Particles;
118 C4PlayerList Players;
119 StdStrBuf PlayerNames;
120 C4GameControl Control;
121 C4Control &Input; // shortcut
122
123 C4PathFinder PathFinder;
124 C4TransferZones TransferZones;
125 C4Group ScenarioFile;
126 C4GroupSet GroupSet;
127 C4Group *pParentGroup;
128 C4Extra Extra;
129 C4GUI::Screen *pGUI;
130 C4ScenarioSection *pScenarioSections, *pCurrentScenarioSection;
131 C4Effect *pGlobalEffects;
132#ifndef USE_CONSOLE
133 // We don't need fonts when we don't have graphics
134 C4FontLoader FontLoader;
135#endif
136 C4Scoreboard Scoreboard;
137 class C4Network2Stats *pNetworkStatistics; // may be nullptr if no statistics are recorded
138 class C4KeyboardInput &KeyboardInput;
139 char CurrentScenarioSection[C4MaxName + 1];
140 char ScenarioFilename[_MAX_PATH + 1];
141 char PlayerFilenames[20 * _MAX_PATH + 1];
142 std::vector<std::string> DefinitionFilenames;
143 bool FixedDefinitions;
144 char DirectJoinAddress[_MAX_PATH + 1];
145 class C4Network2Reference *pJoinReference;
146 int32_t FPS, cFPS;
147 int32_t HaltCount;
148 bool GameOver;
149 bool Evaluated;
150 bool GameOverDlgShown;
151 bool fScriptCreatedObjects;
152 bool fLobby;
153 int32_t iLobbyTimeout;
154 bool fObserve;
155 bool NetworkActive;
156 StdStrBuf RecordDumpFile;
157 StdStrBuf RecordStream;
158 bool TempScenarioFile;
159 bool fPreinited; // set after PreInit has been called; unset by Clear and Default
160 int32_t FrameCounter;
161 int32_t iTick2, iTick3, iTick5, iTick10, iTick35, iTick255, iTick500, iTick1000;
162 bool TimeGo;
163 int32_t Time;
164 int32_t StartTime;
165 int32_t InitProgress; int32_t LastInitProgress;
166 int32_t ObjectEnumerationIndex;
167 int32_t Rules;
168 bool GameGo;
169 bool FullSpeed;
170 int32_t FrameSkip; bool DoSkipFrame;
171 uint32_t FoWColor; // FoW-color; may contain transparency
172 bool fResortAnyObject; // if set, object list will be checked for unsorted objects next frame
173 bool IsRunning; // (NoSave) if set, the game is running; if not, just the startup message board is painted
174 bool PointersDenumerated; // (NoSave) set after object pointers have been denumerated
175 bool fQuitWithError; // if set, game shut down irregularly
176 bool IsMusicEnabled;
177 int32_t iMusicLevel; // scenario-defined music level
178 // current play list
179 StdStrBuf PlayList;
180 bool DebugMode;
181 // next mission to be played after this one
182 StdStrBuf NextMission, NextMissionText, NextMissionDesc;
183 C4NetworkRestartInfos::Infos RestartRestoreInfos;
184
185public:
186 // Init and execution
187 void Default();
188 void Clear();
189 void Abort(bool fApproved = false); // hard-quit on Esc+Y (/J/O)
190 void Evaluate();
191 void ShowGameOverDlg();
192 void Sec1Timer();
193 bool DoKeyboardInput(C4KeyCode vk_code, C4KeyEventType eEventType, bool fAlt, bool fCtrl, bool fShift, bool fRepeated, class C4GUI::Dialog *pForDialog = nullptr, bool fPlrCtrlOnly = false);
194 void DrawCursors(C4FacetEx &cgo, int32_t iPlayer);
195 bool LocalControlKey(C4KeyCodeEx key, C4KeySetCtrl Ctrl);
196 bool LocalControlKeyUp(C4KeyCodeEx key, C4KeySetCtrl Ctrl);
197 void LocalPlayerControl(int32_t iPlayer, int32_t iCom);
198 void FixRandom(int32_t iSeed);
199 bool Init();
200 bool PreInit();
201 void InitLogger();
202 void ParseCommandLine(const char *szCmdLine);
203 bool Execute();
204 class C4Player *JoinPlayer(const char *szFilename, int32_t iAtClient, const char *szAtClientName, C4PlayerInfo *pInfo);
205 bool DoGameOver();
206 bool CanQuickSave();
207 bool QuickSave(const char *strFilename, const char *strTitle, bool fForceSave = false);
208 void SetInitProgress(float fToProgress);
209 void OnResolutionChanged(); // update anything that's dependent on screen resolution
210 void InitFullscreenComponents(bool fRunning);
211 bool ToggleChat();
212 // Pause
213 bool TogglePause();
214 bool Pause();
215 bool Unpause();
216 bool IsPaused();
217 // Network
218 void Synchronize(bool fSavePlayerFiles);
219 void SyncClearance();
220 // Editing
221 bool DropFile(const char *szFilename, int32_t iX, int32_t iY);
222 bool CreateViewport(int32_t iPlayer, bool fSilent = false);
223 bool DropDef(C4ID id, int32_t iX, int32_t iY);
224 void ReloadFile(const char *path);
225 bool ReloadDef(C4ID id, uint32_t reloadWhat = C4D_Load_RX);
226 bool ReloadParticle(const char *szName);
227 // Object functions
228 void ClearPointers(C4Object *cobj);
229 C4Object *CreateObject(C4ID type, C4Object *pCreator, int32_t owner = NO_OWNER,
230 int32_t x = 50, int32_t y = 50, int32_t r = 0,
231 C4Fixed xdir = Fix0, C4Fixed ydir = Fix0, C4Fixed rdir = Fix0, int32_t iController = NO_OWNER);
232 C4Object *CreateObjectConstruction(C4ID type,
233 C4Object *pCreator,
234 int32_t owner,
235 int32_t ctx = 0, int32_t bty = 0,
236 int32_t con = 1, bool terrain = false);
237 C4Object *CreateInfoObject(C4ObjectInfo *cinf, int32_t owner,
238 int32_t tx = 50, int32_t ty = 50);
239 void BlastObjects(int32_t tx, int32_t ty, int32_t level, C4Object *inobj, int32_t iCausedBy, C4Object *pByObj);
240 void ShakeObjects(int32_t tx, int32_t ry, int32_t range, int32_t iCausedBy);
241 C4Object *OverlapObject(int32_t tx, int32_t ty, int32_t wdt, int32_t hgt,
242 int32_t category);
243 C4Object *FindObject(C4ID id,
244 int32_t iX = 0, int32_t iY = 0, int32_t iWdt = 0, int32_t iHgt = 0,
245 uint32_t ocf = OCF_All,
246 const char *szAction = nullptr, C4Object *pActionTarget = nullptr,
247 C4Object *pExclude = nullptr,
248 C4Object *pContainer = nullptr,
249 int32_t iOwner = ANY_OWNER,
250 C4Object *pFindNext = nullptr);
251 C4Object *FindVisObject( // find object in view at pos, regarding parallaxity and visibility (but not distance)
252 int32_t tx, int32_t ty, int32_t iPlr, const C4Facet &fctViewport,
253 int32_t iX = 0, int32_t iY = 0, int32_t iWdt = 0, int32_t iHgt = 0,
254 uint32_t ocf = OCF_All,
255 C4Object *pExclude = nullptr,
256 int32_t iOwner = ANY_OWNER,
257 C4Object *pFindNext = nullptr);
258 int32_t ObjectCount(C4ID id,
259 int32_t x = 0, int32_t y = 0, int32_t wdt = 0, int32_t hgt = 0,
260 uint32_t ocf = OCF_All,
261 const char *szAction = nullptr, C4Object *pActionTarget = nullptr,
262 C4Object *pExclude = nullptr,
263 C4Object *pContainer = nullptr,
264 int32_t iOwner = ANY_OWNER);
265 C4Object *FindBase(int32_t iPlayer, int32_t iIndex);
266 C4Object *FindFriendlyBase(int32_t iPlayer, int32_t iIndex);
267 C4Object *FindObjectByCommand(int32_t iCommand, C4Object *pTarget = nullptr, C4Value iTx = C4VNull, int32_t iTy = 0, C4Object *pTarget2 = nullptr, C4Object *pFindNext = nullptr);
268 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);
269 void BlastCastObjects(C4ID id, C4Object *pCreator, int32_t num, int32_t tx, int32_t ty, int32_t iController = NO_OWNER);
270 C4Object *PlaceVegetation(C4ID id, int32_t iX, int32_t iY, int32_t iWdt, int32_t iHgt, int32_t iGrowth);
271 C4Object *PlaceAnimal(C4ID idAnimal);
272
273 bool LoadScenarioSection(const char *szSection, uint32_t dwFlags);
274
275 bool DrawTextSpecImage(C4FacetExSurface &fctTarget, const char *szSpec, uint32_t dwClr = 0xff);
276 bool SpeedUp();
277 bool SlowDown();
278 bool InitKeyboard(); // register main keyboard input functions
279
280protected:
281 bool InitSystem();
282 void InitInEarth();
283 void InitVegetation();
284 void InitAnimals();
285 void InitGoals();
286 void InitRules();
287 void InitValueOverloads();
288 void InitEnvironment();
289 void UpdateRules();
290 void CloseScenario();
291 void DeleteObjects(bool fDeleteInactive);
292 void ExecObjects();
293 void Ticks();
294 std::vector<std::string> FoldersWithLocalsDefs(std::string path);
295 bool CheckObjectEnumeration();
296 bool DefinitionFilenamesFromSaveGame();
297 bool LoadScenarioComponents();
298 void LoadScenarioScripts();
299
300public:
301 bool SaveGameTitle(C4Group &hGroup);
302 bool Preload();
303 bool CanPreload() const;
304
305protected:
306 bool InitGame(C4Group &hGroup, C4ScenarioSection *section, bool fLoadSky);
307 bool InitGameFirstPart();
308 bool InitGameSecondPart(C4Group &hGroup, C4ScenarioSection *section, bool fLoadSky, bool preloading);
309 bool InitGameFinal();
310 bool InitNetworkFromAddress(const char *szAddress);
311 bool InitNetworkFromReference(const C4Network2Reference &Reference);
312 bool InitNetworkHost();
313 bool InitControl();
314 bool InitScriptEngine();
315 void LinkScriptEngine();
316 bool InitPlayers();
317 bool OpenScenario();
318 bool InitDefs();
319 bool InitMaterialTexture();
320 bool EnumerateMaterials();
321 bool GameOverCheck();
322 bool PlaceInEarth(C4ID id);
323 bool Compile(const char *szSource);
324 bool Decompile(std::string &buf, bool fSaveSection, bool fSaveExact);
325
326public:
327 void CompileFunc(StdCompiler *pComp, CompileSettings comp);
328 bool SaveData(C4Group &hGroup, bool fSaveSection, bool fInitial, bool fSaveExact);
329
330protected:
331 bool CompileRuntimeData(C4ComponentHost &rGameData);
332
333 // Object function internals
334 C4Object *NewObject(C4Def *ndef, C4Object *pCreator,
335 int32_t owner, C4ObjectInfo *info,
336 int32_t tx, int32_t ty, int32_t tr,
337 C4Fixed xdir, C4Fixed ydir, C4Fixed rdir,
338 int32_t con, int32_t iController);
339 void ClearObjectPtrs(C4Object *tptr);
340 void ObjectRemovalCheck();
341
342 bool ToggleDebugMode(); // dbg modeon/off if allowed
343
344public:
345 bool ToggleChart(); // chart dlg on/off
346 void SetMusicLevel(int32_t iToLvl); // change game music volume; multiplied by config volume for real volume
347 bool ToggleMusic(); // music on / off
348 bool ToggleSound(); // sound on / off
349 void AddDirectoryForMonitoring(const char *directory);
350
351protected:
352 enum class PreloadLevel
353 {
354 None,
355 Scenario,
356 Basic,
357 LandscapeObjects
358 };
359 std::thread PreloadThread;
360 PreloadLevel PreloadStatus;
361 CStdCSecEx PreloadMutex;
362 bool LandscapeLoaded;
363 std::unique_ptr<C4FileMonitor> FileMonitor;
364};
365
366const int32_t C4RULE_StructuresNeedEnergy = 1,
367 C4RULE_ConstructionNeedsMaterial = 2,
368 C4RULE_FlagRemoveable = 4,
369 C4RULE_StructuresSnowIn = 8,
370 C4RULE_TeamHombase = 16;
371
372extern C4Game Game;
373
374// a global wrapper
375inline std::string GetKeyboardInputName(const char *szKeyName, bool fShort = false, int32_t iIndex = 0)
376{
377 return Game.KeyboardInput.GetKeyCodeNameByKeyName(szKeyName, fShort, iIndex);
378}
379