OpenTTD Source  14.0-beta3
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 
46  Backup<CompanyID> cur_company(_current_company, FILE_LINE);
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(bool randomise)
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 
86  if (randomise) config->AddRandomDeviation();
88 
89  Backup<CompanyID> cur_company(_current_company, FILE_LINE);
90  cur_company.Change(OWNER_DEITY);
91 
92  Game::info = info;
95  Game::instance->LoadOnStack(config->GetToLoadData());
96  config->SetToLoadData(nullptr);
97 
98  cur_company.Restore();
99 
101 }
102 
103 /* static */ void Game::Uninitialize(bool keepConfig)
104 {
105  Backup<CompanyID> cur_company(_current_company, FILE_LINE);
106 
107  delete Game::instance;
108  Game::instance = nullptr;
109  Game::info = nullptr;
110 
111  cur_company.Restore();
112 
113  if (keepConfig) {
114  Rescan();
115  } else {
116  delete Game::scanner_info;
117  delete Game::scanner_library;
118  Game::scanner_info = nullptr;
119  Game::scanner_library = nullptr;
120 
121  if (_settings_game.game_config != nullptr) {
123  _settings_game.game_config = nullptr;
124  }
125  if (_settings_newgame.game_config != nullptr) {
127  _settings_newgame.game_config = nullptr;
128  }
129  }
130 }
131 
132 /* static */ void Game::Pause()
133 {
134  if (Game::instance != nullptr) Game::instance->Pause();
135 }
136 
137 /* static */ void Game::Unpause()
138 {
139  if (Game::instance != nullptr) Game::instance->Unpause();
140 }
141 
142 /* static */ bool Game::IsPaused()
143 {
144  return Game::instance != nullptr? Game::instance->IsPaused() : false;
145 }
146 
147 /* static */ void Game::NewEvent(ScriptEvent *event)
148 {
149  /* AddRef() and Release() need to be called at least once, so do it here */
150  event->AddRef();
151 
152  /* Clients should ignore events */
153  if (_networking && !_network_server) {
154  event->Release();
155  return;
156  }
157 
158  /* Check if Game instance is alive */
159  if (Game::instance == nullptr) {
160  event->Release();
161  return;
162  }
163 
164  /* Queue the event */
165  Backup<CompanyID> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
166  Game::instance->InsertEvent(event);
167  cur_company.Restore();
168 
169  event->Release();
170 }
171 
172 /* static */ void Game::ResetConfig()
173 {
174  /* Check for both newgame as current game if we can reload the GameInfo inside
175  * the GameConfig. If not, remove the Game from the list. */
177  if (!_settings_game.game_config->ResetInfo(true)) {
178  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());
179  _settings_game.game_config->Change(std::nullopt);
180  if (Game::instance != nullptr) {
181  delete Game::instance;
182  Game::instance = nullptr;
183  Game::info = nullptr;
184  }
185  } else if (Game::instance != nullptr) {
187  }
188  }
190  if (!_settings_newgame.game_config->ResetInfo(false)) {
191  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());
192  _settings_newgame.game_config->Change(std::nullopt);
193  }
194  }
195 }
196 
197 /* static */ void Game::Rescan()
198 {
200 
203  ResetConfig();
204 
209 }
210 
211 
212 /* static */ void Game::Save()
213 {
214  if (Game::instance != nullptr && (!_networking || _network_server)) {
215  Backup<CompanyID> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
216  Game::instance->Save();
217  cur_company.Restore();
218  } else {
220  }
221 }
222 
223 /* static */ void Game::GetConsoleList(std::back_insert_iterator<std::string> &output_iterator, bool newest_only)
224 {
225  Game::scanner_info->GetConsoleList(output_iterator, newest_only);
226 }
227 
228 /* static */ void Game::GetConsoleLibraryList(std::back_insert_iterator<std::string> &output_iterator)
229 {
230  Game::scanner_library->GetConsoleList(output_iterator, true);
231 }
232 
233 /* static */ const ScriptInfoList *Game::GetInfoList()
234 {
236 }
237 
239 {
241 }
242 
243 /* static */ GameInfo *Game::FindInfo(const std::string &name, int version, bool force_exact_match)
244 {
245  return Game::scanner_info->FindInfo(name, version, force_exact_match);
246 }
247 
248 /* static */ GameLibrary *Game::FindLibrary(const std::string &library, int version)
249 {
250  return Game::scanner_library->FindLibrary(library, version);
251 }
252 
259 /* static */ bool Game::HasGame(const ContentInfo *ci, bool md5sum)
260 {
261  return Game::scanner_info->HasScript(ci, md5sum);
262 }
263 
264 /* static */ bool Game::HasGameLibrary(const ContentInfo *ci, bool md5sum)
265 {
266  return Game::scanner_library->HasScript(ci, md5sum);
267 }
268 
270 {
271  return Game::scanner_info;
272 }
274 {
275  return Game::scanner_library;
276 }
game.hpp
Backup::Change
void Change(const U &new_value)
Change the value of the variable.
Definition: backup_type.hpp:84
InvalidateWindowData
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:3200
WC_SCRIPT_DEBUG
@ WC_SCRIPT_DEBUG
Script debug window; Window numbers:
Definition: window_type.h:669
Game::IsPaused
static bool IsPaused()
Checks if the Game Script is paused.
Definition: game_core.cpp:142
ScriptInfoList
std::map< std::string, class ScriptInfo *, CaseInsensitiveComparator > ScriptInfoList
Type for the list of scripts.
Definition: script_scanner.hpp:16
game_instance.hpp
ScriptInstance::InsertEvent
void InsertEvent(class ScriptEvent *event)
Insert an event for this script.
Definition: script_instance.cpp:778
ScriptInstance::GameLoop
void GameLoop()
Run the GameLoop of a script.
Definition: script_instance.cpp:171
game_info.hpp
ScriptInstance::Save
void Save()
Call the script Save function and save all data in the savegame.
Definition: script_instance.cpp:476
Backup
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:21
GameScannerLibrary::FindLibrary
class GameLibrary * FindLibrary(const std::string &library, int version)
Find a library in the pool.
Definition: game_scanner.cpp:89
TarScanner::DoScan
uint DoScan(Subdirectory sd)
Perform the scanning of a particular subdirectory.
Definition: fileio.cpp:427
_network_server
bool _network_server
network-server is active
Definition: network.cpp:60
Game::frame_counter
static uint frame_counter
Tick counter for the Game code.
Definition: game.hpp:113
ScriptInstance::Unpause
void Unpause()
Resume execution of the script.
Definition: script_instance.cpp:555
GameScannerInfo
Definition: game_scanner.hpp:15
PerformanceMeasurer
RAII class for measuring simple elements of performance.
Definition: framerate_type.h:92
GameSettings::game_config
class GameConfig * game_config
settings for gamescript
Definition: settings_type.h:624
ScriptScanner::GetConsoleList
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.
Definition: script_scanner.cpp:141
Game::Unpause
static void Unpause()
Resume execution of the Game Script.
Definition: game_core.cpp:137
PerformanceMeasurer::SetInactive
static void SetInactive(PerformanceElement elem)
Mark a performance element as not currently in use.
Definition: framerate_gui.cpp:286
ScriptScanner::RescanDir
void RescanDir()
Rescan the script dir.
Definition: script_scanner.cpp:75
Debug
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
ScriptInstance::Pause
void Pause()
Suspends the script for the current tick and then pause the execution of script.
Definition: script_instance.cpp:546
ScriptScanner::GetUniqueInfoList
const ScriptInfoList * GetUniqueInfoList()
Get the list of the latest version of all registered scripts.
Definition: script_scanner.hpp:49
ScriptInfo::version
int version
Version of the script.
Definition: script_info.hpp:152
Game::GetScannerLibrary
static GameScannerLibrary * GetScannerLibrary()
Gets the ScriptScanner instance that is used to find Game Libraries.
Definition: game_core.cpp:273
Game::FindInfo
static class GameInfo * FindInfo(const std::string &name, int version, bool force_exact_match)
Wrapper function for GameScannerInfo::FindInfo.
Definition: game_core.cpp:243
Game::scanner_library
static class GameScannerLibrary * scanner_library
Scanner for GS Libraries.
Definition: game.hpp:116
ScriptConfig::AddRandomDeviation
void AddRandomDeviation()
Randomize all settings the Script requested to be randomized.
Definition: script_config.cpp:128
Game::GetConsoleLibraryList
static void GetConsoleLibraryList(std::back_insert_iterator< std::string > &output_iterator)
Wrapper function for GameScanner::GetConsoleLibraryList.
Definition: game_core.cpp:228
Game::GetConsoleList
static void GetConsoleList(std::back_insert_iterator< std::string > &output_iterator, bool newest_only)
Wrapper function for GameScanner::GetConsoleList.
Definition: game_core.cpp:223
ContentInfo
Container for all important information about a piece of content.
Definition: tcp_content_type.h:52
ScriptInstance::SaveEmpty
static void SaveEmpty()
Don't save any data in the savegame.
Definition: script_instance.cpp:470
GameConfig
Definition: game_config.hpp:15
Game::Pause
static void Pause()
Suspends the Game Script and then pause the execution of the script.
Definition: game_core.cpp:132
GameInstance::Initialize
void Initialize(class GameInfo *info)
Initialize the script and prepare it for its first run.
Definition: game_instance.cpp:34
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:55
Game::StartNew
static void StartNew(bool randomise=true)
Start up a new GameScript.
Definition: game_core.cpp:72
Game::NewEvent
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition: game_core.cpp:147
Game::Uninitialize
static void Uninitialize(bool keepConfig)
Uninitialize the Game system.
Definition: game_core.cpp:103
_networking
bool _networking
are we in networking mode?
Definition: network.cpp:59
TarScanner::GAME
@ GAME
Scan for game scripts.
Definition: fileio_func.h:69
ScriptConfig::Change
void Change(std::optional< const std::string > name, int version=-1, bool force_exact_match=false, bool is_random=false)
Set another Script to be loaded in this slot.
Definition: script_config.cpp:21
GameInstance
Runtime information about a game script like a pointer to the squirrel vm and the current state.
Definition: game_instance.hpp:16
game_scanner.hpp
PFE_GAMESCRIPT
@ PFE_GAMESCRIPT
Game script execution.
Definition: framerate_type.h:62
_current_company
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:50
WC_GAME_OPTIONS
@ WC_GAME_OPTIONS
Game options window; Window numbers:
Definition: window_type.h:619
Game::GameLoop
static void GameLoop()
Called every game-tick to let Game do something.
Definition: game_core.cpp:31
ScriptScanner::HasScript
bool HasScript(const struct ContentInfo *ci, bool md5sum)
Check whether we have a script with the exact characteristics as ci.
Definition: script_scanner.cpp:237
ScriptConfig::AnchorUnchangeableSettings
void AnchorUnchangeableSettings()
As long as the default of a setting has not been changed, the value of the setting is not stored.
Definition: script_config.cpp:75
ScriptScanner::GetInfoList
const ScriptInfoList * GetInfoList()
Get the list of all registered scripts.
Definition: script_scanner.hpp:44
Game::info
static class GameInfo * info
Current selected GameInfo.
Definition: game.hpp:117
Backup::Restore
void Restore()
Restore the variable.
Definition: backup_type.hpp:112
GameConfig::ResetInfo
bool ResetInfo(bool force_exact_match)
When ever the Game Scanner is reloaded, all infos become invalid.
Definition: game_config.cpp:40
InvalidateWindowClassesData
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:3217
GameConfig::GetConfig
static GameConfig * GetConfig(ScriptSettingSource source=SSS_DEFAULT)
Get the config of a company.
Definition: game_config.cpp:18
Game::HasGame
static bool HasGame(const struct ContentInfo *ci, bool md5sum)
Wrapper function for GameScanner::HasGame.
Definition: game_core.cpp:259
GameInfo
All static information from an Game like name, version, etc.
Definition: game_info.hpp:16
ScriptInfo::name
std::string name
Full name of the script.
Definition: script_info.hpp:147
GameScannerInfo::FindInfo
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.
Definition: game_scanner.cpp:36
ScriptInstance::LoadOnStack
void LoadOnStack(ScriptData *data)
Store loaded data on the stack.
Definition: script_instance.cpp:690
OWNER_DEITY
@ OWNER_DEITY
The object is owned by a superuser / goal script.
Definition: company_type.h:27
Game::Save
static void Save()
Save data from a GameScript to a savegame.
Definition: game_core.cpp:212
GameLibrary
All static information from an Game library like name, version, etc.
Definition: game_info.hpp:49
Game::GetScannerInfo
static GameScannerInfo * GetScannerInfo()
Gets the ScriptScanner instance that is used to find Game scripts.
Definition: game_core.cpp:269
ScriptInstance::IsPaused
bool IsPaused()
Checks if the script is paused.
Definition: script_instance.cpp:560
ScriptInstance::CollectGarbage
void CollectGarbage()
Let the VM collect any garbage.
Definition: script_instance.cpp:260
Game::GetUniqueInfoList
static const ScriptInfoList * GetUniqueInfoList()
Wrapper function for GameScanner::GetUniqueInfoList.
Definition: game_core.cpp:238
GameScannerLibrary
Definition: game_scanner.hpp:37
Game::FindLibrary
static class GameLibrary * FindLibrary(const std::string &library, int version)
Wrapper function for GameScanner::FindLibrary.
Definition: game_core.cpp:248
WC_SCRIPT_SETTINGS
@ WC_SCRIPT_SETTINGS
Script settings; Window numbers:
Definition: window_type.h:175
WC_SCRIPT_LIST
@ WC_SCRIPT_LIST
Scripts list; Window numbers:
Definition: window_type.h:284
game_config.hpp
SetWindowClassesDirty
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition: window.cpp:3108
ScriptConfig::SSS_FORCE_GAME
@ SSS_FORCE_GAME
Get the Script config from the current game.
Definition: script_config.hpp:99
ScriptConfig::HasScript
bool HasScript() const
Is this config attached to an Script? In other words, is there a Script that is assigned to this slot...
Definition: script_config.cpp:137
Game::scanner_info
static class GameScannerInfo * scanner_info
Scanner for Game scripts.
Definition: game.hpp:115
_settings_newgame
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition: settings.cpp:56
Game::instance
static class GameInstance * instance
Instance to the current active Game.
Definition: game.hpp:114
Game::GetInfoList
static const ScriptInfoList * GetInfoList()
Wrapper function for GameScanner::GetInfoList.
Definition: game_core.cpp:233
ScriptConfig::GetName
const std::string & GetName() const
Get the name of the Script.
Definition: script_config.cpp:147
Game::Initialize
static void Initialize()
Initialize the Game system.
Definition: game_core.cpp:57