genworld_gui.cpp

Go to the documentation of this file.
00001 /* $Id$ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * 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.
00006  * 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.
00007  * 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/>.
00008  */
00009 
00012 #include "stdafx.h"
00013 #include "heightmap.h"
00014 #include "debug.h"
00015 #include "genworld.h"
00016 #include "network/network.h"
00017 #include "strings_func.h"
00018 #include "window_func.h"
00019 #include "date_func.h"
00020 #include "sound_func.h"
00021 #include "fios.h"
00022 #include "string_func.h"
00023 #include "widgets/dropdown_type.h"
00024 #include "widgets/dropdown_func.h"
00025 #include "querystring_gui.h"
00026 #include "town.h"
00027 #include "settings_func.h"
00028 #include "core/geometry_func.hpp"
00029 #include "core/random_func.hpp"
00030 #include "progress.h"
00031 #include "error.h"
00032 
00033 #include "widgets/genworld_widget.h"
00034 
00035 
00036 extern void MakeNewgameSettingsLive();
00037 
00039 enum GenenerateLandscapeWindowMode {
00040   GLWM_GENERATE,  
00041   GLWM_HEIGHTMAP, 
00042   GLWM_SCENARIO,  
00043 };
00044 
00049 void SetNewLandscapeType(byte landscape)
00050 {
00051   _settings_newgame.game_creation.landscape = landscape;
00052   InvalidateWindowClassesData(WC_SELECT_GAME);
00053   InvalidateWindowClassesData(WC_GENERATE_LANDSCAPE);
00054 }
00055 
00057 static const NWidgetPart _nested_generate_landscape_widgets[] = {
00058   NWidget(NWID_HORIZONTAL),
00059     NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
00060     NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_MAPGEN_WORLD_GENERATION_CAPTION, STR_NULL),
00061   EndContainer(),
00062   NWidget(WWT_PANEL, COLOUR_BROWN),
00063     NWidget(NWID_SPACER), SetMinimalSize(0, 10),
00064     /* Landscape selection. */
00065     NWidget(NWID_HORIZONTAL), SetPIP(10, 0, 10),
00066       NWidget(NWID_SPACER), SetFill(1, 0),
00067       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
00068       NWidget(NWID_SPACER), SetFill(1, 0),
00069       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
00070       NWidget(NWID_SPACER), SetFill(1, 0),
00071       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
00072       NWidget(NWID_SPACER), SetFill(1, 0),
00073       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
00074       NWidget(NWID_SPACER), SetFill(1, 0),
00075     EndContainer(),
00076     NWidget(NWID_SPACER), SetMinimalSize(0, 11),
00077     NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10),
00078       NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
00079         /* Left column with labels. */
00080         NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
00081           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
00082           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_LAND_GENERATOR, STR_NULL), SetFill(1, 1),
00083           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1),
00084           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TERRAIN_TYPE, STR_NULL), SetFill(1, 1),
00085           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_RANDOM_SEED, STR_NULL), SetFill(1, 1),
00086           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_SEA_LAKES, STR_NULL), SetFill(1, 1),
00087           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TREE_PLACER, STR_NULL), SetFill(1, 1),
00088           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_VARIETY, STR_NULL), SetFill(1, 1),
00089           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BORDER_TYPE, STR_NULL), SetFill(1, 1),
00090         EndContainer(),
00091         /* Widgets at the right of the labels. */
00092         NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
00093           /* Mapsize X * Y. */
00094           NWidget(NWID_HORIZONTAL), SetPIP(0, 4, 0),
00095             NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0),
00096             NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(1, 1),
00097             NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0),
00098           EndContainer(),
00099           NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_LANDSCAPE_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00100           NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00101           NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TERRAIN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00102           NWidget(WWT_EDITBOX, COLOUR_ORANGE, WID_GL_RANDOM_EDITBOX), SetDataTip(STR_MAPGEN_RANDOM_SEED_OSKTITLE, STR_MAPGEN_RANDOM_SEED_HELP), SetFill(1, 1),
00103           NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_WATER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00104           NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TREE_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00105           NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_VARIETY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00106           NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_BORDERS_RANDOM), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00107         EndContainer(),
00108       EndContainer(),
00109       NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
00110         NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
00111           NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
00112             NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetFill(1, 1),
00113             NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SNOW_LINE_HEIGHT, STR_NULL), SetFill(1, 1),
00114             NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1),
00115             NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SMOOTHNESS, STR_NULL), SetFill(1, 1),
00116           EndContainer(),
00117           NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
00118             /* Starting date. */
00119             NWidget(NWID_HORIZONTAL),
00120               NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD), SetFill(0, 1),
00121               NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL), SetFill(1, 0),
00122               NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1),
00123             EndContainer(),
00124             /* Snow line. */
00125             NWidget(NWID_HORIZONTAL),
00126               NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_LEVEL_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_SNOW_LINE_DOWN), SetFill(0, 1),
00127               NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_SNOW_LEVEL_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0),
00128               NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_LEVEL_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_SNOW_LINE_UP), SetFill(0, 1),
00129             EndContainer(),
00130             NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00131             NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_SMOOTHNESS_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00132           EndContainer(),
00133         EndContainer(),
00134         NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_RANDOM_BUTTON), SetDataTip(STR_MAPGEN_RANDOM, STR_MAPGEN_RANDOM_HELP), SetFill(1, 0),
00135         NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
00136           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1),
00137           NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00138         EndContainer(),
00139         NWidget(NWID_SPACER), SetFill(1, 1),
00140         NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 30), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetFill(1, 0),
00141       EndContainer(),
00142     EndContainer(),
00143     NWidget(NWID_SPACER), SetMinimalSize(0, 4),
00144     /* Map borders buttons for each edge. */
00145     NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 0, 10),
00146       NWidget(NWID_HORIZONTAL), SetPIP(0, 0, 3),
00147         NWidget(NWID_SPACER), SetFill(1, 1),
00148         NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NORTHWEST, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(0, 1),
00149       EndContainer(),
00150       NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_NW), SetDataTip(STR_JUST_STRING, STR_MAPGEN_NORTHWEST), SetFill(1, 1),
00151       NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_NE), SetDataTip(STR_JUST_STRING, STR_MAPGEN_NORTHEAST), SetFill(1, 1),
00152       NWidget(NWID_HORIZONTAL), SetPIP(3, 0, 0),
00153         NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NORTHEAST, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(0, 1),
00154         NWidget(NWID_SPACER), SetFill(1, 1),
00155       EndContainer(),
00156     EndContainer(),
00157     NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 0, 10),
00158       NWidget(NWID_HORIZONTAL), SetPIP(0, 0, 3),
00159         NWidget(NWID_SPACER), SetFill(1, 1),
00160         NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SOUTHWEST, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(0, 1),
00161       EndContainer(),
00162       NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_SW), SetDataTip(STR_JUST_STRING, STR_MAPGEN_SOUTHWEST), SetFill(1, 1),
00163       NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_SE), SetDataTip(STR_JUST_STRING, STR_MAPGEN_SOUTHEAST), SetFill(1, 1),
00164       NWidget(NWID_HORIZONTAL), SetPIP(3, 0, 0),
00165         NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SOUTHEAST, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(0, 1),
00166         NWidget(NWID_SPACER), SetFill(1, 1),
00167       EndContainer(),
00168     EndContainer(),
00169     NWidget(NWID_SPACER), SetMinimalSize(0, 9), SetFill(1, 1),
00170   EndContainer(),
00171 };
00172 
00174 static const NWidgetPart _nested_heightmap_load_widgets[] = {
00175   /* Window header. */
00176   NWidget(NWID_HORIZONTAL),
00177     NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
00178     NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_MAPGEN_WORLD_GENERATION_CAPTION, STR_NULL),
00179   EndContainer(),
00180   NWidget(WWT_PANEL, COLOUR_BROWN),
00181     NWidget(NWID_SPACER), SetMinimalSize(0, 10),
00182     /* Landscape selection. */
00183     NWidget(NWID_HORIZONTAL), SetPIP(10, 0, 10),
00184       NWidget(NWID_SPACER), SetFill(1, 0),
00185       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
00186       NWidget(NWID_SPACER), SetFill(1, 0),
00187       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
00188       NWidget(NWID_SPACER), SetFill(1, 0),
00189       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
00190       NWidget(NWID_SPACER), SetFill(1, 0),
00191       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
00192       NWidget(NWID_SPACER), SetFill(1, 0),
00193     EndContainer(),
00194     NWidget(NWID_SPACER), SetMinimalSize(0, 11), SetFill(0, 1),
00195     NWidget(NWID_HORIZONTAL), SetPIP(10, 3, 10),
00196       /* Labels at the left side. */
00197       NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
00198         NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_NAME, STR_NULL), SetFill(1, 1),
00199         NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_NULL), SetFill(1, 1),
00200         NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1),
00201         NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1),
00202         NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_RANDOM_SEED, STR_NULL), SetFill(1, 1),
00203         NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1),
00204         NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TREE_PLACER, STR_NULL), SetFill(1, 1),
00205         NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_ROTATION, STR_NULL), SetFill(1, 1),
00206       EndContainer(),
00207       /* Widgets at the right of the labels. */
00208       NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
00209         NWidget(WWT_EMPTY, COLOUR_ORANGE, WID_GL_HEIGHTMAP_NAME_TEXT), SetFill(1, 0),
00210         NWidget(NWID_HORIZONTAL), SetPIP(0, 5, 0),
00211           NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
00212             /* Mapsize X * Y. */
00213             NWidget(NWID_HORIZONTAL), SetPIP(0, 4, 0),
00214               NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetFill(1, 0),
00215               NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(1, 1),
00216               NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetFill(1, 0),
00217             EndContainer(),
00218             NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00219             NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00220             NWidget(WWT_EDITBOX, COLOUR_ORANGE, WID_GL_RANDOM_EDITBOX), SetDataTip(STR_MAPGEN_RANDOM_SEED_OSKTITLE, STR_MAPGEN_RANDOM_SEED_HELP), SetFill(1, 1),
00221             NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00222             NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TREE_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00223             NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_ROTATION_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
00224           EndContainer(),
00225           NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
00226             NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
00227               NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
00228                 NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_SIZE_LABEL, STR_NULL), SetFill(1, 1),
00229                 NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetFill(1, 1),
00230                 NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SNOW_LINE_HEIGHT, STR_NULL), SetFill(1, 1),
00231               EndContainer(),
00232               NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
00233                 NWidget(WWT_TEXT, COLOUR_ORANGE, WID_GL_HEIGHTMAP_SIZE_TEXT), SetDataTip(STR_MAPGEN_HEIGHTMAP_SIZE, STR_NULL), SetFill(1, 0),
00234                 NWidget(NWID_HORIZONTAL),
00235                   NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD), SetFill(0, 1),
00236                   NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL), SetFill(1, 0),
00237                   NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1),
00238                 EndContainer(),
00239                 NWidget(NWID_HORIZONTAL),
00240                   NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_LEVEL_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_SNOW_LINE_DOWN), SetFill(0, 1),
00241                   NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_SNOW_LEVEL_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0),
00242                   NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_LEVEL_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_SNOW_LINE_UP), SetFill(0, 1),
00243                 EndContainer(),
00244               EndContainer(),
00245             EndContainer(),
00246             NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_RANDOM_BUTTON), SetDataTip(STR_MAPGEN_RANDOM, STR_MAPGEN_RANDOM_HELP), SetFill(1, 0),
00247             NWidget(NWID_SPACER), SetFill(1, 1),
00248             NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 30), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetFill(1, 0),
00249           EndContainer(),
00250         EndContainer(),
00251       EndContainer(),
00252     EndContainer(),
00253     NWidget(NWID_SPACER), SetMinimalSize(0, 9), SetFill(1, 1),
00254   EndContainer(),
00255 };
00256 
00257 static void StartGeneratingLandscape(GenenerateLandscapeWindowMode mode)
00258 {
00259   DeleteAllNonVitalWindows();
00260   ClearErrorMessages();
00261 
00262   /* Copy all XXX_newgame to XXX when coming from outside the editor */
00263   MakeNewgameSettingsLive();
00264   ResetGRFConfig(true);
00265 
00266   if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP);
00267   switch (mode) {
00268     case GLWM_GENERATE:  _switch_mode = (_game_mode == GM_EDITOR) ? SM_GENRANDLAND    : SM_NEWGAME;         break;
00269     case GLWM_HEIGHTMAP: _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_HEIGHTMAP : SM_START_HEIGHTMAP; break;
00270     case GLWM_SCENARIO:  _switch_mode = SM_EDITOR; break;
00271     default: NOT_REACHED();
00272   }
00273 }
00274 
00275 static void LandscapeGenerationCallback(Window *w, bool confirmed)
00276 {
00277   if (confirmed) StartGeneratingLandscape((GenenerateLandscapeWindowMode)w->window_number);
00278 }
00279 
00280 static DropDownList *BuildMapsizeDropDown()
00281 {
00282   DropDownList *list = new DropDownList();
00283 
00284   for (uint i = MIN_MAP_SIZE_BITS; i <= MAX_MAP_SIZE_BITS; i++) {
00285     DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false);
00286     item->SetParam(0, 1 << i);
00287     list->push_back(item);
00288   }
00289 
00290   return list;
00291 }
00292 
00293 static const StringID _elevations[]  = {STR_TERRAIN_TYPE_VERY_FLAT, STR_TERRAIN_TYPE_FLAT, STR_TERRAIN_TYPE_HILLY, STR_TERRAIN_TYPE_MOUNTAINOUS, INVALID_STRING_ID};
00294 static const StringID _sea_lakes[]   = {STR_SEA_LEVEL_VERY_LOW, STR_SEA_LEVEL_LOW, STR_SEA_LEVEL_MEDIUM, STR_SEA_LEVEL_HIGH, STR_SEA_LEVEL_CUSTOM, INVALID_STRING_ID};
00295 static const StringID _rivers[]      = {STR_RIVERS_NONE, STR_RIVERS_FEW, STR_RIVERS_MODERATE, STR_RIVERS_LOT, INVALID_STRING_ID};
00296 static const StringID _smoothness[]  = {STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_SMOOTH, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_ROUGH, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_ROUGH, INVALID_STRING_ID};
00297 static const StringID _tree_placer[] = {STR_CONFIG_SETTING_TREE_PLACER_NONE, STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL, STR_CONFIG_SETTING_TREE_PLACER_IMPROVED, INVALID_STRING_ID};
00298 static const StringID _rotation[]    = {STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE, STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_CLOCKWISE, INVALID_STRING_ID};
00299 static const StringID _landscape[]   = {STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL, STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS, INVALID_STRING_ID};
00300 static const StringID _num_towns[]   = {STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, STR_NUM_CUSTOM, INVALID_STRING_ID};
00301 static const StringID _num_inds[]    = {STR_FUNDING_ONLY, STR_MINIMAL, STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, INVALID_STRING_ID};
00302 static const StringID _variety[]     = {STR_VARIETY_NONE, STR_VARIETY_VERY_LOW, STR_VARIETY_LOW, STR_VARIETY_MEDIUM, STR_VARIETY_HIGH, STR_VARIETY_VERY_HIGH, INVALID_STRING_ID};
00303 
00304 assert_compile(lengthof(_num_inds) == ID_END + 1);
00305 
00306 struct GenerateLandscapeWindow : public Window {
00307   uint widget_id;
00308   uint x;
00309   uint y;
00310   char name[64];
00311   GenenerateLandscapeWindowMode mode;
00312   QueryString seed_editbox;
00313 
00314   GenerateLandscapeWindow(WindowDesc *desc, WindowNumber number = 0) : Window(desc), seed_editbox(11)
00315   {
00316     this->InitNested(number);
00317 
00318     this->LowerWidget(_settings_newgame.game_creation.landscape + WID_GL_TEMPERATE);
00319 
00320     this->querystrings[WID_GL_RANDOM_EDITBOX] = &this->seed_editbox;
00321     this->seed_editbox.text.Print("%u", _settings_newgame.game_creation.generation_seed);
00322     this->seed_editbox.caption = STR_NULL;
00323     this->seed_editbox.text.afilter = CS_NUMERAL;
00324 
00325     this->mode = (GenenerateLandscapeWindowMode)this->window_number;
00326 
00327     /* Disable town, industry and trees in SE */
00328     this->SetWidgetDisabledState(WID_GL_TOWN_PULLDOWN,     _game_mode == GM_EDITOR);
00329     this->SetWidgetDisabledState(WID_GL_INDUSTRY_PULLDOWN, _game_mode == GM_EDITOR);
00330     this->SetWidgetDisabledState(WID_GL_TREE_PULLDOWN,     _game_mode == GM_EDITOR);
00331 
00332     this->OnInvalidateData();
00333   }
00334 
00335 
00336   virtual void SetStringParameters(int widget) const
00337   {
00338     switch (widget) {
00339       case WID_GL_START_DATE_TEXT:     SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1)); break;
00340       case WID_GL_MAPSIZE_X_PULLDOWN:  SetDParam(0, 1 << _settings_newgame.game_creation.map_x); break;
00341       case WID_GL_MAPSIZE_Y_PULLDOWN:  SetDParam(0, 1 << _settings_newgame.game_creation.map_y); break;
00342       case WID_GL_SNOW_LEVEL_TEXT:     SetDParam(0, _settings_newgame.game_creation.snow_line_height); break;
00343 
00344       case WID_GL_TOWN_PULLDOWN:
00345         if (_game_mode == GM_EDITOR) {
00346           SetDParam(0, STR_CONFIG_SETTING_OFF);
00347         } else if (_settings_newgame.difficulty.number_towns == CUSTOM_TOWN_NUMBER_DIFFICULTY) {
00348           SetDParam(0, STR_NUM_CUSTOM_NUMBER);
00349           SetDParam(1, _settings_newgame.game_creation.custom_town_number);
00350         } else {
00351           SetDParam(0, _num_towns[_settings_newgame.difficulty.number_towns]);
00352         }
00353         break;
00354 
00355       case WID_GL_INDUSTRY_PULLDOWN:   SetDParam(0, _game_mode == GM_EDITOR ? STR_CONFIG_SETTING_OFF : _num_inds[_settings_newgame.difficulty.industry_density]); break;
00356       case WID_GL_LANDSCAPE_PULLDOWN:  SetDParam(0, _landscape[_settings_newgame.game_creation.land_generator]); break;
00357       case WID_GL_TREE_PULLDOWN:       SetDParam(0, _tree_placer[_settings_newgame.game_creation.tree_placer]); break;
00358       case WID_GL_TERRAIN_PULLDOWN:    SetDParam(0, _elevations[_settings_newgame.difficulty.terrain_type]); break;
00359 
00360       case WID_GL_WATER_PULLDOWN:
00361         if (_settings_newgame.difficulty.quantity_sea_lakes == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) {
00362           SetDParam(0, STR_SEA_LEVEL_CUSTOM_PERCENTAGE);
00363           SetDParam(1, _settings_newgame.game_creation.custom_sea_level);
00364         } else {
00365           SetDParam(0, _sea_lakes[_settings_newgame.difficulty.quantity_sea_lakes]);
00366         }
00367         break;
00368 
00369       case WID_GL_RIVER_PULLDOWN:      SetDParam(0, _rivers[_settings_newgame.game_creation.amount_of_rivers]); break;
00370       case WID_GL_SMOOTHNESS_PULLDOWN: SetDParam(0, _smoothness[_settings_newgame.game_creation.tgen_smoothness]); break;
00371       case WID_GL_VARIETY_PULLDOWN:    SetDParam(0, _variety[_settings_newgame.game_creation.variety]); break;
00372       case WID_GL_BORDERS_RANDOM:      SetDParam(0, (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? STR_MAPGEN_BORDER_RANDOMIZE : STR_MAPGEN_BORDER_MANUAL); break;
00373       case WID_GL_WATER_NE: SetDParam(0, (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? STR_MAPGEN_BORDER_RANDOM : HasBit(_settings_newgame.game_creation.water_borders, BORDER_NE) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); break;
00374       case WID_GL_WATER_NW: SetDParam(0, (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? STR_MAPGEN_BORDER_RANDOM : HasBit(_settings_newgame.game_creation.water_borders, BORDER_NW) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); break;
00375       case WID_GL_WATER_SE: SetDParam(0, (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? STR_MAPGEN_BORDER_RANDOM : HasBit(_settings_newgame.game_creation.water_borders, BORDER_SE) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); break;
00376       case WID_GL_WATER_SW: SetDParam(0, (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? STR_MAPGEN_BORDER_RANDOM : HasBit(_settings_newgame.game_creation.water_borders, BORDER_SW) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM); break;
00377       case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: SetDParam(0, _rotation[_settings_newgame.game_creation.heightmap_rotation]); break;
00378 
00379       case WID_GL_HEIGHTMAP_SIZE_TEXT:
00380         if (_settings_newgame.game_creation.heightmap_rotation == HM_CLOCKWISE) {
00381           SetDParam(0, this->y);
00382           SetDParam(1, this->x);
00383         } else {
00384           SetDParam(0, this->x);
00385           SetDParam(1, this->y);
00386         }
00387         break;
00388     }
00389   }
00390 
00396   virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
00397   {
00398     if (!gui_scope) return;
00399     /* Update the climate buttons */
00400     this->SetWidgetLoweredState(WID_GL_TEMPERATE, _settings_newgame.game_creation.landscape == LT_TEMPERATE);
00401     this->SetWidgetLoweredState(WID_GL_ARCTIC,    _settings_newgame.game_creation.landscape == LT_ARCTIC);
00402     this->SetWidgetLoweredState(WID_GL_TROPICAL,  _settings_newgame.game_creation.landscape == LT_TROPIC);
00403     this->SetWidgetLoweredState(WID_GL_TOYLAND,   _settings_newgame.game_creation.landscape == LT_TOYLAND);
00404 
00405     /* You can't select smoothness / non-water borders if not terragenesis */
00406     if (mode == GLWM_GENERATE) {
00407       this->SetWidgetDisabledState(WID_GL_SMOOTHNESS_PULLDOWN, _settings_newgame.game_creation.land_generator == 0);
00408       this->SetWidgetDisabledState(WID_GL_VARIETY_PULLDOWN, _settings_newgame.game_creation.land_generator == 0);
00409       this->SetWidgetDisabledState(WID_GL_BORDERS_RANDOM, _settings_newgame.game_creation.land_generator == 0 || !_settings_newgame.construction.freeform_edges);
00410       this->SetWidgetsDisabledState(_settings_newgame.game_creation.land_generator == 0 || !_settings_newgame.construction.freeform_edges || _settings_newgame.game_creation.water_borders == BORDERS_RANDOM,
00411           WID_GL_WATER_NW, WID_GL_WATER_NE, WID_GL_WATER_SE, WID_GL_WATER_SW, WIDGET_LIST_END);
00412 
00413       this->SetWidgetLoweredState(WID_GL_BORDERS_RANDOM, _settings_newgame.game_creation.water_borders == BORDERS_RANDOM);
00414 
00415       this->SetWidgetLoweredState(WID_GL_WATER_NW, HasBit(_settings_newgame.game_creation.water_borders, BORDER_NW));
00416       this->SetWidgetLoweredState(WID_GL_WATER_NE, HasBit(_settings_newgame.game_creation.water_borders, BORDER_NE));
00417       this->SetWidgetLoweredState(WID_GL_WATER_SE, HasBit(_settings_newgame.game_creation.water_borders, BORDER_SE));
00418       this->SetWidgetLoweredState(WID_GL_WATER_SW, HasBit(_settings_newgame.game_creation.water_borders, BORDER_SW));
00419 
00420       this->SetWidgetsDisabledState(_settings_newgame.game_creation.land_generator == 0 && (_settings_newgame.game_creation.landscape == LT_ARCTIC || _settings_newgame.game_creation.landscape == LT_TROPIC),
00421           WID_GL_TERRAIN_PULLDOWN, WID_GL_WATER_PULLDOWN, WIDGET_LIST_END);
00422     }
00423 
00424     /* Disable snowline if not arctic */
00425     this->SetWidgetDisabledState(WID_GL_SNOW_LEVEL_TEXT, _settings_newgame.game_creation.landscape != LT_ARCTIC);
00426 
00427     /* Update availability of decreasing / increasing start date and snow level */
00428     this->SetWidgetDisabledState(WID_GL_START_DATE_DOWN, _settings_newgame.game_creation.starting_year <= MIN_YEAR);
00429     this->SetWidgetDisabledState(WID_GL_START_DATE_UP,   _settings_newgame.game_creation.starting_year >= MAX_YEAR);
00430     this->SetWidgetDisabledState(WID_GL_SNOW_LEVEL_DOWN, _settings_newgame.game_creation.snow_line_height <= MIN_SNOWLINE_HEIGHT || _settings_newgame.game_creation.landscape != LT_ARCTIC);
00431     this->SetWidgetDisabledState(WID_GL_SNOW_LEVEL_UP,   _settings_newgame.game_creation.snow_line_height >= MAX_SNOWLINE_HEIGHT || _settings_newgame.game_creation.landscape != LT_ARCTIC);
00432 
00433     /* Do not allow a custom sea level with the original land generator. */
00434     if (_settings_newgame.game_creation.land_generator == 0 &&
00435         _settings_newgame.difficulty.quantity_sea_lakes == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) {
00436       _settings_newgame.difficulty.quantity_sea_lakes = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE;
00437     }
00438 
00439   }
00440 
00441   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
00442   {
00443     const StringID *strs = NULL;
00444     switch (widget) {
00445       case WID_GL_START_DATE_TEXT:
00446         SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
00447         *size = GetStringBoundingBox(STR_BLACK_DATE_LONG);
00448         break;
00449 
00450       case WID_GL_MAPSIZE_X_PULLDOWN:
00451       case WID_GL_MAPSIZE_Y_PULLDOWN:
00452         SetDParamMaxValue(0, MAX_MAP_SIZE);
00453         *size = GetStringBoundingBox(STR_JUST_INT);
00454         break;
00455 
00456       case WID_GL_SNOW_LEVEL_TEXT:
00457         SetDParamMaxValue(0, MAX_TILE_HEIGHT);
00458         *size = GetStringBoundingBox(STR_JUST_INT);
00459         break;
00460 
00461       case WID_GL_HEIGHTMAP_SIZE_TEXT:
00462         SetDParam(0, this->x);
00463         SetDParam(1, this->y);
00464         *size = GetStringBoundingBox(STR_MAPGEN_HEIGHTMAP_SIZE);
00465         break;
00466 
00467       case WID_GL_TOWN_PULLDOWN:
00468         strs = _num_towns;
00469         SetDParamMaxValue(0, CUSTOM_TOWN_MAX_NUMBER);
00470         *size = GetStringBoundingBox(STR_NUM_CUSTOM_NUMBER);
00471         break;
00472 
00473       case WID_GL_INDUSTRY_PULLDOWN:   strs = _num_inds; break;
00474       case WID_GL_LANDSCAPE_PULLDOWN:  strs = _landscape; break;
00475       case WID_GL_TREE_PULLDOWN:       strs = _tree_placer; break;
00476       case WID_GL_TERRAIN_PULLDOWN:    strs = _elevations; break;
00477       case WID_GL_WATER_PULLDOWN:
00478         strs = _sea_lakes;
00479         SetDParamMaxValue(0, CUSTOM_SEA_LEVEL_MAX_PERCENTAGE);
00480         *size = GetStringBoundingBox(STR_SEA_LEVEL_CUSTOM_PERCENTAGE);
00481         break;
00482 
00483       case WID_GL_RIVER_PULLDOWN:      strs = _rivers; break;
00484       case WID_GL_SMOOTHNESS_PULLDOWN: strs = _smoothness; break;
00485       case WID_GL_VARIETY_PULLDOWN:    strs = _variety; break;
00486       case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: strs = _rotation; break;
00487       case WID_GL_BORDERS_RANDOM:
00488         *size = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOMIZE), GetStringBoundingBox(STR_MAPGEN_BORDER_MANUAL));
00489         break;
00490 
00491       case WID_GL_WATER_NE:
00492       case WID_GL_WATER_NW:
00493       case WID_GL_WATER_SE:
00494       case WID_GL_WATER_SW:
00495         *size = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOM), maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_WATER), GetStringBoundingBox(STR_MAPGEN_BORDER_FREEFORM)));
00496         break;
00497 
00498       case WID_GL_HEIGHTMAP_NAME_TEXT:
00499         size->width = 0;
00500         break;
00501 
00502       default:
00503         return;
00504     }
00505     if (strs != NULL) {
00506       while (*strs != INVALID_STRING_ID) {
00507         *size = maxdim(*size, GetStringBoundingBox(*strs++));
00508       }
00509     }
00510     size->width += padding.width;
00511     size->height = FONT_HEIGHT_NORMAL + WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM;
00512   }
00513 
00514   virtual void DrawWidget(const Rect &r, int widget) const
00515   {
00516     switch (widget) {
00517       case WID_GL_HEIGHTMAP_NAME_TEXT: {
00518         DrawString(r.left, r.right, r.top, this->name, TC_ORANGE);
00519         break;
00520       }
00521     }
00522   }
00523 
00524   virtual void OnClick(Point pt, int widget, int click_count)
00525   {
00526     switch (widget) {
00527       case WID_GL_TEMPERATE:
00528       case WID_GL_ARCTIC:
00529       case WID_GL_TROPICAL:
00530       case WID_GL_TOYLAND:
00531         SetNewLandscapeType(widget - WID_GL_TEMPERATE);
00532         break;
00533 
00534       case WID_GL_MAPSIZE_X_PULLDOWN: // Mapsize X
00535         ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_x, WID_GL_MAPSIZE_X_PULLDOWN);
00536         break;
00537 
00538       case WID_GL_MAPSIZE_Y_PULLDOWN: // Mapsize Y
00539         ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_y, WID_GL_MAPSIZE_Y_PULLDOWN);
00540         break;
00541 
00542       case WID_GL_TOWN_PULLDOWN: // Number of towns
00543         ShowDropDownMenu(this, _num_towns, _settings_newgame.difficulty.number_towns, WID_GL_TOWN_PULLDOWN, 0, 0);
00544         break;
00545 
00546       case WID_GL_INDUSTRY_PULLDOWN: // Number of industries
00547         ShowDropDownMenu(this, _num_inds, _settings_newgame.difficulty.industry_density, WID_GL_INDUSTRY_PULLDOWN, 0, 0);
00548         break;
00549 
00550       case WID_GL_RANDOM_BUTTON: // Random seed
00551         _settings_newgame.game_creation.generation_seed = InteractiveRandom();
00552         this->seed_editbox.text.Print("%u", _settings_newgame.game_creation.generation_seed);
00553         this->SetDirty();
00554         break;
00555 
00556       case WID_GL_GENERATE_BUTTON: { // Generate
00557         /* Get rotated map size. */
00558         uint map_x;
00559         uint map_y;
00560         if (_settings_newgame.game_creation.heightmap_rotation == HM_CLOCKWISE) {
00561           map_x = this->y;
00562           map_y = this->x;
00563         } else {
00564           map_x = this->x;
00565           map_y = this->y;
00566         }
00567         if (mode == GLWM_HEIGHTMAP &&
00568             (map_x * 2 < (1U << _settings_newgame.game_creation.map_x) ||
00569             map_x / 2 > (1U << _settings_newgame.game_creation.map_x) ||
00570             map_y * 2 < (1U << _settings_newgame.game_creation.map_y) ||
00571             map_y / 2 > (1U << _settings_newgame.game_creation.map_y))) {
00572           ShowQuery(
00573             STR_WARNING_HEIGHTMAP_SCALE_CAPTION,
00574             STR_WARNING_HEIGHTMAP_SCALE_MESSAGE,
00575             this,
00576             LandscapeGenerationCallback);
00577         } else {
00578           StartGeneratingLandscape(mode);
00579         }
00580         break;
00581       }
00582 
00583       case WID_GL_START_DATE_DOWN:
00584       case WID_GL_START_DATE_UP: // Year buttons
00585         /* Don't allow too fast scrolling */
00586         if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
00587           this->HandleButtonClick(widget);
00588 
00589           _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_GL_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
00590           this->InvalidateData();
00591         }
00592         _left_button_clicked = false;
00593         break;
00594 
00595       case WID_GL_START_DATE_TEXT: // Year text
00596         this->widget_id = WID_GL_START_DATE_TEXT;
00597         SetDParam(0, _settings_newgame.game_creation.starting_year);
00598         ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ENABLE_DEFAULT);
00599         break;
00600 
00601       case WID_GL_SNOW_LEVEL_DOWN:
00602       case WID_GL_SNOW_LEVEL_UP: // Snow line buttons
00603         /* Don't allow too fast scrolling */
00604         if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
00605           this->HandleButtonClick(widget);
00606 
00607           _settings_newgame.game_creation.snow_line_height = Clamp(_settings_newgame.game_creation.snow_line_height + widget - WID_GL_SNOW_LEVEL_TEXT, MIN_SNOWLINE_HEIGHT, MAX_SNOWLINE_HEIGHT);
00608           this->InvalidateData();
00609         }
00610         _left_button_clicked = false;
00611         break;
00612 
00613       case WID_GL_SNOW_LEVEL_TEXT: // Snow line text
00614         this->widget_id = WID_GL_SNOW_LEVEL_TEXT;
00615         SetDParam(0, _settings_newgame.game_creation.snow_line_height);
00616         ShowQueryString(STR_JUST_INT, STR_MAPGEN_SNOW_LINE_QUERY_CAPT, 3, this, CS_NUMERAL, QSF_ENABLE_DEFAULT);
00617         break;
00618 
00619       case WID_GL_TREE_PULLDOWN: // Tree placer
00620         ShowDropDownMenu(this, _tree_placer, _settings_newgame.game_creation.tree_placer, WID_GL_TREE_PULLDOWN, 0, 0);
00621         break;
00622 
00623       case WID_GL_LANDSCAPE_PULLDOWN: // Landscape generator
00624         ShowDropDownMenu(this, _landscape, _settings_newgame.game_creation.land_generator, WID_GL_LANDSCAPE_PULLDOWN, 0, 0);
00625         break;
00626 
00627       case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: // Heightmap rotation
00628         ShowDropDownMenu(this, _rotation, _settings_newgame.game_creation.heightmap_rotation, WID_GL_HEIGHTMAP_ROTATION_PULLDOWN, 0, 0);
00629         break;
00630 
00631       case WID_GL_TERRAIN_PULLDOWN: // Terrain type
00632         ShowDropDownMenu(this, _elevations, _settings_newgame.difficulty.terrain_type, WID_GL_TERRAIN_PULLDOWN, 0, 0);
00633         break;
00634 
00635       case WID_GL_WATER_PULLDOWN: { // Water quantity
00636         uint32 hidden_mask = 0;
00637         /* Disable custom water level when the original map generator is active. */
00638         if (_settings_newgame.game_creation.land_generator == 0) {
00639           SetBit(hidden_mask, CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY);
00640         }
00641         ShowDropDownMenu(this, _sea_lakes, _settings_newgame.difficulty.quantity_sea_lakes, WID_GL_WATER_PULLDOWN, 0, hidden_mask);
00642         break;
00643       }
00644 
00645       case WID_GL_RIVER_PULLDOWN: // Amount of rivers
00646         ShowDropDownMenu(this, _rivers, _settings_newgame.game_creation.amount_of_rivers, WID_GL_RIVER_PULLDOWN, 0, 0);
00647         break;
00648 
00649       case WID_GL_SMOOTHNESS_PULLDOWN: // Map smoothness
00650         ShowDropDownMenu(this, _smoothness, _settings_newgame.game_creation.tgen_smoothness, WID_GL_SMOOTHNESS_PULLDOWN, 0, 0);
00651         break;
00652 
00653       case WID_GL_VARIETY_PULLDOWN: // Map variety
00654         ShowDropDownMenu(this, _variety, _settings_newgame.game_creation.variety, WID_GL_VARIETY_PULLDOWN, 0, 0);
00655         break;
00656 
00657       /* Freetype map borders */
00658       case WID_GL_WATER_NW:
00659         _settings_newgame.game_creation.water_borders = ToggleBit(_settings_newgame.game_creation.water_borders, BORDER_NW);
00660         this->InvalidateData();
00661         break;
00662 
00663       case WID_GL_WATER_NE:
00664         _settings_newgame.game_creation.water_borders = ToggleBit(_settings_newgame.game_creation.water_borders, BORDER_NE);
00665         this->InvalidateData();
00666         break;
00667 
00668       case WID_GL_WATER_SE:
00669         _settings_newgame.game_creation.water_borders = ToggleBit(_settings_newgame.game_creation.water_borders, BORDER_SE);
00670         this->InvalidateData();
00671         break;
00672 
00673       case WID_GL_WATER_SW:
00674         _settings_newgame.game_creation.water_borders = ToggleBit(_settings_newgame.game_creation.water_borders, BORDER_SW);
00675         this->InvalidateData();
00676         break;
00677 
00678       case WID_GL_BORDERS_RANDOM:
00679         _settings_newgame.game_creation.water_borders = (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? 0 : BORDERS_RANDOM;
00680         this->InvalidateData();
00681         break;
00682     }
00683   }
00684 
00685   virtual void OnTimeout()
00686   {
00687     static const int raise_widgets[] = {WID_GL_START_DATE_DOWN, WID_GL_START_DATE_UP, WID_GL_SNOW_LEVEL_UP, WID_GL_SNOW_LEVEL_DOWN, WIDGET_LIST_END};
00688     for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) {
00689       if (this->IsWidgetLowered(*widget)) {
00690         this->RaiseWidget(*widget);
00691         this->SetWidgetDirty(*widget);
00692       }
00693     }
00694   }
00695 
00696   virtual void OnEditboxChanged(int wid)
00697   {
00698     if (wid == WID_GL_RANDOM_EDITBOX) {
00699       /* the seed is unsigned, therefore atoi cannot be used.
00700        * As UINT32_MAX is a 'magic' value (use random seed) it
00701        * should not be possible to be entered into the input
00702        * field; the generate seed button can be used instead. */
00703       _settings_newgame.game_creation.generation_seed = minu(strtoul(this->seed_editbox.text.buf, NULL, 10), UINT32_MAX - 1);
00704     }
00705   }
00706 
00707   virtual void OnDropdownSelect(int widget, int index)
00708   {
00709     switch (widget) {
00710       case WID_GL_MAPSIZE_X_PULLDOWN:     _settings_newgame.game_creation.map_x = index; break;
00711       case WID_GL_MAPSIZE_Y_PULLDOWN:     _settings_newgame.game_creation.map_y = index; break;
00712       case WID_GL_TREE_PULLDOWN:          _settings_newgame.game_creation.tree_placer = index; break;
00713       case WID_GL_RIVER_PULLDOWN:         _settings_newgame.game_creation.amount_of_rivers = index; break;
00714       case WID_GL_SMOOTHNESS_PULLDOWN:    _settings_newgame.game_creation.tgen_smoothness = index;  break;
00715       case WID_GL_VARIETY_PULLDOWN:       _settings_newgame.game_creation.variety = index; break;
00716       case WID_GL_LANDSCAPE_PULLDOWN:     _settings_newgame.game_creation.land_generator = index; break;
00717       case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: _settings_newgame.game_creation.heightmap_rotation = index; break;
00718 
00719       case WID_GL_TOWN_PULLDOWN:
00720         if ((uint)index == CUSTOM_TOWN_NUMBER_DIFFICULTY) {
00721           this->widget_id = widget;
00722           SetDParam(0, _settings_newgame.game_creation.custom_town_number);
00723           ShowQueryString(STR_JUST_INT, STR_MAPGEN_NUMBER_OF_TOWNS, 5, this, CS_NUMERAL, QSF_NONE);
00724         }
00725         IConsoleSetSetting("difficulty.number_towns", index);
00726         break;
00727 
00728       case WID_GL_INDUSTRY_PULLDOWN:
00729         IConsoleSetSetting("difficulty.industry_density", index);
00730         break;
00731 
00732       case WID_GL_TERRAIN_PULLDOWN: {
00733         GameMode old_gm = _game_mode;
00734         _game_mode = GM_MENU;
00735         IConsoleSetSetting("difficulty.terrain_type", index);
00736         _game_mode = old_gm;
00737         break;
00738       }
00739 
00740       case WID_GL_WATER_PULLDOWN: {
00741         if ((uint)index == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) {
00742           this->widget_id = widget;
00743           SetDParam(0, _settings_newgame.game_creation.custom_sea_level);
00744           ShowQueryString(STR_JUST_INT, STR_MAPGEN_QUANTITY_OF_SEA_LAKES, 3, this, CS_NUMERAL, QSF_NONE);
00745         }
00746         GameMode old_gm = _game_mode;
00747         _game_mode = GM_MENU;
00748         IConsoleSetSetting("difficulty.quantity_sea_lakes", index);
00749         _game_mode = old_gm;
00750         break;
00751       }
00752     }
00753     this->InvalidateData();
00754   }
00755 
00756   virtual void OnQueryTextFinished(char *str)
00757   {
00758     /* Was 'cancel' pressed? */
00759     if (str == NULL) return;
00760 
00761     int32 value;
00762     if (!StrEmpty(str)) {
00763       value = atoi(str);
00764     } else {
00765       /* An empty string means revert to the default */
00766       switch (this->widget_id) {
00767         case WID_GL_START_DATE_TEXT: value = DEF_START_YEAR; break;
00768         case WID_GL_SNOW_LEVEL_TEXT: value = DEF_SNOWLINE_HEIGHT; break;
00769         case WID_GL_TOWN_PULLDOWN:   value = 1; break;
00770         case WID_GL_WATER_PULLDOWN:  value = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE; break;
00771         default: NOT_REACHED();
00772       }
00773     }
00774 
00775     switch (this->widget_id) {
00776       case WID_GL_START_DATE_TEXT:
00777         this->SetWidgetDirty(WID_GL_START_DATE_TEXT);
00778         _settings_newgame.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
00779         break;
00780 
00781       case WID_GL_SNOW_LEVEL_TEXT:
00782         this->SetWidgetDirty(WID_GL_SNOW_LEVEL_TEXT);
00783         _settings_newgame.game_creation.snow_line_height = Clamp(value, MIN_SNOWLINE_HEIGHT, MAX_SNOWLINE_HEIGHT);
00784         break;
00785 
00786       case WID_GL_TOWN_PULLDOWN:
00787         _settings_newgame.game_creation.custom_town_number = Clamp(value, 1, CUSTOM_TOWN_MAX_NUMBER);
00788         break;
00789 
00790       case WID_GL_WATER_PULLDOWN:
00791         _settings_newgame.game_creation.custom_sea_level = Clamp(value, CUSTOM_SEA_LEVEL_MIN_PERCENTAGE, CUSTOM_SEA_LEVEL_MAX_PERCENTAGE);
00792         break;
00793     }
00794 
00795     this->InvalidateData();
00796   }
00797 };
00798 
00799 static WindowDesc _generate_landscape_desc(
00800   WDP_CENTER, NULL, 0, 0,
00801   WC_GENERATE_LANDSCAPE, WC_NONE,
00802   0,
00803   _nested_generate_landscape_widgets, lengthof(_nested_generate_landscape_widgets)
00804 );
00805 
00806 static WindowDesc _heightmap_load_desc(
00807   WDP_CENTER, NULL, 0, 0,
00808   WC_GENERATE_LANDSCAPE, WC_NONE,
00809   0,
00810   _nested_heightmap_load_widgets, lengthof(_nested_heightmap_load_widgets)
00811 );
00812 
00813 static void _ShowGenerateLandscape(GenenerateLandscapeWindowMode mode)
00814 {
00815   uint x = 0;
00816   uint y = 0;
00817 
00818   DeleteWindowByClass(WC_GENERATE_LANDSCAPE);
00819 
00820   /* Always give a new seed if not editor */
00821   if (_game_mode != GM_EDITOR) _settings_newgame.game_creation.generation_seed = InteractiveRandom();
00822 
00823   if (mode == GLWM_HEIGHTMAP) {
00824     /* If the function returns negative, it means there was a problem loading the heightmap */
00825     if (!GetHeightmapDimensions(_file_to_saveload.name, &x, &y)) return;
00826   }
00827 
00828   GenerateLandscapeWindow *w = AllocateWindowDescFront<GenerateLandscapeWindow>((mode == GLWM_HEIGHTMAP) ? &_heightmap_load_desc : &_generate_landscape_desc, mode);
00829 
00830   if (mode == GLWM_HEIGHTMAP) {
00831     w->x = x;
00832     w->y = y;
00833     strecpy(w->name, _file_to_saveload.title, lastof(w->name));
00834   }
00835 
00836   SetWindowDirty(WC_GENERATE_LANDSCAPE, mode);
00837 }
00838 
00840 void ShowGenerateLandscape()
00841 {
00842   _ShowGenerateLandscape(GLWM_GENERATE);
00843 }
00844 
00846 void ShowHeightmapLoad()
00847 {
00848   _ShowGenerateLandscape(GLWM_HEIGHTMAP);
00849 }
00850 
00852 void StartScenarioEditor()
00853 {
00854   StartGeneratingLandscape(GLWM_SCENARIO);
00855 }
00856 
00861 void StartNewGameWithoutGUI(uint seed)
00862 {
00863   /* GenerateWorld takes care of the possible GENERATE_NEW_SEED value in 'seed' */
00864   _settings_newgame.game_creation.generation_seed = seed;
00865 
00866   StartGeneratingLandscape(GLWM_GENERATE);
00867 }
00868 
00869 struct CreateScenarioWindow : public Window
00870 {
00871   uint widget_id;
00872 
00873   CreateScenarioWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
00874   {
00875     this->InitNested(window_number);
00876     this->LowerWidget(_settings_newgame.game_creation.landscape + WID_CS_TEMPERATE);
00877   }
00878 
00879   virtual void SetStringParameters(int widget) const
00880   {
00881     switch (widget) {
00882       case WID_CS_START_DATE_TEXT:
00883         SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1));
00884         break;
00885 
00886       case WID_CS_MAPSIZE_X_PULLDOWN:
00887         SetDParam(0, 1 << _settings_newgame.game_creation.map_x);
00888         break;
00889 
00890       case WID_CS_MAPSIZE_Y_PULLDOWN:
00891         SetDParam(0, 1 << _settings_newgame.game_creation.map_y);
00892         break;
00893 
00894       case WID_CS_FLAT_LAND_HEIGHT_TEXT:
00895         SetDParam(0, _settings_newgame.game_creation.se_flat_world_height);
00896         break;
00897     }
00898   }
00899 
00900   virtual void OnPaint()
00901   {
00902     this->SetWidgetDisabledState(WID_CS_START_DATE_DOWN,       _settings_newgame.game_creation.starting_year <= MIN_YEAR);
00903     this->SetWidgetDisabledState(WID_CS_START_DATE_UP,         _settings_newgame.game_creation.starting_year >= MAX_YEAR);
00904     this->SetWidgetDisabledState(WID_CS_FLAT_LAND_HEIGHT_DOWN, _settings_newgame.game_creation.se_flat_world_height <= 0);
00905     this->SetWidgetDisabledState(WID_CS_FLAT_LAND_HEIGHT_UP,   _settings_newgame.game_creation.se_flat_world_height >= MAX_TILE_HEIGHT);
00906 
00907     this->SetWidgetLoweredState(WID_CS_TEMPERATE, _settings_newgame.game_creation.landscape == LT_TEMPERATE);
00908     this->SetWidgetLoweredState(WID_CS_ARCTIC,    _settings_newgame.game_creation.landscape == LT_ARCTIC);
00909     this->SetWidgetLoweredState(WID_CS_TROPICAL,  _settings_newgame.game_creation.landscape == LT_TROPIC);
00910     this->SetWidgetLoweredState(WID_CS_TOYLAND,   _settings_newgame.game_creation.landscape == LT_TOYLAND);
00911 
00912     this->DrawWidgets();
00913   }
00914 
00915   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
00916   {
00917     StringID str = STR_JUST_INT;
00918     switch (widget) {
00919       case WID_CS_START_DATE_TEXT:
00920         SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
00921         str = STR_BLACK_DATE_LONG;
00922         break;
00923 
00924       case WID_CS_MAPSIZE_X_PULLDOWN:
00925       case WID_CS_MAPSIZE_Y_PULLDOWN:
00926         SetDParamMaxValue(0, MAX_MAP_SIZE);
00927         break;
00928 
00929       case WID_CS_FLAT_LAND_HEIGHT_TEXT:
00930         SetDParamMaxValue(0, MAX_TILE_HEIGHT);
00931         break;
00932 
00933       default:
00934         return;
00935     }
00936     *size = GetStringBoundingBox(str);
00937     size->width += padding.width;
00938     size->height += padding.height;
00939   }
00940 
00941   virtual void OnClick(Point pt, int widget, int click_count)
00942   {
00943     switch (widget) {
00944       case WID_CS_TEMPERATE:
00945       case WID_CS_ARCTIC:
00946       case WID_CS_TROPICAL:
00947       case WID_CS_TOYLAND:
00948         this->RaiseWidget(_settings_newgame.game_creation.landscape + WID_CS_TEMPERATE);
00949         SetNewLandscapeType(widget - WID_CS_TEMPERATE);
00950         break;
00951 
00952       case WID_CS_MAPSIZE_X_PULLDOWN: // Mapsize X
00953         ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_x, WID_CS_MAPSIZE_X_PULLDOWN);
00954         break;
00955 
00956       case WID_CS_MAPSIZE_Y_PULLDOWN: // Mapsize Y
00957         ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_y, WID_CS_MAPSIZE_Y_PULLDOWN);
00958         break;
00959 
00960       case WID_CS_EMPTY_WORLD: // Empty world / flat world
00961         StartGeneratingLandscape(GLWM_SCENARIO);
00962         break;
00963 
00964       case WID_CS_RANDOM_WORLD: // Generate
00965         ShowGenerateLandscape();
00966         break;
00967 
00968       case WID_CS_START_DATE_DOWN:
00969       case WID_CS_START_DATE_UP: // Year buttons
00970         /* Don't allow too fast scrolling */
00971         if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
00972           this->HandleButtonClick(widget);
00973           this->SetDirty();
00974 
00975           _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_CS_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
00976         }
00977         _left_button_clicked = false;
00978         break;
00979 
00980       case WID_CS_START_DATE_TEXT: // Year text
00981         this->widget_id = WID_CS_START_DATE_TEXT;
00982         SetDParam(0, _settings_newgame.game_creation.starting_year);
00983         ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_NONE);
00984         break;
00985 
00986       case WID_CS_FLAT_LAND_HEIGHT_DOWN:
00987       case WID_CS_FLAT_LAND_HEIGHT_UP: // Height level buttons
00988         /* Don't allow too fast scrolling */
00989         if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
00990           this->HandleButtonClick(widget);
00991           this->SetDirty();
00992 
00993           _settings_newgame.game_creation.se_flat_world_height = Clamp(_settings_newgame.game_creation.se_flat_world_height + widget - WID_CS_FLAT_LAND_HEIGHT_TEXT, 0, MAX_TILE_HEIGHT);
00994         }
00995         _left_button_clicked = false;
00996         break;
00997 
00998       case WID_CS_FLAT_LAND_HEIGHT_TEXT: // Height level text
00999         this->widget_id = WID_CS_FLAT_LAND_HEIGHT_TEXT;
01000         SetDParam(0, _settings_newgame.game_creation.se_flat_world_height);
01001         ShowQueryString(STR_JUST_INT, STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_QUERY_CAPT, 3, this, CS_NUMERAL, QSF_NONE);
01002         break;
01003     }
01004   }
01005 
01006   virtual void OnTimeout()
01007   {
01008     static const int raise_widgets[] = {WID_CS_START_DATE_DOWN, WID_CS_START_DATE_UP, WID_CS_FLAT_LAND_HEIGHT_DOWN, WID_CS_FLAT_LAND_HEIGHT_UP, WIDGET_LIST_END};
01009     for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) {
01010       if (this->IsWidgetLowered(*widget)) {
01011         this->RaiseWidget(*widget);
01012         this->SetWidgetDirty(*widget);
01013       }
01014     }
01015   }
01016 
01017   virtual void OnDropdownSelect(int widget, int index)
01018   {
01019     switch (widget) {
01020       case WID_CS_MAPSIZE_X_PULLDOWN: _settings_newgame.game_creation.map_x = index; break;
01021       case WID_CS_MAPSIZE_Y_PULLDOWN: _settings_newgame.game_creation.map_y = index; break;
01022     }
01023     this->SetDirty();
01024   }
01025 
01026   virtual void OnQueryTextFinished(char *str)
01027   {
01028     if (!StrEmpty(str)) {
01029       int32 value = atoi(str);
01030 
01031       switch (this->widget_id) {
01032         case WID_CS_START_DATE_TEXT:
01033           this->SetWidgetDirty(WID_CS_START_DATE_TEXT);
01034           _settings_newgame.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
01035           break;
01036 
01037         case WID_CS_FLAT_LAND_HEIGHT_TEXT:
01038           this->SetWidgetDirty(WID_CS_FLAT_LAND_HEIGHT_TEXT);
01039           _settings_newgame.game_creation.se_flat_world_height = Clamp(value, 0, MAX_TILE_HEIGHT);
01040           break;
01041       }
01042 
01043       this->SetDirty();
01044     }
01045   }
01046 };
01047 
01048 static const NWidgetPart _nested_create_scenario_widgets[] = {
01049   NWidget(NWID_HORIZONTAL),
01050     NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
01051     NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_SE_MAPGEN_CAPTION, STR_NULL),
01052   EndContainer(),
01053   NWidget(WWT_PANEL, COLOUR_BROWN),
01054     NWidget(NWID_SPACER), SetMinimalSize(0, 10),
01055     /* Landscape style selection. */
01056     NWidget(NWID_HORIZONTAL), SetPIP(10, 3, 10),
01057       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
01058       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
01059       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
01060       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
01061     EndContainer(),
01062     NWidget(NWID_HORIZONTAL), SetPIP(10, 8, 10),
01063       /* Green generation type buttons: 'Flat land' and 'Random land'. */
01064       NWidget(NWID_VERTICAL), SetPIP(10, 6, 10),
01065         NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_CS_EMPTY_WORLD), SetDataTip(STR_SE_MAPGEN_FLAT_WORLD, STR_SE_MAPGEN_FLAT_WORLD_TOOLTIP), SetFill(1, 1),
01066         NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_CS_RANDOM_WORLD), SetDataTip(STR_SE_MAPGEN_RANDOM_LAND, STR_TERRAFORM_TOOLTIP_GENERATE_RANDOM_LAND), SetFill(1, 1),
01067       EndContainer(),
01068       /* Labels + setting drop-downs */
01069       NWidget(NWID_VERTICAL), SetPIP(10, 6, 10),
01070         /* Map size. */
01071         NWidget(NWID_HORIZONTAL),
01072           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_NULL), SetPadding(1, 0, 0, 0),
01073           NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0),
01074           NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_CS_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetPadding(0, 4, 0, 0),
01075           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 2, 0, 0),
01076           NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_CS_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL),
01077         EndContainer(),
01078         /* Date. */
01079         NWidget(NWID_HORIZONTAL),
01080           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetPadding(1, 0, 0, 0),
01081           NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0),
01082           NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_CS_START_DATE_DOWN), SetFill(0, 1), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD),
01083           NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CS_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL),
01084           NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_CS_START_DATE_UP), SetFill(0, 1), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD),
01085         EndContainer(),
01086         /* Flat map height. */
01087         NWidget(NWID_HORIZONTAL),
01088           NWidget(WWT_TEXT, COLOUR_ORANGE),
01089                         SetDataTip(STR_SE_MAPGEN_FLAT_WORLD_HEIGHT, STR_NULL), SetPadding(1, 0, 0, 0),
01090           NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0),
01091           NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_CS_FLAT_LAND_HEIGHT_DOWN), SetFill(0, 1), SetDataTip(SPR_ARROW_DOWN, STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_DOWN),
01092           NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CS_FLAT_LAND_HEIGHT_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL),
01093           NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_CS_FLAT_LAND_HEIGHT_UP), SetFill(0, 1), SetDataTip(SPR_ARROW_UP, STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_UP),
01094         EndContainer(),
01095       EndContainer(),
01096     EndContainer(),
01097   EndContainer(),
01098 };
01099 
01100 static WindowDesc _create_scenario_desc(
01101   WDP_CENTER, NULL, 0, 0,
01102   WC_GENERATE_LANDSCAPE, WC_NONE,
01103   0,
01104   _nested_create_scenario_widgets, lengthof(_nested_create_scenario_widgets)
01105 );
01106 
01108 void ShowCreateScenario()
01109 {
01110   DeleteWindowByClass(WC_GENERATE_LANDSCAPE);
01111   new CreateScenarioWindow(&_create_scenario_desc, GLWM_SCENARIO);
01112 }
01113 
01114 static const NWidgetPart _nested_generate_progress_widgets[] = {
01115   NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_GENERATION_WORLD, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01116   NWidget(WWT_PANEL, COLOUR_GREY),
01117     NWidget(NWID_HORIZONTAL), SetPIP(20, 0, 20),
01118       NWidget(NWID_VERTICAL), SetPIP(11, 8, 11),
01119         NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_BAR), SetFill(1, 0),
01120         NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_TEXT), SetFill(1, 0),
01121         NWidget(WWT_TEXTBTN, COLOUR_WHITE, WID_GP_ABORT), SetDataTip(STR_GENERATION_ABORT, STR_NULL), SetFill(1, 0),
01122       EndContainer(),
01123     EndContainer(),
01124   EndContainer(),
01125 };
01126 
01127 
01128 static WindowDesc _generate_progress_desc(
01129   WDP_CENTER, NULL, 0, 0,
01130   WC_MODAL_PROGRESS, WC_NONE,
01131   0,
01132   _nested_generate_progress_widgets, lengthof(_nested_generate_progress_widgets)
01133 );
01134 
01135 struct GenWorldStatus {
01136   uint percent;
01137   StringID cls;
01138   uint current;
01139   uint total;
01140   int timer;
01141 };
01142 
01143 static GenWorldStatus _gws;
01144 
01145 static const StringID _generation_class_table[]  = {
01146   STR_GENERATION_WORLD_GENERATION,
01147   STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION,
01148   STR_GENERATION_RIVER_GENERATION,
01149   STR_GENERATION_CLEARING_TILES,
01150   STR_SCENEDIT_TOOLBAR_TOWN_GENERATION,
01151   STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION,
01152   STR_GENERATION_OBJECT_GENERATION,
01153   STR_GENERATION_TREE_GENERATION,
01154   STR_GENERATION_SETTINGUP_GAME,
01155   STR_GENERATION_PREPARING_TILELOOP,
01156   STR_GENERATION_PREPARING_SCRIPT,
01157   STR_GENERATION_PREPARING_GAME
01158 };
01159 assert_compile(lengthof(_generation_class_table) == GWP_CLASS_COUNT);
01160 
01161 
01162 static void AbortGeneratingWorldCallback(Window *w, bool confirmed)
01163 {
01164   if (confirmed) {
01165     AbortGeneratingWorld();
01166   } else if (HasModalProgress() && !IsGeneratingWorldAborted()) {
01167     SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
01168   }
01169 }
01170 
01171 struct GenerateProgressWindow : public Window {
01172 
01173   GenerateProgressWindow() : Window(&_generate_progress_desc)
01174   {
01175     this->InitNested();
01176   }
01177 
01178   virtual void OnClick(Point pt, int widget, int click_count)
01179   {
01180     switch (widget) {
01181       case WID_GP_ABORT:
01182         if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
01183         ShowQuery(
01184           STR_GENERATION_ABORT_CAPTION,
01185           STR_GENERATION_ABORT_MESSAGE,
01186           this,
01187           AbortGeneratingWorldCallback
01188         );
01189         break;
01190     }
01191   }
01192 
01193   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01194   {
01195     switch (widget) {
01196       case WID_GP_PROGRESS_BAR: {
01197         SetDParamMaxValue(0, 100);
01198         *size = GetStringBoundingBox(STR_GENERATION_PROGRESS);
01199         /* We need some spacing for the 'border' */
01200         size->height += 8;
01201         size->width += 8;
01202         break;
01203       }
01204 
01205       case WID_GP_PROGRESS_TEXT:
01206         for (uint i = 0; i < GWP_CLASS_COUNT; i++) {
01207           size->width = max(size->width, GetStringBoundingBox(_generation_class_table[i]).width);
01208         }
01209         size->height = FONT_HEIGHT_NORMAL * 2 + WD_PAR_VSEP_NORMAL;
01210         break;
01211     }
01212   }
01213 
01214   virtual void DrawWidget(const Rect &r, int widget) const
01215   {
01216     switch (widget) {
01217       case WID_GP_PROGRESS_BAR:
01218         /* Draw the % complete with a bar and a text */
01219         DrawFrameRect(r.left, r.top, r.right, r.bottom, COLOUR_GREY, FR_BORDERONLY);
01220         DrawFrameRect(r.left + 1, r.top + 1, (int)((r.right - r.left - 2) * _gws.percent / 100) + r.left + 1, r.bottom - 1, COLOUR_MAUVE, FR_NONE);
01221         SetDParam(0, _gws.percent);
01222         DrawString(r.left, r.right, r.top + 5, STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER);
01223         break;
01224 
01225       case WID_GP_PROGRESS_TEXT:
01226         /* Tell which class we are generating */
01227         DrawString(r.left, r.right, r.top, _gws.cls, TC_FROMSTRING, SA_HOR_CENTER);
01228 
01229         /* And say where we are in that class */
01230         SetDParam(0, _gws.current);
01231         SetDParam(1, _gws.total);
01232         DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL, STR_GENERATION_PROGRESS_NUM, TC_FROMSTRING, SA_HOR_CENTER);
01233     }
01234   }
01235 };
01236 
01240 void PrepareGenerateWorldProgress()
01241 {
01242   _gws.cls     = STR_GENERATION_WORLD_GENERATION;
01243   _gws.current = 0;
01244   _gws.total   = 0;
01245   _gws.percent = 0;
01246   _gws.timer   = 0; // Forces to paint the progress window immediately
01247 }
01248 
01252 void ShowGenerateWorldProgress()
01253 {
01254   if (BringWindowToFrontById(WC_MODAL_PROGRESS, 0)) return;
01255   new GenerateProgressWindow();
01256 }
01257 
01258 static void _SetGeneratingWorldProgress(GenWorldProgress cls, uint progress, uint total)
01259 {
01260   static const int percent_table[] = {0, 5, 14, 17, 20, 40, 60, 65, 80, 85, 95, 99, 100 };
01261   assert_compile(lengthof(percent_table) == GWP_CLASS_COUNT + 1);
01262   assert(cls < GWP_CLASS_COUNT);
01263 
01264   /* Do not run this function if we aren't in a thread */
01265   if (!IsGenerateWorldThreaded() && !_network_dedicated) return;
01266 
01267   if (IsGeneratingWorldAborted()) HandleGeneratingWorldAbortion();
01268 
01269   if (total == 0) {
01270     assert(_gws.cls == _generation_class_table[cls]);
01271     _gws.current += progress;
01272     assert(_gws.current <= _gws.total);
01273   } else {
01274     _gws.cls     = _generation_class_table[cls];
01275     _gws.current = progress;
01276     _gws.total   = total;
01277     _gws.percent = percent_table[cls];
01278   }
01279 
01280   /* Don't update the screen too often. So update it once in every once in a while... */
01281   if (!_network_dedicated && _gws.timer != 0 && _realtime_tick - _gws.timer < MODAL_PROGRESS_REDRAW_TIMEOUT) return;
01282 
01283   /* Percentage is about the number of completed tasks, so 'current - 1' */
01284   _gws.percent = percent_table[cls] + (percent_table[cls + 1] - percent_table[cls]) * (_gws.current == 0 ? 0 : _gws.current - 1) / _gws.total;
01285 
01286   if (_network_dedicated) {
01287     static uint last_percent = 0;
01288 
01289     /* Never display 0% */
01290     if (_gws.percent == 0) return;
01291     /* Reset if percent is lower than the last recorded */
01292     if (_gws.percent < last_percent) last_percent = 0;
01293     /* Display every 5%, but 6% is also very valid.. just not smaller steps than 5% */
01294     if (_gws.percent % 5 != 0 && _gws.percent <= last_percent + 5) return;
01295     /* Never show steps smaller than 2%, even if it is a mod 5% */
01296     if (_gws.percent <= last_percent + 2) return;
01297 
01298     DEBUG(net, 1, "Map generation percentage complete: %d", _gws.percent);
01299     last_percent = _gws.percent;
01300 
01301     /* Don't continue as dedicated never has a thread running */
01302     return;
01303   }
01304 
01305   SetWindowDirty(WC_MODAL_PROGRESS, 0);
01306   MarkWholeScreenDirty();
01307 
01308   /* Release the rights to the map generator, and acquire the rights to the
01309    * paint thread. The 'other' thread already has the paint thread rights so
01310    * this ensures us that we are waiting until the paint thread is done
01311    * before we reacquire the mapgen rights */
01312   _modal_progress_work_mutex->EndCritical();
01313   _modal_progress_paint_mutex->BeginCritical();
01314   _modal_progress_work_mutex->BeginCritical();
01315   _modal_progress_paint_mutex->EndCritical();
01316 
01317   _gws.timer = _realtime_tick;
01318 }
01319 
01328 void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
01329 {
01330   if (total == 0) return;
01331 
01332   _SetGeneratingWorldProgress(cls, 0, total);
01333 }
01334 
01342 void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
01343 {
01344   /* In fact the param 'class' isn't needed.. but for some security reasons, we want it around */
01345   _SetGeneratingWorldProgress(cls, 1, 0);
01346 }