OpenTTD
genworld.cpp
Go to the documentation of this file.
1 /* $Id: genworld.cpp 27670 2016-10-30 17:29:33Z frosch $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #include "stdafx.h"
13 #include "landscape.h"
14 #include "company_func.h"
15 #include "genworld.h"
16 #include "gfxinit.h"
17 #include "window_func.h"
18 #include "network/network.h"
19 #include "heightmap.h"
20 #include "viewport_func.h"
21 #include "date_func.h"
22 #include "engine_func.h"
23 #include "water.h"
24 #include "video/video_driver.hpp"
25 #include "tilehighlight_func.h"
26 #include "saveload/saveload.h"
27 #include "void_map.h"
28 #include "town.h"
29 #include "newgrf.h"
30 #include "core/random_func.hpp"
31 #include "core/backup_type.hpp"
32 #include "progress.h"
33 #include "error.h"
34 #include "game/game.hpp"
35 #include "game/game_instance.hpp"
36 #include "string_func.h"
37 
38 #include "safeguards.h"
39 
40 
41 void GenerateClearTile();
42 void GenerateIndustries();
43 void GenerateObjects();
44 void GenerateTrees();
45 
46 void StartupEconomy();
47 void StartupCompanies();
48 void StartupDisasters();
49 
50 void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settings);
51 
59 
62 
68 {
69  return _gw.threaded && !_gw.quit_thread;
70 }
71 
76 static void CleanupGeneration()
77 {
78  _generating_world = false;
79 
80  SetMouseCursorBusy(false);
81  /* Show all vital windows again, because we have hidden them */
82  if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows();
83  SetModalProgress(false);
84  _gw.proc = NULL;
85  _gw.abortp = NULL;
86  _gw.threaded = false;
87 
91 }
92 
96 static void _GenerateWorld(void *)
97 {
98  /* Make sure everything is done via OWNER_NONE. */
99  Backup<CompanyByte> _cur_company(_current_company, OWNER_NONE, FILE_LINE);
100 
101  try {
102  _generating_world = true;
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 row = 0; row < MapSizeY(); row++) MakeVoid(TileXY(0, row));
124  for (uint col = 0; col < MapSizeX(); col++) MakeVoid(TileXY(col, 0));
125  }
126 
127  /* Make the map the height of the setting */
129 
130  ConvertGroundTilesIntoWaterTiles();
132  } else {
133  GenerateLandscape(_gw.mode);
134  GenerateClearTile();
135 
136  /* only generate towns, tree and industries in newgame mode. */
137  if (_game_mode != GM_EDITOR) {
139  _cur_company.Restore();
141  return;
142  }
144  GenerateObjects();
145  GenerateTrees();
146  }
147  }
148 
149  /* These are probably pointless when inside the scenario editor. */
153  StartupEngines();
155  StartupDisasters();
156  _generating_world = false;
157 
158  /* No need to run the tile loop in the scenario editor. */
159  if (_gw.mode != GWM_EMPTY) {
160  uint i;
161 
163  for (i = 0; i < 0x500; i++) {
164  RunTileLoop();
165  _tick_counter++;
167  }
168 
169  if (_game_mode != GM_EDITOR) {
170  Game::StartNew();
171 
172  if (Game::GetInstance() != NULL) {
174  _generating_world = true;
175  for (i = 0; i < 2500; i++) {
176  Game::GameLoop();
178  if (Game::GetInstance()->IsSleeping()) break;
179  }
180  _generating_world = false;
181  }
182  }
183  }
184 
186 
188  _cur_company.Trash();
190 
192  /* Call any callback */
193  if (_gw.proc != NULL) _gw.proc();
195 
198 
199  ShowNewGRFError();
200 
201  if (_network_dedicated) DEBUG(net, 1, "Map generated, starting game");
202  DEBUG(desync, 1, "new_map: %08x", _settings_game.game_creation.generation_seed);
203 
204  if (_debug_desync_level > 0) {
205  char name[MAX_PATH];
206  seprintf(name, lastof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date);
208  }
209  } catch (...) {
211  if (_cur_company.IsValid()) _cur_company.Restore();
212  _generating_world = false;
214  throw;
215  }
216 }
217 
224 {
225  _gw.proc = proc;
226 }
227 
234 {
235  _gw.abortp = proc;
236 }
237 
243 {
244  if (_gw.thread == NULL) return;
245 
248  _gw.quit_thread = true;
249  _gw.thread->Join();
250  delete _gw.thread;
251  _gw.thread = NULL;
252  _gw.threaded = false;
255 }
256 
261 {
262  _gw.abort = true;
263 }
264 
270 {
271  return _gw.abort;
272 }
273 
278 {
279  /* Clean up - in SE create an empty map, otherwise, go to intro menu */
280  _switch_mode = (_game_mode == GM_EDITOR) ? SM_EDITOR : SM_MENU;
281 
282  if (_gw.abortp != NULL) _gw.abortp();
283 
285 
286  if (_gw.thread != NULL) _gw.thread->Exit();
287 
288  SwitchToMode(_switch_mode);
289 }
290 
298 void GenerateWorld(GenWorldMode mode, uint size_x, uint size_y, bool reset_settings)
299 {
300  if (HasModalProgress()) return;
301  _gw.mode = mode;
302  _gw.size_x = size_x;
303  _gw.size_y = size_y;
304  SetModalProgress(true);
305  _gw.abort = false;
306  _gw.abortp = NULL;
307  _gw.lc = _local_company;
308  _gw.quit_thread = false;
309  _gw.threaded = true;
310 
311  /* This disables some commands and stuff */
313 
314  InitializeGame(_gw.size_x, _gw.size_y, true, reset_settings);
316 
317  /* Load the right landscape stuff, and the NewGRFs! */
318  GfxLoadSprites();
320 
321  /* Re-init the windowing system */
323 
324  /* Create toolbars */
326  SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
327 
328  if (_gw.thread != NULL) {
329  _gw.thread->Join();
330  delete _gw.thread;
331  _gw.thread = NULL;
332  }
333 
334  if (!VideoDriver::GetInstance()->HasGUI() || !ThreadObject::New(&_GenerateWorld, NULL, &_gw.thread, "ottd:genworld")) {
335  DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode");
336  _gw.threaded = false;
338  _GenerateWorld(NULL);
340  return;
341  }
342 
344  /* Remove any open window */
346  /* Hide vital windows, because we don't allow to use them */
348 
349  /* Don't show the dialog if we don't have a thread */
351 
352  /* Centre the view on the map */
353  if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) {
354  ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2), true);
355  }
356 }