OpenTTD Source  1.11.0-beta2
genworld.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 "landscape.h"
12 #include "company_func.h"
13 #include "genworld.h"
14 #include "gfxinit.h"
15 #include "window_func.h"
16 #include "network/network.h"
17 #include "heightmap.h"
18 #include "viewport_func.h"
19 #include "date_func.h"
20 #include "engine_func.h"
21 #include "water.h"
22 #include "video/video_driver.hpp"
23 #include "tilehighlight_func.h"
24 #include "saveload/saveload.h"
25 #include "void_map.h"
26 #include "town.h"
27 #include "newgrf.h"
28 #include "core/random_func.hpp"
29 #include "core/backup_type.hpp"
30 #include "progress.h"
31 #include "error.h"
32 #include "game/game.hpp"
33 #include "game/game_instance.hpp"
34 #include "string_func.h"
35 #include "thread.h"
36 
37 #include "safeguards.h"
38 
39 
40 void GenerateClearTile();
41 void GenerateIndustries();
42 void GenerateObjects();
43 void GenerateTrees();
44 
45 void StartupEconomy();
46 void StartupCompanies();
47 void StartupDisasters();
48 
49 void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settings);
50 
58 
61 
67 {
68  return _gw.threaded && !_gw.quit_thread;
69 }
70 
75 static void CleanupGeneration()
76 {
77  _generating_world = false;
78 
79  SetMouseCursorBusy(false);
80  /* Show all vital windows again, because we have hidden them */
81  if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows();
82  SetModalProgress(false);
83  _gw.proc = nullptr;
84  _gw.abortp = nullptr;
85  _gw.threaded = false;
86 
90 }
91 
95 static void _GenerateWorld()
96 {
97  /* Make sure everything is done via OWNER_NONE. */
98  Backup<CompanyID> _cur_company(_current_company, OWNER_NONE, FILE_LINE);
99 
100  std::unique_lock<std::mutex> lock(_modal_progress_work_mutex, std::defer_lock);
101  try {
102  _generating_world = true;
103  lock.lock();
104  if (_network_dedicated) DEBUG(net, 1, "Generating map, please wait...");
105  /* Set the Random() seed to generation_seed so we produce the same map with the same seed */
109  SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
110 
112 
114  /* Must start economy early because of the costs. */
115  StartupEconomy();
116 
117  /* Don't generate landscape items when in the scenario editor. */
118  if (_gw.mode == GWM_EMPTY) {
120 
121  /* Make sure the tiles at the north border are void tiles if needed. */
123  for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, 0));
124  for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(0, y));
125  }
126 
127  /* Make the map the height of the setting */
129 
130  ConvertGroundTilesIntoWaterTiles();
132  } else {
134  GenerateClearTile();
135 
136  /* Only generate towns, tree and industries in newgame mode. */
137  if (_game_mode != GM_EDITOR) {
139  _cur_company.Restore();
142  if (_network_dedicated) {
143  /* Exit the game to prevent a return to main menu. */
144  DEBUG(net, 0, "Generating map failed, aborting");
145  _exit_game = true;
146  }
147  return;
148  }
150  GenerateObjects();
151  GenerateTrees();
152  }
153  }
154 
155  /* These are probably pointless when inside the scenario editor. */
159  StartupEngines();
161  StartupDisasters();
162  _generating_world = false;
163 
164  /* No need to run the tile loop in the scenario editor. */
165  if (_gw.mode != GWM_EMPTY) {
166  uint i;
167 
169  for (i = 0; i < 0x500; i++) {
170  RunTileLoop();
171  _tick_counter++;
173  }
174 
175  if (_game_mode != GM_EDITOR) {
176  Game::StartNew();
177 
178  if (Game::GetInstance() != nullptr) {
180  _generating_world = true;
181  for (i = 0; i < 2500; i++) {
182  Game::GameLoop();
184  if (Game::GetInstance()->IsSleeping()) break;
185  }
186  _generating_world = false;
187  }
188  }
189  }
190 
192 
194  _cur_company.Trash();
196 
198  /* Call any callback */
199  if (_gw.proc != nullptr) _gw.proc();
201 
203  lock.unlock();
204 
205  ShowNewGRFError();
206 
207  if (_network_dedicated) DEBUG(net, 1, "Map generated, starting game");
208  DEBUG(desync, 1, "new_map: %08x", _settings_game.game_creation.generation_seed);
209 
210  if (_debug_desync_level > 0) {
211  char name[MAX_PATH];
212  seprintf(name, lastof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date);
214  }
215  } catch (...) {
217  if (_cur_company.IsValid()) _cur_company.Restore();
218  _generating_world = false;
219  throw;
220  }
221 }
222 
229 {
230  _gw.proc = proc;
231 }
232 
239 {
240  _gw.abortp = proc;
241 }
242 
248 {
249  if (!_gw.thread.joinable()) return;
250 
253  _gw.quit_thread = true;
254  _gw.thread.join();
255  _gw.threaded = false;
258 }
259 
264 {
265  _gw.abort = true;
266 }
267 
273 {
274  return _gw.abort;
275 }
276 
281 {
282  /* Clean up - in SE create an empty map, otherwise, go to intro menu */
283  _switch_mode = (_game_mode == GM_EDITOR) ? SM_EDITOR : SM_MENU;
284 
285  if (_gw.abortp != nullptr) _gw.abortp();
286 
288 
289  if (_gw.thread.joinable() && _gw.thread.get_id() == std::this_thread::get_id()) throw OTTDThreadExitSignal();
290 
291  SwitchToMode(_switch_mode);
292 }
293 
301 void GenerateWorld(GenWorldMode mode, uint size_x, uint size_y, bool reset_settings)
302 {
303  if (HasModalProgress()) return;
304  _gw.mode = mode;
305  _gw.size_x = size_x;
306  _gw.size_y = size_y;
307  SetModalProgress(true);
308  _gw.abort = false;
309  _gw.abortp = nullptr;
311  _gw.quit_thread = false;
312  _gw.threaded = true;
313 
314  /* This disables some commands and stuff */
316 
317  InitializeGame(_gw.size_x, _gw.size_y, true, reset_settings);
319 
320  /* Load the right landscape stuff, and the NewGRFs! */
321  GfxLoadSprites();
323 
324  /* Re-init the windowing system */
326 
327  /* Create toolbars */
329  SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
330 
331  if (_gw.thread.joinable()) _gw.thread.join();
332 
333  if (!UseThreadedModelProgress() || !VideoDriver::GetInstance()->HasGUI() || !StartNewThread(&_gw.thread, "ottd:genworld", &_GenerateWorld)) {
334  DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode");
335  _gw.threaded = false;
337  _GenerateWorld();
339  return;
340  }
341 
343  /* Remove any open window */
345  /* Hide vital windows, because we don't allow to use them */
347 
348  /* Don't show the dialog if we don't have a thread */
350 
351  /* Centre the view on the map */
352  if (FindWindowById(WC_MAIN_WINDOW, 0) != nullptr) {
353  ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2), true);
354  }
355 }
GenWorldInfo::size_y
uint size_y
Y-size of the map.
Definition: genworld.h:60
game.hpp
LoadStringWidthTable
void LoadStringWidthTable(bool monospace)
Initialize _stringwidth_table cache.
Definition: gfx.cpp:1276
ShowFirstError
void ShowFirstError()
Show the first error of the queue.
Definition: error_gui.cpp:337
GWP_GAME_INIT
@ GWP_GAME_INIT
Initialize the game.
Definition: genworld.h:76
SetMouseCursorBusy
void SetMouseCursorBusy(bool busy)
Set or unset the ZZZ cursor.
Definition: gfx.cpp:1760
ShowGenerateWorldProgress
void ShowGenerateWorldProgress()
Show the window where a user can follow the process of the map generation.
Definition: genworld_gui.cpp:1303
HideVitalWindows
void HideVitalWindows()
Delete all always on-top windows to get an empty screen.
Definition: window.cpp:3449
GameCreationSettings::generation_seed
uint32 generation_seed
noise seed for world generation
Definition: settings_type.h:282
GenerateLandscape
void GenerateLandscape(byte mode)
Definition: landscape.cpp:1294
game_instance.hpp
GWP_RUNTILELOOP
@ GWP_RUNTILELOOP
Runs the tile loop 1280 times to make snow etc.
Definition: genworld.h:77
ScrollMainWindowToTile
bool ScrollMainWindowToTile(TileIndex tile, bool instant)
Scrolls the viewport of the main window to a given location.
Definition: viewport.cpp:2443
_GenerateWorld
static void _GenerateWorld()
The internal, real, generate function.
Definition: genworld.cpp:95
GenWorldInfo::abort
bool abort
Whether to abort the thread ASAP.
Definition: genworld.h:54
water.h
_modal_progress_paint_mutex
std::mutex _modal_progress_paint_mutex
Rights for the painting.
Definition: progress.cpp:23
GenWorldInfo::lc
CompanyID lc
The local_company before generating.
Definition: genworld.h:58
_gw
GenWorldInfo _gw
Please only use this variable in genworld.h and genworld.cpp and nowhere else.
Definition: genworld.cpp:57
AbortGeneratingWorld
void AbortGeneratingWorld()
Initializes the abortion process.
Definition: genworld.cpp:263
EconomySettings::town_layout
TownLayout town_layout
select town layout,
Definition: settings_type.h:489
Backup
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:21
GenWorldInfo::abortp
GWAbortProc * abortp
Proc that is called when aborting (can be nullptr)
Definition: genworld.h:62
lock
std::mutex lock
synchronization for playback status fields
Definition: win32_m.cpp:34
SaveOrLoad
SaveOrLoadResult SaveOrLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded)
Main Save or Load function where the high-level saveload functions are handled.
Definition: saveload.cpp:2764
SM_EDITOR
@ SM_EDITOR
Switch to scenario editor.
Definition: openttd.h:29
GenWorldInfo::mode
GenWorldMode mode
What mode are we making a world in.
Definition: genworld.h:57
GenerateWorldSetCallback
void GenerateWorldSetCallback(GWDoneProc *proc)
Set here the function, if any, that you want to be called when landscape generation is done.
Definition: genworld.cpp:228
FindWindowById
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
Definition: window.cpp:1133
void_map.h
SetLocalCompany
void SetLocalCompany(CompanyID new_company)
Sets the local company and updates the settings that are set on a per-company basis to reflect the co...
Definition: company_cmd.cpp:102
DFT_GAME_FILE
@ DFT_GAME_FILE
Save game or scenario file.
Definition: fileio_type.h:31
GenWorldInfo::threaded
bool threaded
Whether we run _GenerateWorld threaded.
Definition: genworld.h:56
saveload.h
_random
Randomizer _random
Random used in the game state calculations.
Definition: random_func.cpp:25
AUTOSAVE_DIR
@ AUTOSAVE_DIR
Subdirectory of save for autosaves.
Definition: fileio_type.h:111
GWAbortProc
void GWAbortProc()
Called when genworld is aborted.
Definition: genworld.h:50
DeleteWindowByClass
void DeleteWindowByClass(WindowClass cls)
Delete all windows of a given class.
Definition: window.cpp:1178
town.h
GenWorldInfo::thread
std::thread thread
The thread we are in (joinable if a thread was created)
Definition: genworld.h:63
StartupEngines
void StartupEngines()
Start/initialise all our engines.
Definition: engine.cpp:693
GENERATE_NEW_SEED
static const uint32 GENERATE_NEW_SEED
Create a new random seed.
Definition: genworld.h:24
genworld.h
IncreaseGeneratingWorldProgress
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
Definition: genworld_gui.cpp:1392
ShowNewGRFError
void ShowNewGRFError()
Show the first NewGRF error we can find.
Definition: newgrf_gui.cpp:44
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition: settings_type.h:550
MapSizeX
static uint MapSizeX()
Get the size of the map along the X.
Definition: map_func.h:72
GenWorldInfo::proc
GWDoneProc * proc
Proc that is called when done (can be nullptr)
Definition: genworld.h:61
WC_MODAL_PROGRESS
@ WC_MODAL_PROGRESS
Progress report of landscape generation; Window numbers:
Definition: window_type.h:456
heightmap.h
ShowVitalWindows
void ShowVitalWindows()
Show the vital in-game windows.
Definition: main_gui.cpp:547
_date
Date _date
Current date in days (day counter)
Definition: date.cpp:28
OTTDThreadExitSignal
Signal used for signalling we knowingly want to end the thread.
Definition: thread.h:18
SLO_SAVE
@ SLO_SAVE
File is being saved.
Definition: fileio_type.h:50
tilehighlight_func.h
IsGenerateWorldThreaded
bool IsGenerateWorldThreaded()
Tells if the world generation is done in a thread or not.
Definition: genworld.cpp:66
DEBUG
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:35
GenerateWorldSetAbortCallback
void GenerateWorldSetAbortCallback(GWAbortProc *proc)
Set here the function, if any, that you want to be called when landscape generation is aborted.
Definition: genworld.cpp:238
MakeVoid
static void MakeVoid(TileIndex t)
Make a nice void tile ;)
Definition: void_map.h:19
GenerateTrees
void GenerateTrees()
Place new trees.
Definition: tree_cmd.cpp:344
StartNewThread
bool StartNewThread(std::thread *thr, const char *name, TFn &&_Fx, TArgs &&... _Ax)
Start a new thread.
Definition: thread.h:48
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:80
PSM_ENTER_GAMELOOP
@ PSM_ENTER_GAMELOOP
Enter the gameloop, changes will be permanent.
Definition: newgrf_storage.h:20
GameSettings::economy
EconomySettings economy
settings to change the economy
Definition: settings_type.h:559
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
_tick_counter
uint16 _tick_counter
Ever incrementing (and sometimes wrapping) tick counter for setting off various events.
Definition: date.cpp:30
safeguards.h
GWP_GAME_START
@ GWP_GAME_START
Really prepare to start the game.
Definition: genworld.h:79
GWP_OBJECT
@ GWP_OBJECT
Generate objects (radio tower, light houses)
Definition: genworld.h:74
ConstructionSettings::freeform_edges
bool freeform_edges
allow terraforming the tiles at the map edges
Definition: settings_type.h:319
GWP_MAP_INIT
@ GWP_MAP_INIT
Initialize/allocate the map, start economy.
Definition: genworld.h:68
GameCreationSettings::se_flat_world_height
byte se_flat_world_height
land height a flat world gets in SE
Definition: settings_type.h:293
HT_NONE
@ HT_NONE
default
Definition: tilehighlight_type.h:20
gfxinit.h
error.h
MapSizeY
static uint MapSizeY()
Get the size of the map along the Y.
Definition: map_func.h:82
_network_dedicated
bool _network_dedicated
are we a dedicated server?
Definition: network.cpp:55
date_func.h
stdafx.h
landscape.h
VideoDriver::GetInstance
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
Definition: video_driver.hpp:168
viewport_func.h
FlatEmptyWorld
void FlatEmptyWorld(byte tile_height)
Make an empty world where all tiles are of height 'tile_height'.
Definition: heightmap.cpp:510
Backup::IsValid
bool IsValid() const
Checks whether the variable was already restored.
Definition: backup_type.hpp:63
GenWorldInfo
Properties of current genworld process.
Definition: genworld.h:53
_generating_world
bool _generating_world
Whether we are generating the map or not.
Definition: genworld.cpp:60
string_func.h
_switch_mode
SwitchMode _switch_mode
The next mainloop command.
Definition: gfx.cpp:46
_current_company
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
Game::GameLoop
static void GameLoop()
Called every game-tick to let Game do something.
Definition: game_core.cpp:31
Backup::Trash
void Trash()
Trash the backup.
Definition: backup_type.hpp:103
GenerateTowns
bool GenerateTowns(TownLayout layout)
This function will generate a certain amount of towns, with a certain layout It can be called from th...
Definition: town_cmd.cpp:2201
PrepareGenerateWorldProgress
void PrepareGenerateWorldProgress()
Initializes the progress counters to the starting point.
Definition: genworld_gui.cpp:1291
HandleGeneratingWorldAbortion
void HandleGeneratingWorldAbortion()
Really handle the abortion, i.e.
Definition: genworld.cpp:280
TileXY
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition: map_func.h:163
Backup::Restore
void Restore()
Restore the variable.
Definition: backup_type.hpp:112
UnshowCriticalError
void UnshowCriticalError()
Unshow the critical error.
Definition: error_gui.cpp:351
DeleteAllNonVitalWindows
void DeleteAllNonVitalWindows()
It is possible that a stickied window gets to a position where the 'close' button is outside the gami...
Definition: window.cpp:3396
video_driver.hpp
COMPANY_SPECTATOR
@ COMPANY_SPECTATOR
The client is spectating.
Definition: company_type.h:35
SetGeneratingWorldProgress
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
Set the total of a stage of the world generation.
Definition: genworld_gui.cpp:1378
GenWorldInfo::quit_thread
bool quit_thread
Do we want to quit the active thread.
Definition: genworld.h:55
OWNER_NONE
@ OWNER_NONE
The tile has no ownership.
Definition: company_type.h:25
GWM_EMPTY
@ GWM_EMPTY
Generate an empty map (sea-level)
Definition: genworld.h:29
newgrf.h
progress.h
seprintf
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Definition: string.cpp:442
WC_MAIN_WINDOW
@ WC_MAIN_WINDOW
Main window; Window numbers:
Definition: window_type.h:44
GfxLoadSprites
void GfxLoadSprites()
Initialise and load all the sprites.
Definition: gfxinit.cpp:342
company_func.h
SM_MENU
@ SM_MENU
Switch to game intro menu.
Definition: openttd.h:31
GenerateIndustries
void GenerateIndustries()
This function will create random industries during game creation.
Definition: industry_cmd.cpp:2303
WaitTillGeneratedWorld
void WaitTillGeneratedWorld()
This will wait for the thread to finish up his work.
Definition: genworld.cpp:247
network.h
window_func.h
UseThreadedModelProgress
static bool UseThreadedModelProgress()
Check if we can use a thread for modal progress.
Definition: progress.h:31
MarkWholeScreenDirty
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition: gfx.cpp:1619
StartupCompanies
void StartupCompanies()
Start the next competitor now.
Definition: company_cmd.cpp:588
random_func.hpp
GenWorldInfo::size_x
uint size_x
X-size of the map.
Definition: genworld.h:59
IsGeneratingWorldAborted
bool IsGeneratingWorldAborted()
Is the generation being aborted?
Definition: genworld.cpp:272
GenerateWorld
void GenerateWorld(GenWorldMode mode, uint size_x, uint size_y, bool reset_settings)
Generate a world.
Definition: genworld.cpp:301
PSM_LEAVE_GAMELOOP
@ PSM_LEAVE_GAMELOOP
Leave the gameloop, changes will be temporary.
Definition: newgrf_storage.h:21
BasePersistentStorageArray::SwitchMode
static void SwitchMode(PersistentStorageMode mode, bool ignore_prev_mode=false)
Clear temporary changes made since the last call to SwitchMode, and set whether subsequent changes sh...
Definition: newgrf_storage.cpp:55
CleanupGeneration
static void CleanupGeneration()
Clean up the 'mess' of generation.
Definition: genworld.cpp:75
ResetWindowSystem
void ResetWindowSystem()
Reset the windowing system, by means of shutting it down followed by re-initialization.
Definition: window.cpp:1938
GameSettings::construction
ConstructionSettings construction
construction of things in-game
Definition: settings_type.h:551
SetObjectToPlace
void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowClass window_class, WindowNumber window_num)
Change the cursor and mouse click/drag handling to a mode for performing special operations like tile...
Definition: viewport.cpp:3373
HasModalProgress
static bool HasModalProgress()
Check if we are currently in a modal progress state.
Definition: progress.h:21
Randomizer::SetSeed
void SetSeed(uint32 seed)
(Re)set the state of the random number generator.
Definition: random_func.cpp:55
GenWorldMode
GenWorldMode
Modes for GenerateWorld.
Definition: genworld.h:27
GWDoneProc
void GWDoneProc()
Procedure called when the genworld process finishes.
Definition: genworld.h:49
SetModalProgress
void SetModalProgress(bool state)
Set the modal progress state.
Definition: progress.cpp:30
Game::GetInstance
static class GameInstance * GetInstance()
Get the current active instance.
Definition: game.hpp:111
thread.h
lastof
#define lastof(x)
Get the last element of an fixed size array.
Definition: stdafx.h:383
ResetObjectToPlace
void ResetObjectToPlace()
Reset the cursor and mouse mode handling back to default (normal cursor, only clicking in windows).
Definition: viewport.cpp:3421
Game::StartNew
static void StartNew()
Start up a new GameScript.
Definition: game_core.cpp:72
_settings_newgame
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition: settings.cpp:81
SetupColoursAndInitialWindow
void SetupColoursAndInitialWindow()
Initialise the default colours (remaps and the likes), and load the main windows.
Definition: main_gui.cpp:519
engine_func.h
GWP_RUNSCRIPT
@ GWP_RUNSCRIPT
Runs the game script at most 2500 times, or when ever the script sleeps.
Definition: genworld.h:78
_modal_progress_work_mutex
std::mutex _modal_progress_work_mutex
Rights for the performing work.
Definition: progress.cpp:21
RunTileLoop
void RunTileLoop()
Gradually iterate over all tiles on the map, calling their TileLoopProcs once every 256 ticks.
Definition: landscape.cpp:801
backup_type.hpp