00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "openttd.h"
00014 #include "landscape.h"
00015 #include "company_func.h"
00016 #include "variables.h"
00017 #include "thread/thread.h"
00018 #include "command_func.h"
00019 #include "genworld.h"
00020 #include "gfxinit.h"
00021 #include "window_func.h"
00022 #include "network/network.h"
00023 #include "heightmap.h"
00024 #include "viewport_func.h"
00025 #include "gfx_func.h"
00026 #include "date_func.h"
00027 #include "engine_func.h"
00028 #include "newgrf_storage.h"
00029 #include "water.h"
00030 #include "blitter/factory.hpp"
00031 #include "tilehighlight_func.h"
00032 #include "saveload/saveload.h"
00033 #include "void_map.h"
00034 #include "town.h"
00035 #include "newgrf.h"
00036
00037 #include "table/sprites.h"
00038
00039 void GenerateClearTile();
00040 void GenerateIndustries();
00041 void GenerateUnmovables();
00042 void GenerateTrees();
00043
00044 void StartupEconomy();
00045 void StartupCompanies();
00046 void StartupDisasters();
00047
00048 void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settings);
00049
00050
00051
00052
00053
00054 gw_info _gw;
00055
00057 ThreadMutex *_genworld_mapgen_mutex = ThreadMutex::New();
00059 ThreadMutex *_genworld_paint_mutex = ThreadMutex::New();
00060
00064 bool IsGenerateWorldThreaded()
00065 {
00066 return _gw.threaded && !_gw.quit_thread;
00067 }
00068
00073 static void CleanupGeneration()
00074 {
00075 _generating_world = false;
00076
00077 if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
00078
00079 if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows();
00080 _gw.active = false;
00081 _gw.proc = NULL;
00082 _gw.abortp = NULL;
00083 _gw.threaded = false;
00084
00085 DeleteWindowById(WC_GENERATE_PROGRESS_WINDOW, 0);
00086 MarkWholeScreenDirty();
00087 _genworld_mapgen_mutex->EndCritical();
00088 }
00089
00093 static void _GenerateWorld(void *arg)
00094 {
00095 try {
00096 _generating_world = true;
00097 _genworld_mapgen_mutex->BeginCritical();
00098 if (_network_dedicated) DEBUG(net, 0, "Generating map, please wait...");
00099
00100 if (_settings_game.game_creation.generation_seed == GENERATE_NEW_SEED) _settings_game.game_creation.generation_seed = _settings_newgame.game_creation.generation_seed = InteractiveRandom();
00101 _random.SetSeed(_settings_game.game_creation.generation_seed);
00102 SetGeneratingWorldProgress(GWP_MAP_INIT, 2);
00103 SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
00104
00105 IncreaseGeneratingWorldProgress(GWP_MAP_INIT);
00106
00107 StartupEconomy();
00108
00109
00110 if (_gw.mode == GW_EMPTY) {
00111 SetGeneratingWorldProgress(GWP_UNMOVABLE, 1);
00112
00113
00114 if (_settings_game.construction.freeform_edges) {
00115 for (uint row = 0; row < MapSizeY(); row++) MakeVoid(TileXY(0, row));
00116 for (uint col = 0; col < MapSizeX(); col++) MakeVoid(TileXY(col, 0));
00117 }
00118
00119
00120 if (_game_mode != GM_MENU) FlatEmptyWorld(_settings_game.game_creation.se_flat_world_height);
00121
00122 ConvertGroundTilesIntoWaterTiles();
00123 IncreaseGeneratingWorldProgress(GWP_UNMOVABLE);
00124 } else {
00125 GenerateLandscape(_gw.mode);
00126 GenerateClearTile();
00127
00128
00129 if (_game_mode != GM_EDITOR) {
00130 if (!GenerateTowns(_settings_game.economy.town_layout)) {
00131 HandleGeneratingWorldAbortion();
00132 return;
00133 }
00134 GenerateIndustries();
00135 GenerateUnmovables();
00136 GenerateTrees();
00137 }
00138 }
00139
00140 ClearStorageChanges(true);
00141
00142
00143 SetGeneratingWorldProgress(GWP_GAME_INIT, 3);
00144 StartupCompanies();
00145 IncreaseGeneratingWorldProgress(GWP_GAME_INIT);
00146 StartupEngines();
00147 IncreaseGeneratingWorldProgress(GWP_GAME_INIT);
00148 StartupDisasters();
00149 _generating_world = false;
00150
00151
00152 if (_gw.mode != GW_EMPTY) {
00153 uint i;
00154
00155 SetGeneratingWorldProgress(GWP_RUNTILELOOP, 0x500);
00156 for (i = 0; i < 0x500; i++) {
00157 RunTileLoop();
00158 IncreaseGeneratingWorldProgress(GWP_RUNTILELOOP);
00159 }
00160 }
00161
00162 ResetObjectToPlace();
00163 _local_company = _gw.lc;
00164
00165 SetGeneratingWorldProgress(GWP_GAME_START, 1);
00166
00167 if (_gw.proc != NULL) _gw.proc();
00168 IncreaseGeneratingWorldProgress(GWP_GAME_START);
00169
00170 CleanupGeneration();
00171
00172 ShowNewGRFError();
00173
00174 if (_network_dedicated) DEBUG(net, 0, "Map generated, starting game");
00175 DEBUG(desync, 1, "new_map: %i\n", _settings_game.game_creation.generation_seed);
00176
00177 if (_settings_client.gui.pause_on_newgame && _game_mode == GM_NORMAL) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE);
00178 if (_debug_desync_level > 0) {
00179 char name[MAX_PATH];
00180 snprintf(name, lengthof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date);
00181 SaveOrLoad(name, SL_SAVE, AUTOSAVE_DIR);
00182 }
00183 } catch (...) {
00184 _generating_world = false;
00185 _genworld_mapgen_mutex->EndCritical();
00186 throw;
00187 }
00188 }
00189
00194 void GenerateWorldSetCallback(gw_done_proc *proc)
00195 {
00196 _gw.proc = proc;
00197 }
00198
00203 void GenerateWorldSetAbortCallback(gw_abort_proc *proc)
00204 {
00205 _gw.abortp = proc;
00206 }
00207
00212 void WaitTillGeneratedWorld()
00213 {
00214 if (_gw.thread == NULL) return;
00215
00216 _genworld_mapgen_mutex->EndCritical();
00217 _genworld_paint_mutex->EndCritical();
00218 _gw.quit_thread = true;
00219 _gw.thread->Join();
00220 delete _gw.thread;
00221 _gw.thread = NULL;
00222 _gw.threaded = false;
00223 _genworld_mapgen_mutex->BeginCritical();
00224 _genworld_paint_mutex->BeginCritical();
00225 }
00226
00230 void AbortGeneratingWorld()
00231 {
00232 _gw.abort = true;
00233 }
00234
00238 bool IsGeneratingWorldAborted()
00239 {
00240 return _gw.abort;
00241 }
00242
00246 void HandleGeneratingWorldAbortion()
00247 {
00248
00249 _switch_mode = (_game_mode == GM_EDITOR) ? SM_EDITOR : SM_MENU;
00250
00251 if (_gw.abortp != NULL) _gw.abortp();
00252
00253 CleanupGeneration();
00254
00255 if (_gw.thread != NULL) _gw.thread->Exit();
00256
00257 extern void SwitchToMode(SwitchMode new_mode);
00258 SwitchToMode(_switch_mode);
00259 }
00260
00268 void GenerateWorld(GenerateWorldMode mode, uint size_x, uint size_y, bool reset_settings)
00269 {
00270 if (_gw.active) return;
00271 _gw.mode = mode;
00272 _gw.size_x = size_x;
00273 _gw.size_y = size_y;
00274 _gw.active = true;
00275 _gw.abort = false;
00276 _gw.abortp = NULL;
00277 _gw.lc = _local_company;
00278 _gw.quit_thread = false;
00279 _gw.threaded = true;
00280
00281
00282 SetLocalCompany(COMPANY_SPECTATOR);
00283
00284 _current_company = OWNER_NONE;
00285
00286
00287 SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1));
00288
00289 InitializeGame(_gw.size_x, _gw.size_y, false, reset_settings);
00290 PrepareGenerateWorldProgress();
00291
00292
00293 GfxLoadSprites();
00294 LoadStringWidthTable();
00295
00296
00297 ResetWindowSystem();
00298
00299
00300 SetupColoursAndInitialWindow();
00301 SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0);
00302
00303 if (_gw.thread != NULL) {
00304 _gw.thread->Join();
00305 delete _gw.thread;
00306 _gw.thread = NULL;
00307 }
00308
00309 if (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() == 0 ||
00310 !ThreadObject::New(&_GenerateWorld, NULL, &_gw.thread)) {
00311 DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode");
00312 _gw.threaded = false;
00313 _genworld_mapgen_mutex->EndCritical();
00314 _GenerateWorld(NULL);
00315 _genworld_mapgen_mutex->BeginCritical();
00316 return;
00317 }
00318
00319
00320 DeleteAllNonVitalWindows();
00321
00322 HideVitalWindows();
00323
00324
00325 ShowGenerateWorldProgress();
00326
00327
00328 if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) {
00329 ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2), true);
00330 }
00331 }