OpenTTD Source 20260512-master-g20b387b91f
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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "../stdafx.h"
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 Game::instance->GameLoop();
48
49 /* Occasionally collect garbage */
50 if ((Game::frame_counter & 255) == 0) {
51 Game::instance->CollectGarbage();
52 }
53}
54
55/* static */ void Game::Initialize()
56{
57 if (Game::instance != nullptr) Game::Uninitialize(true);
58
60
61 if (Game::scanner_info == nullptr) {
63 Game::scanner_info = std::make_unique<GameScannerInfo>();
64 Game::scanner_info->Initialize();
65 Game::scanner_library = std::make_unique<GameScannerLibrary>();
66 Game::scanner_library->Initialize();
67 }
68}
69
70/* static */ void Game::StartNew()
71{
72 if (Game::instance != nullptr) return;
73
74 /* Don't start GameScripts in intro */
75 if (_game_mode == GM_MENU) return;
76
77 /* Clients shouldn't start GameScripts */
78 if (_networking && !_network_server) return;
79
81 GameInfo *info = config->GetInfo();
82 if (info == nullptr) return;
83
85
87
89 Game::instance = std::make_unique<GameInstance>();
90 Game::instance->Initialize(info);
91 Game::instance->LoadOnStack(config->GetToLoadData());
92 config->SetToLoadData(nullptr);
93
95}
96
97/* static */ void Game::Uninitialize(bool keepConfig)
98{
100
102
103 cur_company.Restore();
104
105 if (keepConfig) {
106 Rescan();
107 } else {
108 Game::scanner_info.reset();
109 Game::scanner_library.reset();
110
111 _settings_game.script_config.game.reset();
112 _settings_newgame.script_config.game.reset();
113 }
114}
115
116/* static */ void Game::Pause()
117{
118 if (Game::instance != nullptr) Game::instance->Pause();
119}
120
121/* static */ void Game::Unpause()
122{
123 if (Game::instance != nullptr) Game::instance->Unpause();
124}
125
126/* static */ bool Game::IsPaused()
127{
128 return Game::instance != nullptr? Game::instance->IsPaused() : false;
129}
130
131/* static */ void Game::NewEvent(ScriptEvent *event)
132{
133 ScriptObjectRef counter(event);
134
135 /* Clients should ignore events */
137 return;
138 }
139
140 /* Check if Game instance is alive */
141 if (Game::instance == nullptr) {
142 return;
143 }
144
145 /* Queue the event */
147 Game::instance->InsertEvent(event);
148}
149
150/* static */ void Game::ResetConfig()
151{
152 /* Check for both newgame as current game if we can reload the GameInfo inside
153 * the GameConfig. If not, remove the Game from the list. */
154 if (_settings_game.script_config.game != nullptr && _settings_game.script_config.game->HasScript()) {
155 if (!_settings_game.script_config.game->ResetInfo(true)) {
156 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());
157 _settings_game.script_config.game->Change(std::nullopt);
158 if (Game::instance != nullptr) Game::ResetInstance();
159 } else if (Game::instance != nullptr) {
160 Game::info = _settings_game.script_config.game->GetInfo();
161 }
162 }
163 if (_settings_newgame.script_config.game != nullptr && _settings_newgame.script_config.game->HasScript()) {
164 if (!_settings_newgame.script_config.game->ResetInfo(false)) {
165 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());
166 _settings_newgame.script_config.game->Change(std::nullopt);
167 }
168 }
169}
170
184
185
186/* static */ void Game::Save()
187{
188 if (Game::instance != nullptr && (!_networking || _network_server)) {
190 Game::instance->Save();
191 } else {
193 }
194}
195
196/* static */ void Game::GetConsoleList(std::back_insert_iterator<std::string> &output_iterator, bool newest_only)
197{
198 Game::scanner_info->GetConsoleList(output_iterator, newest_only);
199}
200
201/* static */ void Game::GetConsoleLibraryList(std::back_insert_iterator<std::string> &output_iterator, bool newest_only)
202{
203 Game::scanner_library->GetConsoleList(output_iterator, newest_only);
204}
205
207{
208 return Game::scanner_info->GetInfoList();
209}
210
212{
213 return Game::scanner_info->GetUniqueInfoList();
214}
215
216/* static */ GameInfo *Game::FindInfo(const std::string &name, int version, bool force_exact_match)
217{
218 return Game::scanner_info->FindInfo(name, version, force_exact_match);
219}
220
221/* static */ GameLibrary *Game::FindLibrary(const std::string &library, int version)
222{
223 return Game::scanner_library->FindLibrary(library, version);
224}
225
226/* static */ void Game::ResetInstance()
227{
228 Game::instance.reset();
229 Game::info = nullptr;
230}
231
238/* static */ bool Game::HasGame(const ContentInfo &ci, bool md5sum)
239{
240 return Game::scanner_info->HasScript(ci, md5sum);
241}
242
249/* static */ bool Game::HasGameLibrary(const ContentInfo &ci, bool md5sum)
250{
251 return Game::scanner_library->HasScript(ci, md5sum);
252}
253
259{
260 return Game::scanner_info.get();
261}
262
268{
269 return Game::scanner_library.get();
270}
Class for backupping variables and making sure they are restored later.
Game script instantion of script configuration.
class GameInfo * GetInfo() const
Get the ScriptInfo linked to this ScriptConfig.
static GameConfig * GetConfig(ScriptSettingSource source=ScriptSettingSource::Default)
Get the script configuration.
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:58
Game instantiation of a ScriptScanner.
Game instantiation of a ScriptScanner for libraries.
static void StartNew()
Start up a new GameScript.
Definition game_core.cpp:70
static GameInfo * info
Current selected GameInfo.
Definition game.hpp:129
static bool HasGameLibrary(const ContentInfo &ci, bool md5sum)
Check whether we have an Game library with the exact characteristics as ci.
static class GameInfo * FindInfo(const std::string &name, int version, bool force_exact_match)
Finds the appropriate ScriptInfo for a given script name and version.
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 ResetConfig()
Reset all GameConfigs, and make them reload their GameInfo.
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:125
static std::unique_ptr< GameInstance > instance
Instance to the current active Game.
Definition game.hpp:126
static void Save()
Save data from a GameScript to a savegame.
static void Rescan()
Rescans all searchpaths for available Game scripts.
static void ResetInstance()
Reset the current active instance.
static class GameLibrary * FindLibrary(const std::string &library, int version)
Find a library.
static void GetConsoleLibraryList(std::back_insert_iterator< std::string > &output_iterator, bool newest_only)
Get the list of registered scripts to print on the console.
static const ScriptInfoList * GetUniqueInfoList()
Get the list of the latest version of all registered scripts.
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 the 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)
Get the list of registered scripts to print on the console.
static void Uninitialize(bool keepConfig)
Uninitialize the Game system.
Definition game_core.cpp:97
static std::unique_ptr< GameScannerInfo > scanner_info
Scanner for Game scripts.
Definition game.hpp:127
static const ScriptInfoList * GetInfoList()
Get the list of all registered scripts.
static void Initialize()
Initialize the Game system.
Definition game_core.cpp:55
static std::unique_ptr< GameScannerLibrary > scanner_library
Scanner for GS Libraries.
Definition game.hpp:128
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.
@ ForceCurrentGame
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.
Definition fileio_func.h:68
uint DoScan(Subdirectory sd)
Perform the scanning of a particular subdirectory.
Definition fileio.cpp:383
Definition of stuff that is very close to a company, like the company struct itself.
CompanyID _current_company
Company currently doing an action.
Functions related to companies.
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
Types for recording game performance data.
@ 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 GS scanner.
bool _networking
are we in networking mode?
Definition network.cpp:67
bool _network_server
network-server is active
Definition network.cpp:68
Basic functions/variables used all over the place.
A number of safeguards to prevent using unsafe methods.
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
Definition of base types and functions in a cross-platform compatible way.
Class to backup a specific variable and restore it upon destruction of this object to prevent stack v...
Class to backup a specific variable and restore it later.
void Restore()
Restore the variable.
Container for all important information about a piece of content.
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting).
Definition window.cpp:3230
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:3322
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:3340
Window functions not directly related to making/drawing windows.
@ 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: