OpenTTD Source: src/game/game_core.cpp Source File

OpenTTD Source 15.0-RC2

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
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{
33 if (_networking && !_network_server) {
34 PerformanceMeasurer::SetInactive(PFE_GAMESCRIPT);
35 return;
36 }
37 if (Game::instance == nullptr) {
38 PerformanceMeasurer::SetInactive(PFE_GAMESCRIPT);
39 return;
40 }
41
42 PerformanceMeasurer framerate(PFE_GAMESCRIPT);
43
44 Game::frame_counter++;
45
46 Backup<CompanyID> cur_company(_current_company);
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
61 Game::frame_counter = 0;
62
63 if (Game::scanner_info == nullptr) {
64 TarScanner::DoScan(TarScanner::Mode::Game);
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
82 GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME);
83 GameInfo *info = config->GetInfo();
84 if (info == nullptr) return;
85
86 config->AnchorUnchangeableSettings();
87
88 Backup<CompanyID> cur_company(_current_company);
89 cur_company.Change(OWNER_DEITY);
90
91 Game::info = info;
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
99 InvalidateWindowClassesData(WC_SCRIPT_DEBUG, -1);
100}
101
102/* static */ void Game::Uninitialize(bool keepConfig)
103{
104 Backup<CompanyID> cur_company(_current_company);
105
106 Game::ResetInstance();
107
108 cur_company.Restore();
109
110 if (keepConfig) {
111 Rescan();
112 } else {
113 Game::scanner_info.reset();
114 Game::scanner_library.reset();
115
116 _settings_game.script_config.game.reset();
117 _settings_newgame.script_config.game.reset();
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 */
141 if (_networking && !_network_server) {
142 return;
143 }
144
145 /* Check if Game instance is alive */
146 if (Game::instance == nullptr) {
147 return;
148 }
149
150 /* Queue the event */
151 Backup<CompanyID> cur_company(_current_company, OWNER_DEITY);
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) {
166 Game::info = _settings_game.script_config.game->GetInfo();
167 }
168 }
169 if (_settings_newgame.script_config.game != nullptr && _settings_newgame.script_config.game->HasScript()) {
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{
179 TarScanner::DoScan(TarScanner::Mode::Game);
180
181 Game::scanner_info->RescanDir();
182 Game::scanner_library->RescanDir();
183 ResetConfig();
184
185 InvalidateWindowData(WC_SCRIPT_LIST, 0, 1);
186 SetWindowClassesDirty(WC_SCRIPT_DEBUG);
187 InvalidateWindowClassesData(WC_SCRIPT_SETTINGS);
188 InvalidateWindowClassesData(WC_GAME_OPTIONS);
189}
190
191
192/* static */ void Game::Save()
193{
194 if (Game::instance != nullptr && (!_networking || _network_server)) {
195 Backup<CompanyID> cur_company(_current_company, OWNER_DEITY);
196 Game::instance->Save();
197 cur_company.Restore();
198 } else {
199 GameInstance::SaveEmpty();
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
213/* static */ const ScriptInfoList *Game::GetInfoList()
214{
215 return Game::scanner_info->GetInfoList();
216}
217
218/* static */ const ScriptInfoList *Game::GetUniqueInfoList()
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
255/* static */ GameScannerInfo *Game::GetScannerInfo()
256{
257 return Game::scanner_info.get();
258}
259/* static */ GameScannerLibrary *Game::GetScannerLibrary()
260{
261 return Game::scanner_library.get();
262}
GameConfig
Definition game_config.hpp:15
GameConfig::GetConfig
static GameConfig * GetConfig(ScriptSettingSource source=SSS_DEFAULT)
Get the config of a company.
Definition game_config.cpp:18
GameInfo
All static information from an Game like name, version, etc.
Definition game_info.hpp:16
GameLibrary
All static information from an Game library like name, version, etc.
Definition game_info.hpp:52
GameScannerInfo
Definition game_scanner.hpp:15
GameScannerLibrary
Definition game_scanner.hpp:37
Game::StartNew
static void StartNew()
Start up a new GameScript.
Definition game_core.cpp:72
Game::info
static GameInfo * info
Current selected GameInfo.
Definition game.hpp:116
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:223
Game::HasGame
static bool HasGame(const ContentInfo &ci, bool md5sum)
Wrapper function for GameScanner::HasGame.
Definition game_core.cpp:245
Game::GetScannerLibrary
static GameScannerLibrary * GetScannerLibrary()
Gets the ScriptScanner instance that is used to find Game Libraries.
Definition game_core.cpp:259
Game::Unpause
static void Unpause()
Resume execution of the Game Script.
Definition game_core.cpp:126
Game::IsPaused
static bool IsPaused()
Checks if the Game Script is paused.
Definition game_core.cpp:131
Game::frame_counter
static uint frame_counter
Tick counter for the Game code.
Definition game.hpp:112
Game::instance
static std::unique_ptr< GameInstance > instance
Instance to the current active Game.
Definition game.hpp:113
Game::Save
static void Save()
Save data from a GameScript to a savegame.
Definition game_core.cpp:192
Game::ResetInstance
static void ResetInstance()
Reset the current active instance.
Definition game_core.cpp:233
Game::FindLibrary
static class GameLibrary * FindLibrary(const std::string &library, int version)
Wrapper function for GameScanner::FindLibrary.
Definition game_core.cpp:228
Game::GetUniqueInfoList
static const ScriptInfoList * GetUniqueInfoList()
Wrapper function for GameScanner::GetUniqueInfoList.
Definition game_core.cpp:218
Game::Pause
static void Pause()
Suspends the Game Script and then pause the execution of the script.
Definition game_core.cpp:121
Game::NewEvent
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition game_core.cpp:136
Game::GameLoop
static void GameLoop()
Called every game-tick to let Game do something.
Definition game_core.cpp:31
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:203
Game::GetConsoleLibraryList
static void GetConsoleLibraryList(std::back_insert_iterator< std::string > &output_iterator)
Wrapper function for GameScanner::GetConsoleLibraryList.
Definition game_core.cpp:208
Game::Uninitialize
static void Uninitialize(bool keepConfig)
Uninitialize the Game system.
Definition game_core.cpp:102
Game::scanner_info
static std::unique_ptr< GameScannerInfo > scanner_info
Scanner for Game scripts.
Definition game.hpp:114
Game::GetInfoList
static const ScriptInfoList * GetInfoList()
Wrapper function for GameScanner::GetInfoList.
Definition game_core.cpp:213
Game::Initialize
static void Initialize()
Initialize the Game system.
Definition game_core.cpp:57
Game::scanner_library
static std::unique_ptr< GameScannerLibrary > scanner_library
Scanner for GS Libraries.
Definition game.hpp:115
Game::GetScannerInfo
static GameScannerInfo * GetScannerInfo()
Gets the ScriptScanner instance that is used to find Game scripts.
Definition game_core.cpp:255
PerformanceMeasurer
RAII class for measuring simple elements of performance.
Definition framerate_type.h:91
PerformanceMeasurer::SetInactive
static void SetInactive(PerformanceElement elem)
Mark a performance element as not currently in use.
Definition framerate_gui.cpp:291
ScriptConfig::SSS_FORCE_GAME
@ SSS_FORCE_GAME
Get the Script config from the current game.
Definition script_config.hpp:100
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:74
ScriptInstance::SaveEmpty
static void SaveEmpty()
Don't save any data in the savegame.
Definition script_instance.cpp:507
TarScanner::Mode::Game
@ Game
Scan for game scripts.
TarScanner::DoScan
uint DoScan(Subdirectory sd)
Perform the scanning of a particular subdirectory.
Definition fileio.cpp:377
_current_company
CompanyID _current_company
Company currently doing an action.
Definition company_cmd.cpp:56
OWNER_DEITY
static constexpr Owner OWNER_DEITY
The object is owned by a superuser / goal script.
Definition company_type.h:28
Debug
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
PFE_GAMESCRIPT
@ PFE_GAMESCRIPT
Game script execution.
Definition framerate_type.h:61
game.hpp
Base functions for all Games.
game_config.hpp
GameConfig stores the configuration settings of every Game.
game_info.hpp
GameInfo keeps track of all information of an Game, like Author, Description, ...
game_instance.hpp
The GameInstance tracks games.
game_scanner.hpp
declarations of the class for Game scanner
_networking
bool _networking
are we in networking mode?
Definition network.cpp:66
_network_server
bool _network_server
network-server is active
Definition network.cpp:67
ScriptInfoList
std::map< std::string, class ScriptInfo *, CaseInsensitiveComparator > ScriptInfoList
Type for the list of scripts.
Definition script_scanner.hpp:16
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
_settings_newgame
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:62
Backup
Class to backup a specific variable and restore it later.
Definition backup_type.hpp:21
Backup::Change
void Change(const U &new_value)
Change the value of the variable.
Definition backup_type.hpp:82
Backup::Restore
void Restore()
Restore the variable.
Definition backup_type.hpp:110
ContentInfo
Container for all important information about a piece of content.
Definition tcp_content_type.h:56
GameSettings::script_config
ScriptConfigSettings script_config
AI and Gamescript configuration.
Definition settings_type.h:638
ScriptConfigSettings::game
std::unique_ptr< class GameConfig > game
settings for gamescript
Definition settings_type.h:622
SetWindowClassesDirty
void SetWindowClassesDirty(WindowClass cls)
Mark all windows of a particular class as dirty (in need of repainting)
Definition window.cpp:3202
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:3294
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:3311
WC_SCRIPT_SETTINGS
@ WC_SCRIPT_SETTINGS
Script settings; Window numbers:
Definition window_type.h:180
WC_SCRIPT_LIST
@ WC_SCRIPT_LIST
Scripts list; Window numbers:
Definition window_type.h:289
WC_GAME_OPTIONS
@ WC_GAME_OPTIONS
Game options window; Window numbers:
Definition window_type.h:635
WC_SCRIPT_DEBUG
@ WC_SCRIPT_DEBUG
Script debug window; Window numbers:
Definition window_type.h:685