OpenTTD Source  20241120-master-g6d3adc6169
game_core.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "../stdafx.h"
11 #include "../core/backup_type.hpp"
12 #include "../company_base.h"
13 #include "../company_func.h"
14 #include "../network/network.h"
15 #include "../window_func.h"
16 #include "../framerate_type.h"
17 #include "game.hpp"
18 #include "game_scanner.hpp"
19 #include "game_config.hpp"
20 #include "game_instance.hpp"
21 #include "game_info.hpp"
22 
23 #include "../safeguards.h"
24 
25 /* static */ uint Game::frame_counter = 0;
26 /* static */ GameInfo *Game::info = nullptr;
27 /* static */ GameInstance *Game::instance = nullptr;
28 /* static */ GameScannerInfo *Game::scanner_info = nullptr;
29 /* static */ GameScannerLibrary *Game::scanner_library = nullptr;
30 
31 /* static */ void Game::GameLoop()
32 {
33  if (_networking && !_network_server) {
35  return;
36  }
37  if (Game::instance == nullptr) {
39  return;
40  }
41 
43 
45 
47  cur_company.Change(OWNER_DEITY);
49  cur_company.Restore();
50 
51  /* Occasionally collect garbage */
52  if ((Game::frame_counter & 255) == 0) {
54  }
55 }
56 
57 /* static */ void Game::Initialize()
58 {
59  if (Game::instance != nullptr) Game::Uninitialize(true);
60 
62 
63  if (Game::scanner_info == nullptr) {
66  Game::scanner_info->Initialize();
68  Game::scanner_library->Initialize();
69  }
70 }
71 
72 /* static */ void Game::StartNew()
73 {
74  if (Game::instance != nullptr) return;
75 
76  /* Don't start GameScripts in intro */
77  if (_game_mode == GM_MENU) return;
78 
79  /* Clients shouldn't start GameScripts */
80  if (_networking && !_network_server) return;
81 
83  GameInfo *info = config->GetInfo();
84  if (info == nullptr) return;
85 
87 
89  cur_company.Change(OWNER_DEITY);
90 
91  Game::info = info;
94  Game::instance->LoadOnStack(config->GetToLoadData());
95  config->SetToLoadData(nullptr);
96 
97  cur_company.Restore();
98 
100 }
101 
102 /* static */ void Game::Uninitialize(bool keepConfig)
103 {
104  Backup<CompanyID> cur_company(_current_company);
105 
106  delete Game::instance;
107  Game::instance = nullptr;
108  Game::info = nullptr;
109 
110  cur_company.Restore();
111 
112  if (keepConfig) {
113  Rescan();
114  } else {
115  delete Game::scanner_info;
116  delete Game::scanner_library;
117  Game::scanner_info = nullptr;
118  Game::scanner_library = nullptr;
119 
120  if (_settings_game.game_config != nullptr) {
122  _settings_game.game_config = nullptr;
123  }
124  if (_settings_newgame.game_config != nullptr) {
126  _settings_newgame.game_config = nullptr;
127  }
128  }
129 }
130 
131 /* static */ void Game::Pause()
132 {
133  if (Game::instance != nullptr) Game::instance->Pause();
134 }
135 
136 /* static */ void Game::Unpause()
137 {
138  if (Game::instance != nullptr) Game::instance->Unpause();
139 }
140 
141 /* static */ bool Game::IsPaused()
142 {
143  return Game::instance != nullptr? Game::instance->IsPaused() : false;
144 }
145 
146 /* static */ void Game::NewEvent(ScriptEvent *event)
147 {
148  ScriptObjectRef counter(event);
149 
150  /* Clients should ignore events */
151  if (_networking && !_network_server) {
152  return;
153  }
154 
155  /* Check if Game instance is alive */
156  if (Game::instance == nullptr) {
157  return;
158  }
159 
160  /* Queue the event */
162  Game::instance->InsertEvent(event);
163  cur_company.Restore();
164 }
165 
166 /* static */ void Game::ResetConfig()
167 {
168  /* Check for both newgame as current game if we can reload the GameInfo inside
169  * the GameConfig. If not, remove the Game from the list. */
171  if (!_settings_game.game_config->ResetInfo(true)) {
172  Debug(script, 0, "After a reload, the GameScript by the name '{}' was no longer found, and removed from the list.", _settings_game.game_config->GetName());
173  _settings_game.game_config->Change(std::nullopt);
174  if (Game::instance != nullptr) {
175  delete Game::instance;
176  Game::instance = nullptr;
177  Game::info = nullptr;
178  }
179  } else if (Game::instance != nullptr) {
181  }
182  }
184  if (!_settings_newgame.game_config->ResetInfo(false)) {
185  Debug(script, 0, "After a reload, the GameScript by the name '{}' was no longer found, and removed from the list.", _settings_newgame.game_config->GetName());
186  _settings_newgame.game_config->Change(std::nullopt);
187  }
188  }
189 }
190 
191 /* static */ void Game::Rescan()
192 {
194 
197  ResetConfig();
198 
203 }
204 
205 
206 /* static */ void Game::Save()
207 {
208  if (Game::instance != nullptr && (!_networking || _network_server)) {
210  Game::instance->Save();
211  cur_company.Restore();
212  } else {
214  }
215 }
216 
217 /* static */ void Game::GetConsoleList(std::back_insert_iterator<std::string> &output_iterator, bool newest_only)
218 {
219  Game::scanner_info->GetConsoleList(output_iterator, newest_only);
220 }
221 
222 /* static */ void Game::GetConsoleLibraryList(std::back_insert_iterator<std::string> &output_iterator)
223 {
224  Game::scanner_library->GetConsoleList(output_iterator, true);
225 }
226 
227 /* static */ const ScriptInfoList *Game::GetInfoList()
228 {
230 }
231 
233 {
235 }
236 
237 /* static */ GameInfo *Game::FindInfo(const std::string &name, int version, bool force_exact_match)
238 {
239  return Game::scanner_info->FindInfo(name, version, force_exact_match);
240 }
241 
242 /* static */ GameLibrary *Game::FindLibrary(const std::string &library, int version)
243 {
244  return Game::scanner_library->FindLibrary(library, version);
245 }
246 
253 /* static */ bool Game::HasGame(const ContentInfo *ci, bool md5sum)
254 {
255  return Game::scanner_info->HasScript(ci, md5sum);
256 }
257 
258 /* static */ bool Game::HasGameLibrary(const ContentInfo *ci, bool md5sum)
259 {
260  return Game::scanner_library->HasScript(ci, md5sum);
261 }
262 
264 {
265  return Game::scanner_info;
266 }
268 {
269  return Game::scanner_library;
270 }
bool ResetInfo(bool force_exact_match)
When ever the Game Scanner is reloaded, all infos become invalid.
Definition: game_config.cpp:40
static GameConfig * GetConfig(ScriptSettingSource source=SSS_DEFAULT)
Get the config of a company.
Definition: game_config.cpp:18
All static information from an Game like name, version, etc.
Definition: game_info.hpp:16
Runtime information about a game script like a pointer to the squirrel vm and the current state.
void Initialize(class GameInfo *info)
Initialize the script and prepare it for its first run.
All static information from an Game library like name, version, etc.
Definition: game_info.hpp:49
class GameInfo * FindInfo(const std::string &name, int version, bool force_exact_match)
Check if we have a game by name and version available in our list.
class GameLibrary * FindLibrary(const std::string &library, int version)
Find a library in the pool.
static void StartNew()
Start up a new GameScript.
Definition: game_core.cpp:72
static class GameInfo * info
Current selected GameInfo.
Definition: game.hpp:116
static class GameInfo * FindInfo(const std::string &name, int version, bool force_exact_match)
Wrapper function for GameScannerInfo::FindInfo.
Definition: game_core.cpp:237
static GameScannerLibrary * GetScannerLibrary()
Gets the ScriptScanner instance that is used to find Game Libraries.
Definition: game_core.cpp:267
static void Unpause()
Resume execution of the Game Script.
Definition: game_core.cpp:136
static bool IsPaused()
Checks if the Game Script is paused.
Definition: game_core.cpp:141
static uint frame_counter
Tick counter for the Game code.
Definition: game.hpp:112
static void Save()
Save data from a GameScript to a savegame.
Definition: game_core.cpp:206
static class GameScannerInfo * scanner_info
Scanner for Game scripts.
Definition: game.hpp:114
static class GameInstance * instance
Instance to the current active Game.
Definition: game.hpp:113
static class GameScannerLibrary * scanner_library
Scanner for GS Libraries.
Definition: game.hpp:115
static bool HasGame(const struct ContentInfo *ci, bool md5sum)
Wrapper function for GameScanner::HasGame.
Definition: game_core.cpp:253
static class GameLibrary * FindLibrary(const std::string &library, int version)
Wrapper function for GameScanner::FindLibrary.
Definition: game_core.cpp:242
static const ScriptInfoList * GetUniqueInfoList()
Wrapper function for GameScanner::GetUniqueInfoList.
Definition: game_core.cpp:232
static void Pause()
Suspends the Game Script and then pause the execution of the script.
Definition: game_core.cpp:131
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition: game_core.cpp:146
static void GameLoop()
Called every game-tick to let Game do something.
Definition: game_core.cpp:31
static void GetConsoleList(std::back_insert_iterator< std::string > &output_iterator, bool newest_only)
Wrapper function for GameScanner::GetConsoleList.
Definition: game_core.cpp:217
static void GetConsoleLibraryList(std::back_insert_iterator< std::string > &output_iterator)
Wrapper function for GameScanner::GetConsoleLibraryList.
Definition: game_core.cpp:222
static void Uninitialize(bool keepConfig)
Uninitialize the Game system.
Definition: game_core.cpp:102
static const ScriptInfoList * GetInfoList()
Wrapper function for GameScanner::GetInfoList.
Definition: game_core.cpp:227
static void Initialize()
Initialize the Game system.
Definition: game_core.cpp:57
static GameScannerInfo * GetScannerInfo()
Gets the ScriptScanner instance that is used to find Game scripts.
Definition: game_core.cpp:263
RAII class for measuring simple elements of performance.
static void SetInactive(PerformanceElement elem)
Mark a performance element as not currently in use.
@ SSS_FORCE_GAME
Get the Script config from the current game.
void AnchorUnchangeableSettings()
As long as the default of a setting has not been changed, the value of the setting is not stored.
bool HasScript() const
Is this config attached to an Script? In other words, is there a Script that is assigned to this slot...
void Change(std::optional< const std::string > name, int version=-1, bool force_exact_match=false)
Set another Script to be loaded in this slot.
const std::string & GetName() const
Get the name of the Script.
void InsertEvent(class ScriptEvent *event)
Insert an event for this script.
void Unpause()
Resume execution of the script.
bool IsPaused()
Checks if the script is paused.
void CollectGarbage()
Let the VM collect any garbage.
static void SaveEmpty()
Don't save any data in the savegame.
void LoadOnStack(ScriptData *data)
Store loaded data on the stack.
void Save()
Call the script Save function and save all data in the savegame.
void Pause()
Suspends the script for the current tick and then pause the execution of script.
void GameLoop()
Run the GameLoop of a script.
bool HasScript(const struct ContentInfo *ci, bool md5sum)
Check whether we have a script with the exact characteristics as ci.
const ScriptInfoList * GetUniqueInfoList()
Get the list of the latest version of all registered scripts.
const ScriptInfoList * GetInfoList()
Get the list of all registered scripts.
void RescanDir()
Rescan the script dir.
void GetConsoleList(std::back_insert_iterator< std::string > &output_iterator, bool newest_only) const
Get the list of registered scripts to print on the console.
uint DoScan(Subdirectory sd)
Perform the scanning of a particular subdirectory.
Definition: fileio.cpp:375
@ GAME
Scan for game scripts.
Definition: fileio_func.h:69
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:53
@ OWNER_DEITY
The object is owned by a superuser / goal script.
Definition: company_type.h:27
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
@ PFE_GAMESCRIPT
Game script execution.
Base functions for all Games.
GameConfig stores the configuration settings of every Game.
GameInfo keeps track of all information of an Game, like Author, Description, ...
The GameInstance tracks games.
declarations of the class for Game scanner
bool _networking
are we in networking mode?
Definition: network.cpp:65
bool _network_server
network-server is active
Definition: network.cpp:66
std::map< std::string, class ScriptInfo *, CaseInsensitiveComparator > ScriptInfoList
Type for the list of scripts.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:57
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition: settings.cpp:58
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:21
void Change(const U &new_value)
Change the value of the variable.
Definition: backup_type.hpp:82
void Restore()
Restore the variable.
Container for all important information about a piece of content.
class GameConfig * game_config
settings for gamescript
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition: window.cpp:3119
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition: window.cpp:3211
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Definition: window.cpp:3228
@ WC_SCRIPT_SETTINGS
Script settings; Window numbers:
Definition: window_type.h:175
@ WC_SCRIPT_LIST
Scripts list; Window numbers:
Definition: window_type.h:284
@ WC_GAME_OPTIONS
Game options window; Window numbers:
Definition: window_type.h:624
@ WC_SCRIPT_DEBUG
Script debug window; Window numbers:
Definition: window_type.h:674