genworld.cpp
Go to the documentation of this file.00001
00002
00005 #include "stdafx.h"
00006 #include "openttd.h"
00007 #include "landscape.h"
00008 #include "player_func.h"
00009 #include "variables.h"
00010 #include "thread.h"
00011 #include "command_func.h"
00012 #include "genworld.h"
00013 #include "gfxinit.h"
00014 #include "window_func.h"
00015 #include "network/network.h"
00016 #include "debug.h"
00017 #include "settings_func.h"
00018 #include "heightmap.h"
00019 #include "viewport_func.h"
00020 #include "gfx_func.h"
00021 #include "map_func.h"
00022 #include "date_func.h"
00023 #include "core/random_func.hpp"
00024 #include "engine.h"
00025 #include "settings_type.h"
00026 #include "newgrf_storage.h"
00027 #include "water.h"
00028
00029 #include "table/sprites.h"
00030
00031 void GenerateClearTile();
00032 void GenerateIndustries();
00033 void GenerateUnmovables();
00034 bool GenerateTowns();
00035 void GenerateTrees();
00036
00037 void StartupEconomy();
00038 void StartupPlayers();
00039 void StartupDisasters();
00040
00041 void InitializeGame(int mode, uint size_x, uint size_y);
00042
00043
00044
00045
00046
00047 gw_info _gw;
00048
00056 void SetGeneratingWorldPaintStatus(bool status)
00057 {
00058 _gw.wait_for_draw = status;
00059 }
00060
00067 bool IsGeneratingWorldReadyForPaint()
00068 {
00069
00070
00071 if (!_gw.active || _gw.quit_thread || !_gw.threaded) return false;
00072
00073 return _gw.wait_for_draw;
00074 }
00075
00079 bool IsGenerateWorldThreaded()
00080 {
00081 return _gw.threaded && !_gw.quit_thread;
00082 }
00083
00087 static void *_GenerateWorld(void *arg)
00088 {
00089 _generating_world = true;
00090 if (_network_dedicated) DEBUG(net, 0, "Generating map, please wait...");
00091
00092 if (_patches.generation_seed == GENERATE_NEW_SEED) _patches.generation_seed = _patches_newgame.generation_seed = InteractiveRandom();
00093 _random.SetSeed(_patches.generation_seed);
00094 SetGeneratingWorldProgress(GWP_MAP_INIT, 2);
00095 SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, VHM_NONE, WC_MAIN_WINDOW, 0);
00096
00097 IncreaseGeneratingWorldProgress(GWP_MAP_INIT);
00098
00099 StartupEconomy();
00100
00101
00102 if (_gw.mode == GW_EMPTY) {
00103 SetGeneratingWorldProgress(GWP_UNMOVABLE, 1);
00104
00105
00106 if (_game_mode != GM_MENU) FlatEmptyWorld(_patches.se_flat_world_height);
00107
00108 ConvertGroundTilesIntoWaterTiles();
00109 IncreaseGeneratingWorldProgress(GWP_UNMOVABLE);
00110 } else {
00111 GenerateLandscape(_gw.mode);
00112 GenerateClearTile();
00113
00114
00115 if (_game_mode != GM_EDITOR) {
00116 GenerateTowns();
00117 GenerateIndustries();
00118 GenerateUnmovables();
00119 GenerateTrees();
00120 }
00121 }
00122
00123 ClearStorageChanges(true);
00124
00125
00126 SetGeneratingWorldProgress(GWP_GAME_INIT, 3);
00127 StartupPlayers();
00128 IncreaseGeneratingWorldProgress(GWP_GAME_INIT);
00129 StartupEngines();
00130 IncreaseGeneratingWorldProgress(GWP_GAME_INIT);
00131 StartupDisasters();
00132 _generating_world = false;
00133
00134
00135 if (_gw.mode != GW_EMPTY) {
00136 uint i;
00137
00138 SetGeneratingWorldProgress(GWP_RUNTILELOOP, 0x500);
00139 for (i = 0; i < 0x500; i++) {
00140 RunTileLoop();
00141 IncreaseGeneratingWorldProgress(GWP_RUNTILELOOP);
00142 }
00143 }
00144
00145 ResetObjectToPlace();
00146 SetLocalPlayer(_gw.lp);
00147
00148 SetGeneratingWorldProgress(GWP_GAME_START, 1);
00149
00150 if (_gw.proc != NULL) _gw.proc();
00151 IncreaseGeneratingWorldProgress(GWP_GAME_START);
00152
00153 if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
00154
00155 if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows();
00156 _gw.active = false;
00157 _gw.thread = NULL;
00158 _gw.proc = NULL;
00159 _gw.threaded = false;
00160
00161 DeleteWindowById(WC_GENERATE_PROGRESS_WINDOW, 0);
00162 MarkWholeScreenDirty();
00163
00164 if (_network_dedicated) DEBUG(net, 0, "Map generated, starting game");
00165
00166 if (_patches.pause_on_newgame && _game_mode == GM_NORMAL) DoCommandP(0, 1, 0, NULL, CMD_PAUSE);
00167
00168 return NULL;
00169 }
00170
00175 void GenerateWorldSetCallback(gw_done_proc *proc)
00176 {
00177 _gw.proc = proc;
00178 }
00179
00184 void GenerateWorldSetAbortCallback(gw_abort_proc *proc)
00185 {
00186 _gw.abortp = proc;
00187 }
00188
00193 void WaitTillGeneratedWorld()
00194 {
00195 if (_gw.thread == NULL) return;
00196 _gw.quit_thread = true;
00197 OTTDJoinThread((OTTDThread*)_gw.thread);
00198 _gw.thread = NULL;
00199 _gw.threaded = false;
00200 }
00201
00205 void AbortGeneratingWorld()
00206 {
00207 _gw.abort = true;
00208 }
00209
00213 bool IsGeneratingWorldAborted()
00214 {
00215 return _gw.abort;
00216 }
00217
00221 void HandleGeneratingWorldAbortion()
00222 {
00223
00224 _switch_mode = (_game_mode == GM_EDITOR) ? SM_EDITOR : SM_MENU;
00225
00226 if (_gw.abortp != NULL) _gw.abortp();
00227
00228 if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
00229
00230 if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows();
00231 _gw.active = false;
00232 _gw.thread = NULL;
00233 _gw.proc = NULL;
00234 _gw.abortp = NULL;
00235 _gw.threaded = false;
00236
00237 DeleteWindowById(WC_GENERATE_PROGRESS_WINDOW, 0);
00238 MarkWholeScreenDirty();
00239
00240 OTTDExitThread();
00241 }
00242
00249 void GenerateWorld(int mode, uint size_x, uint size_y)
00250 {
00251 if (_gw.active) return;
00252 _gw.mode = mode;
00253 _gw.size_x = size_x;
00254 _gw.size_y = size_y;
00255 _gw.active = true;
00256 _gw.abort = false;
00257 _gw.abortp = NULL;
00258 _gw.lp = _local_player;
00259 _gw.wait_for_draw = false;
00260 _gw.quit_thread = false;
00261 _gw.threaded = true;
00262
00263
00264 SetLocalPlayer(PLAYER_SPECTATOR);
00265
00266 _current_player = OWNER_NONE;
00267
00268
00269 SetDate(ConvertYMDToDate(_patches.starting_year, 0, 1));
00270
00271
00272 GfxLoadSprites();
00273 LoadStringWidthTable();
00274
00275 InitializeGame(IG_NONE, _gw.size_x, _gw.size_y);
00276 PrepareGenerateWorldProgress();
00277
00278
00279 ResetWindowSystem();
00280
00281
00282 SetupColorsAndInitialWindow();
00283
00284 if (_network_dedicated ||
00285 (_gw.thread = OTTDCreateThread(&_GenerateWorld, NULL)) == NULL) {
00286 DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode");
00287 _gw.threaded = false;
00288 _GenerateWorld(NULL);
00289 return;
00290 }
00291
00292
00293 DeleteAllNonVitalWindows();
00294
00295 HideVitalWindows();
00296
00297
00298 ShowGenerateWorldProgress();
00299
00300
00301 if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) {
00302 ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2), true);
00303 }
00304 }