OpenTTD Source 20250529-master-g10c159a79f
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 */ std::unique_ptr<GameInstance> Game::instance = nullptr;
28/* static */ std::unique_ptr<GameScannerInfo> Game::scanner_info = nullptr;
29/* static */ std::unique_ptr<GameScannerLibrary> Game::scanner_library = nullptr;
30
31/* static */ void Game::GameLoop()
32{
35 return;
36 }
37 if (Game::instance == nullptr) {
39 return;
40 }
41
43
45
47 cur_company.Change(OWNER_DEITY);
48 Game::instance->GameLoop();
49 cur_company.Restore();
50
51 /* Occasionally collect garbage */
52 if ((Game::frame_counter & 255) == 0) {
53 Game::instance->CollectGarbage();
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) {
65 Game::scanner_info = std::make_unique<GameScannerInfo>();
66 Game::scanner_info->Initialize();
67 Game::scanner_library = std::make_unique<GameScannerLibrary>();
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
92 Game::instance = std::make_unique<GameInstance>();
93 Game::instance->Initialize(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{
105
107
108 cur_company.Restore();
109
110 if (keepConfig) {
111 Rescan();
112 } else {
113 Game::scanner_info.reset();
114 Game::scanner_library.reset();
115
118 }
119}
120
121/* static */ void Game::Pause()
122{
123 if (Game::instance != nullptr) Game::instance->Pause();
124}
125
126/* static */ void Game::Unpause()
127{
128 if (Game::instance != nullptr) Game::instance->Unpause();
129}
130
131/* static */ bool Game::IsPaused()
132{
133 return Game::instance != nullptr? Game::instance->IsPaused() : false;
134}
135
136/* static */ void Game::NewEvent(ScriptEvent *event)
137{
138 ScriptObjectRef counter(event);
139
140 /* Clients should ignore events */
142 return;
143 }
144
145 /* Check if Game instance is alive */
146 if (Game::instance == nullptr) {
147 return;
148 }
149
150 /* Queue the event */
152 Game::instance->InsertEvent(event);
153 cur_company.Restore();
154}
155
156/* static */ void Game::ResetConfig()
157{
158 /* Check for both newgame as current game if we can reload the GameInfo inside
159 * the GameConfig. If not, remove the Game from the list. */
160 if (_settings_game.script_config.game != nullptr && _settings_game.script_config.game->HasScript()) {
161 if (!_settings_game.script_config.game->ResetInfo(true)) {
162 Debug(script, 0, "After a reload, the GameScript by the name '{}' was no longer found, and removed from the list.", _settings_game.script_config.game->GetName());
163 _settings_game.script_config.game->Change(std::nullopt);
164 if (Game::instance != nullptr) Game::ResetInstance();
165 } else if (Game::instance != nullptr) {
167 }
168 }
170 if (!_settings_newgame.script_config.game->ResetInfo(false)) {
171 Debug(script, 0, "After a reload, the GameScript by the name '{}' was no longer found, and removed from the list.", _settings_newgame.script_config.game->GetName());
172 _settings_newgame.script_config.game->Change(std::nullopt);
173 }
174 }
175}
176
177/* static */ void Game::Rescan()
178{
180
181 Game::scanner_info->RescanDir();
182 Game::scanner_library->RescanDir();
183 ResetConfig();
184
189}
190
191
192/* static */ void Game::Save()
193{
194 if (Game::instance != nullptr && (!_networking || _network_server)) {
196 Game::instance->Save();
197 cur_company.Restore();
198 } else {
200 }
201}
202
203/* static */ void Game::GetConsoleList(std::back_insert_iterator<std::string> &output_iterator, bool newest_only)
204{
205 Game::scanner_info->GetConsoleList(output_iterator, newest_only);
206}
207
208/* static */ void Game::GetConsoleLibraryList(std::back_insert_iterator<std::string> &output_iterator)
209{
210 Game::scanner_library->GetConsoleList(output_iterator, true);
211}
212
214{
215 return Game::scanner_info->GetInfoList();
216}
217
219{
220 return Game::scanner_info->GetUniqueInfoList();
221}
222
223/* static */ GameInfo *Game::FindInfo(const std::string &name, int version, bool force_exact_match)
224{
225 return Game::scanner_info->FindInfo(name, version, force_exact_match);
226}
227
228/* static */ GameLibrary *Game::FindLibrary(const std::string &library, int version)
229{
230 return Game::scanner_library->FindLibrary(library, version);
231}
232
233/* static */ void Game::ResetInstance()
234{
235 Game::instance.reset();
236 Game::info = nullptr;
237}
238
245/* static */ bool Game::HasGame(const ContentInfo &ci, bool md5sum)
246{
247 return Game::scanner_info->HasScript(ci, md5sum);
248}
249
250/* static */ bool Game::HasGameLibrary(const ContentInfo &ci, bool md5sum)
251{
252 return Game::scanner_library->HasScript(ci, md5sum);
253}
254
256{
257 return Game::scanner_info.get();
258}
260{
261 return Game::scanner_library.get();
262}
static GameConfig * GetConfig(ScriptSettingSource source=SSS_DEFAULT)
Get the config of a company.
All static information from an Game like name, version, etc.
Definition game_info.hpp:16
All static information from an Game library like name, version, etc.
Definition game_info.hpp:52
static void StartNew()
Start up a new GameScript.
Definition game_core.cpp:72
static 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.
static bool HasGame(const ContentInfo &ci, bool md5sum)
Wrapper function for GameScanner::HasGame.
static GameScannerLibrary * GetScannerLibrary()
Gets the ScriptScanner instance that is used to find Game Libraries.
static void Unpause()
Resume execution of the Game Script.
static bool IsPaused()
Checks if the Game Script is paused.
static uint frame_counter
Tick counter for the Game code.
Definition game.hpp:112
static std::unique_ptr< GameInstance > instance
Instance to the current active Game.
Definition game.hpp:113
static void Save()
Save data from a GameScript to a savegame.
static void ResetInstance()
Reset the current active instance.
static class GameLibrary * FindLibrary(const std::string &library, int version)
Wrapper function for GameScanner::FindLibrary.
static const ScriptInfoList * GetUniqueInfoList()
Wrapper function for GameScanner::GetUniqueInfoList.
static void Pause()
Suspends the Game Script and then pause the execution of the script.
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
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.
static void GetConsoleLibraryList(std::back_insert_iterator< std::string > &output_iterator)
Wrapper function for GameScanner::GetConsoleLibraryList.
static void Uninitialize(bool keepConfig)
Uninitialize the Game system.
static std::unique_ptr< GameScannerInfo > scanner_info
Scanner for Game scripts.
Definition game.hpp:114
static const ScriptInfoList * GetInfoList()
Wrapper function for GameScanner::GetInfoList.
static void Initialize()
Initialize the Game system.
Definition game_core.cpp:57
static std::unique_ptr< GameScannerLibrary > scanner_library
Scanner for GS Libraries.
Definition game.hpp:115
static GameScannerInfo * GetScannerInfo()
Gets the ScriptScanner instance that is used to find Game scripts.
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.
static void SaveEmpty()
Don't save any data in the savegame.
@ Game
Scan for game scripts.
uint DoScan(Subdirectory sd)
Perform the scanning of a particular subdirectory.
Definition fileio.cpp:374
CompanyID _current_company
Company currently doing an action.
static constexpr Owner OWNER_DEITY
The object is owned by a superuser / goal script.
#define Debug(category, level, format_string,...)
Output 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:67
bool _network_server
network-server is active
Definition network.cpp:68
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:61
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:62
Class to backup a specific variable and restore it later.
void Change(const U &new_value)
Change the value of the variable.
void Restore()
Restore the variable.
Container for all important information about a piece of content.
ScriptConfigSettings script_config
AI and Gamescript configuration.
std::unique_ptr< class GameConfig > game
settings for gamescript
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3173
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:3265
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:3282
@ WC_SCRIPT_SETTINGS
Script settings; Window numbers:
@ WC_SCRIPT_LIST
Scripts list; Window numbers:
@ WC_GAME_OPTIONS
Game options window; Window numbers:
@ WC_SCRIPT_DEBUG
Script debug window; Window numbers: