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_NULL), 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_NULL), 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_NULL), 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_WHITE, 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_PUSHTXTBTN, 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_TEXTBTN, 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_TEXTBTN, 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_TEXTBTN, 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_TEXTBTN, 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_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_WATER_NW), SetDataTip(STR_JUST_STRING, STR_MAPGEN_NORTHWEST), SetFill(1, 1),
00151       NWidget(WWT_PUSHTXTBTN, 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_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_WATER_SW), SetDataTip(STR_JUST_STRING, STR_MAPGEN_SOUTHWEST), SetFill(1, 1),
00163       NWidget(WWT_PUSHTXTBTN, 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_WHITE, 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_TEXTBTN, 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_TEXTBTN, 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_TEXTBTN, 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_TEXTBTN, 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   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 QueryStringBaseWindow {
00307   uint widget_id;
00308   uint x;
00309   uint y;
00310   char name[64];
00311   GenenerateLandscapeWindowMode mode;
00312 
00313   GenerateLandscapeWindow(const WindowDesc *desc, WindowNumber number = 0) : QueryStringBaseWindow(11)
00314   {
00315     this->InitNested(desc, number);
00316 
00317     this->LowerWidget(_settings_newgame.game_creation.landscape + WID_GL_TEMPERATE);
00318 
00319     /* snprintf() always outputs trailing '\0', so whole buffer can be used */
00320     snprintf(this->edit_str_buf, this->edit_str_size, "%u", _settings_newgame.game_creation.generation_seed);
00321     this->text.Initialize(this->edit_str_buf, this->edit_str_size);
00322     this->caption = STR_NULL;
00323     this->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         SetDParam(0, MAX_MAP_SIZE);
00453         *size = GetStringBoundingBox(STR_JUST_INT);
00454         break;
00455 
00456       case WID_GL_SNOW_LEVEL_TEXT:
00457         SetDParam(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         SetDParam(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         SetDParam(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 OnPaint()
00525   {
00526     this->DrawWidgets();
00527     this->DrawEditBox(WID_GL_RANDOM_EDITBOX);
00528   }
00529 
00530   virtual void OnClick(Point pt, int widget, int click_count)
00531   {
00532     switch (widget) {
00533       case WID_GL_TEMPERATE:
00534       case WID_GL_ARCTIC:
00535       case WID_GL_TROPICAL:
00536       case WID_GL_TOYLAND:
00537         SetNewLandscapeType(widget - WID_GL_TEMPERATE);
00538         break;
00539 
00540       case WID_GL_MAPSIZE_X_PULLDOWN: // Mapsize X
00541         ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_x, WID_GL_MAPSIZE_X_PULLDOWN);
00542         break;
00543 
00544       case WID_GL_MAPSIZE_Y_PULLDOWN: // Mapsize Y
00545         ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_y, WID_GL_MAPSIZE_Y_PULLDOWN);
00546         break;
00547 
00548       case WID_GL_TOWN_PULLDOWN: // Number of towns
00549         ShowDropDownMenu(this, _num_towns, _settings_newgame.difficulty.number_towns, WID_GL_TOWN_PULLDOWN, 0, 0);
00550         break;
00551 
00552       case WID_GL_INDUSTRY_PULLDOWN: // Number of industries
00553         ShowDropDownMenu(this, _num_inds, _settings_newgame.difficulty.industry_density, WID_GL_INDUSTRY_PULLDOWN, 0, 0);
00554         break;
00555 
00556       case WID_GL_RANDOM_BUTTON: // Random seed
00557         _settings_newgame.game_creation.generation_seed = InteractiveRandom();
00558         snprintf(this->edit_str_buf, this->edit_str_size, "%u", _settings_newgame.game_creation.generation_seed);
00559         this->text.UpdateSize();
00560         this->SetDirty();
00561         break;
00562 
00563       case WID_GL_GENERATE_BUTTON: { // Generate
00564         /* Get rotated map size. */
00565         uint map_x;
00566         uint map_y;
00567         if (_settings_newgame.game_creation.heightmap_rotation == HM_CLOCKWISE) {
00568           map_x = this->y;
00569           map_y = this->x;
00570         } else {
00571           map_x = this->x;
00572           map_y = this->y;
00573         }
00574         if (mode == GLWM_HEIGHTMAP &&
00575             (map_x * 2 < (1U << _settings_newgame.game_creation.map_x) ||
00576             map_x / 2 > (1U << _settings_newgame.game_creation.map_x) ||
00577             map_y * 2 < (1U << _settings_newgame.game_creation.map_y) ||
00578             map_y / 2 > (1U << _settings_newgame.game_creation.map_y))) {
00579           ShowQuery(
00580             STR_WARNING_HEIGHTMAP_SCALE_CAPTION,
00581             STR_WARNING_HEIGHTMAP_SCALE_MESSAGE,
00582             this,
00583             LandscapeGenerationCallback);
00584         } else {
00585           StartGeneratingLandscape(mode);
00586         }
00587         break;
00588       }
00589 
00590       case WID_GL_START_DATE_DOWN:
00591       case WID_GL_START_DATE_UP: // Year buttons
00592         /* Don't allow too fast scrolling */
00593         if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
00594           this->HandleButtonClick(widget);
00595 
00596           _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_GL_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
00597           this->InvalidateData();
00598         }
00599         _left_button_clicked = false;
00600         break;
00601 
00602       case WID_GL_START_DATE_TEXT: // Year text
00603         this->widget_id = WID_GL_START_DATE_TEXT;
00604         SetDParam(0, _settings_newgame.game_creation.starting_year);
00605         ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ENABLE_DEFAULT);
00606         break;
00607 
00608       case WID_GL_SNOW_LEVEL_DOWN:
00609       case WID_GL_SNOW_LEVEL_UP: // Snow line buttons
00610         /* Don't allow too fast scrolling */
00611         if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
00612           this->HandleButtonClick(widget);
00613 
00614           _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);
00615           this->InvalidateData();
00616         }
00617         _left_button_clicked = false;
00618         break;
00619 
00620       case WID_GL_SNOW_LEVEL_TEXT: // Snow line text
00621         this->widget_id = WID_GL_SNOW_LEVEL_TEXT;
00622         SetDParam(0, _settings_newgame.game_creation.snow_line_height);
00623         ShowQueryString(STR_JUST_INT, STR_MAPGEN_SNOW_LINE_QUERY_CAPT, 3, this, CS_NUMERAL, QSF_ENABLE_DEFAULT);
00624         break;
00625 
00626       case WID_GL_TREE_PULLDOWN: // Tree placer
00627         ShowDropDownMenu(this, _tree_placer, _settings_newgame.game_creation.tree_placer, WID_GL_TREE_PULLDOWN, 0, 0);
00628         break;
00629 
00630       case WID_GL_LANDSCAPE_PULLDOWN: // Landscape generator
00631         ShowDropDownMenu(this, _landscape, _settings_newgame.game_creation.land_generator, WID_GL_LANDSCAPE_PULLDOWN, 0, 0);
00632         break;
00633 
00634       case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: // Heightmap rotation
00635         ShowDropDownMenu(this, _rotation, _settings_newgame.game_creation.heightmap_rotation, WID_GL_HEIGHTMAP_ROTATION_PULLDOWN, 0, 0);
00636         break;
00637 
00638       case WID_GL_TERRAIN_PULLDOWN: // Terrain type
00639         ShowDropDownMenu(this, _elevations, _settings_newgame.difficulty.terrain_type, WID_GL_TERRAIN_PULLDOWN, 0, 0);
00640         break;
00641 
00642       case WID_GL_WATER_PULLDOWN: { // Water quantity
00643         uint32 hidden_mask = 0;
00644         /* Disable custom water level when the original map generator is active. */
00645         if (_settings_newgame.game_creation.land_generator == 0) {
00646           SetBit(hidden_mask, CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY);
00647         }
00648         ShowDropDownMenu(this, _sea_lakes, _settings_newgame.difficulty.quantity_sea_lakes, WID_GL_WATER_PULLDOWN, 0, hidden_mask);
00649         break;
00650       }
00651 
00652       case WID_GL_RIVER_PULLDOWN: // Amount of rivers
00653         ShowDropDownMenu(this, _rivers, _settings_newgame.game_creation.amount_of_rivers, WID_GL_RIVER_PULLDOWN, 0, 0);
00654         break;
00655 
00656       case WID_GL_SMOOTHNESS_PULLDOWN: // Map smoothness
00657         ShowDropDownMenu(this, _smoothness, _settings_newgame.game_creation.tgen_smoothness, WID_GL_SMOOTHNESS_PULLDOWN, 0, 0);
00658         break;
00659 
00660       case WID_GL_VARIETY_PULLDOWN: // Map variety
00661         ShowDropDownMenu(this, _variety, _settings_newgame.game_creation.variety, WID_GL_VARIETY_PULLDOWN, 0, 0);
00662         break;
00663 
00664       /* Freetype map borders */
00665       case WID_GL_WATER_NW:
00666         _settings_newgame.game_creation.water_borders = ToggleBit(_settings_newgame.game_creation.water_borders, BORDER_NW);
00667         this->InvalidateData();
00668         break;
00669 
00670       case WID_GL_WATER_NE:
00671         _settings_newgame.game_creation.water_borders = ToggleBit(_settings_newgame.game_creation.water_borders, BORDER_NE);
00672         this->InvalidateData();
00673         break;
00674 
00675       case WID_GL_WATER_SE:
00676         _settings_newgame.game_creation.water_borders = ToggleBit(_settings_newgame.game_creation.water_borders, BORDER_SE);
00677         this->InvalidateData();
00678         break;
00679 
00680       case WID_GL_WATER_SW:
00681         _settings_newgame.game_creation.water_borders = ToggleBit(_settings_newgame.game_creation.water_borders, BORDER_SW);
00682         this->InvalidateData();
00683         break;
00684 
00685       case WID_GL_BORDERS_RANDOM:
00686         _settings_newgame.game_creation.water_borders = (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? 0 : BORDERS_RANDOM;
00687         this->InvalidateData();
00688         break;
00689     }
00690   }
00691 
00692   virtual void OnTimeout()
00693   {
00694     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};
00695     for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) {
00696       if (this->IsWidgetLowered(*widget)) {
00697         this->RaiseWidget(*widget);
00698         this->SetWidgetDirty(*widget);
00699       }
00700     }
00701   }
00702 
00703   virtual void OnMouseLoop()
00704   {
00705     this->HandleEditBox(WID_GL_RANDOM_EDITBOX);
00706   }
00707 
00708   virtual EventState OnKeyPress(uint16 key, uint16 keycode)
00709   {
00710     EventState state = ES_NOT_HANDLED;
00711     this->HandleEditBoxKey(WID_GL_RANDOM_EDITBOX, key, keycode, state);
00712     /* the seed is unsigned, therefore atoi cannot be used.
00713      * As UINT32_MAX is a 'magic' value (use random seed) it
00714      * should not be possible to be entered into the input
00715      * field; the generate seed button can be used instead. */
00716     _settings_newgame.game_creation.generation_seed = minu(strtoul(this->edit_str_buf, NULL, 10), UINT32_MAX - 1);
00717     return state;
00718   }
00719 
00720   virtual void OnDropdownSelect(int widget, int index)
00721   {
00722     switch (widget) {
00723       case WID_GL_MAPSIZE_X_PULLDOWN:     _settings_newgame.game_creation.map_x = index; break;
00724       case WID_GL_MAPSIZE_Y_PULLDOWN:     _settings_newgame.game_creation.map_y = index; break;
00725       case WID_GL_TREE_PULLDOWN:          _settings_newgame.game_creation.tree_placer = index; break;
00726       case WID_GL_RIVER_PULLDOWN:         _settings_newgame.game_creation.amount_of_rivers = index; break;
00727       case WID_GL_SMOOTHNESS_PULLDOWN:    _settings_newgame.game_creation.tgen_smoothness = index;  break;
00728       case WID_GL_VARIETY_PULLDOWN:       _settings_newgame.game_creation.variety = index; break;
00729       case WID_GL_LANDSCAPE_PULLDOWN:     _settings_newgame.game_creation.land_generator = index; break;
00730       case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: _settings_newgame.game_creation.heightmap_rotation = index; break;
00731 
00732       case WID_GL_TOWN_PULLDOWN:
00733         if ((uint)index == CUSTOM_TOWN_NUMBER_DIFFICULTY) {
00734           this->widget_id = widget;
00735           SetDParam(0, _settings_newgame.game_creation.custom_town_number);
00736           ShowQueryString(STR_JUST_INT, STR_MAPGEN_NUMBER_OF_TOWNS, 5, this, CS_NUMERAL, QSF_NONE);
00737         }
00738         IConsoleSetSetting("difficulty.number_towns", index);
00739         break;
00740 
00741       case WID_GL_INDUSTRY_PULLDOWN:
00742         IConsoleSetSetting("difficulty.industry_density", index);
00743         break;
00744 
00745       case WID_GL_TERRAIN_PULLDOWN: {
00746         GameMode old_gm = _game_mode;
00747         _game_mode = GM_MENU;
00748         IConsoleSetSetting("difficulty.terrain_type", index);
00749         _game_mode = old_gm;
00750         break;
00751       }
00752 
00753       case WID_GL_WATER_PULLDOWN: {
00754         if ((uint)index == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) {
00755           this->widget_id = widget;
00756           SetDParam(0, _settings_newgame.game_creation.custom_sea_level);
00757           ShowQueryString(STR_JUST_INT, STR_MAPGEN_QUANTITY_OF_SEA_LAKES, 3, this, CS_NUMERAL, QSF_NONE);
00758         }
00759         GameMode old_gm = _game_mode;
00760         _game_mode = GM_MENU;
00761         IConsoleSetSetting("difficulty.quantity_sea_lakes", index);
00762         _game_mode = old_gm;
00763         break;
00764       }
00765     }
00766     this->InvalidateData();
00767   }
00768 
00769   virtual void OnQueryTextFinished(char *str)
00770   {
00771     /* Was 'cancel' pressed? */
00772     if (str == NULL) return;
00773 
00774     int32 value;
00775     if (!StrEmpty(str)) {
00776       value = atoi(str);
00777     } else {
00778       /* An empty string means revert to the default */
00779       switch (this->widget_id) {
00780         case WID_GL_START_DATE_TEXT: value = DEF_START_YEAR; break;
00781         case WID_GL_SNOW_LEVEL_TEXT: value = DEF_SNOWLINE_HEIGHT; break;
00782         case WID_GL_TOWN_PULLDOWN:   value = 1; break;
00783         case WID_GL_WATER_PULLDOWN:  value = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE; break;
00784         default: NOT_REACHED();
00785       }
00786     }
00787 
00788     switch (this->widget_id) {
00789       case WID_GL_START_DATE_TEXT:
00790         this->SetWidgetDirty(WID_GL_START_DATE_TEXT);
00791         _settings_newgame.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
00792         break;
00793 
00794       case WID_GL_SNOW_LEVEL_TEXT:
00795         this->SetWidgetDirty(WID_GL_SNOW_LEVEL_TEXT);
00796         _settings_newgame.game_creation.snow_line_height = Clamp(value, MIN_SNOWLINE_HEIGHT, MAX_SNOWLINE_HEIGHT);
00797         break;
00798 
00799       case WID_GL_TOWN_PULLDOWN:
00800         _settings_newgame.game_creation.custom_town_number = Clamp(value, 1, CUSTOM_TOWN_MAX_NUMBER);
00801         break;
00802 
00803       case WID_GL_WATER_PULLDOWN:
00804         _settings_newgame.game_creation.custom_sea_level = Clamp(value, CUSTOM_SEA_LEVEL_MIN_PERCENTAGE, CUSTOM_SEA_LEVEL_MAX_PERCENTAGE);
00805         break;
00806     }
00807 
00808     this->InvalidateData();
00809   }
00810 };
00811 
00812 static const WindowDesc _generate_landscape_desc(
00813   WDP_CENTER, 0, 0,
00814   WC_GENERATE_LANDSCAPE, WC_NONE,
00815   0,
00816   _nested_generate_landscape_widgets, lengthof(_nested_generate_landscape_widgets)
00817 );
00818 
00819 static const WindowDesc _heightmap_load_desc(
00820   WDP_CENTER, 0, 0,
00821   WC_GENERATE_LANDSCAPE, WC_NONE,
00822   0,
00823   _nested_heightmap_load_widgets, lengthof(_nested_heightmap_load_widgets)
00824 );
00825 
00826 static void _ShowGenerateLandscape(GenenerateLandscapeWindowMode mode)
00827 {
00828   uint x = 0;
00829   uint y = 0;
00830 
00831   DeleteWindowByClass(WC_GENERATE_LANDSCAPE);
00832 
00833   /* Always give a new seed if not editor */
00834   if (_game_mode != GM_EDITOR) _settings_newgame.game_creation.generation_seed = InteractiveRandom();
00835 
00836   if (mode == GLWM_HEIGHTMAP) {
00837     /* If the function returns negative, it means there was a problem loading the heightmap */
00838     if (!GetHeightmapDimensions(_file_to_saveload.name, &x, &y)) return;
00839   }
00840 
00841   GenerateLandscapeWindow *w = AllocateWindowDescFront<GenerateLandscapeWindow>((mode == GLWM_HEIGHTMAP) ? &_heightmap_load_desc : &_generate_landscape_desc, mode);
00842 
00843   if (mode == GLWM_HEIGHTMAP) {
00844     w->x = x;
00845     w->y = y;
00846     strecpy(w->name, _file_to_saveload.title, lastof(w->name));
00847   }
00848 
00849   SetWindowDirty(WC_GENERATE_LANDSCAPE, mode);
00850 }
00851 
00853 void ShowGenerateLandscape()
00854 {
00855   _ShowGenerateLandscape(GLWM_GENERATE);
00856 }
00857 
00859 void ShowHeightmapLoad()
00860 {
00861   _ShowGenerateLandscape(GLWM_HEIGHTMAP);
00862 }
00863 
00865 void StartScenarioEditor()
00866 {
00867   StartGeneratingLandscape(GLWM_SCENARIO);
00868 }
00869 
00874 void StartNewGameWithoutGUI(uint seed)
00875 {
00876   /* GenerateWorld takes care of the possible GENERATE_NEW_SEED value in 'seed' */
00877   _settings_newgame.game_creation.generation_seed = seed;
00878 
00879   StartGeneratingLandscape(GLWM_GENERATE);
00880 }
00881 
00882 struct CreateScenarioWindow : public Window
00883 {
00884   uint widget_id;
00885 
00886   CreateScenarioWindow(const WindowDesc *desc, WindowNumber window_number) : Window()
00887   {
00888     this->InitNested(desc, window_number);
00889     this->LowerWidget(_settings_newgame.game_creation.landscape + WID_CS_TEMPERATE);
00890   }
00891 
00892   virtual void SetStringParameters(int widget) const
00893   {
00894     switch (widget) {
00895       case WID_CS_START_DATE_TEXT:
00896         SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1));
00897         break;
00898 
00899       case WID_CS_MAPSIZE_X_PULLDOWN:
00900         SetDParam(0, 1 << _settings_newgame.game_creation.map_x);
00901         break;
00902 
00903       case WID_CS_MAPSIZE_Y_PULLDOWN:
00904         SetDParam(0, 1 << _settings_newgame.game_creation.map_y);
00905         break;
00906 
00907       case WID_CS_FLAT_LAND_HEIGHT_TEXT:
00908         SetDParam(0, _settings_newgame.game_creation.se_flat_world_height);
00909         break;
00910     }
00911   }
00912 
00913   virtual void OnPaint()
00914   {
00915     this->SetWidgetDisabledState(WID_CS_START_DATE_DOWN,       _settings_newgame.game_creation.starting_year <= MIN_YEAR);
00916     this->SetWidgetDisabledState(WID_CS_START_DATE_UP,         _settings_newgame.game_creation.starting_year >= MAX_YEAR);
00917     this->SetWidgetDisabledState(WID_CS_FLAT_LAND_HEIGHT_DOWN, _settings_newgame.game_creation.se_flat_world_height <= 0);
00918     this->SetWidgetDisabledState(WID_CS_FLAT_LAND_HEIGHT_UP,   _settings_newgame.game_creation.se_flat_world_height >= MAX_TILE_HEIGHT);
00919 
00920     this->SetWidgetLoweredState(WID_CS_TEMPERATE, _settings_newgame.game_creation.landscape == LT_TEMPERATE);
00921     this->SetWidgetLoweredState(WID_CS_ARCTIC,    _settings_newgame.game_creation.landscape == LT_ARCTIC);
00922     this->SetWidgetLoweredState(WID_CS_TROPICAL,  _settings_newgame.game_creation.landscape == LT_TROPIC);
00923     this->SetWidgetLoweredState(WID_CS_TOYLAND,   _settings_newgame.game_creation.landscape == LT_TOYLAND);
00924 
00925     this->DrawWidgets();
00926   }
00927 
00928   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
00929   {
00930     StringID str = STR_JUST_INT;
00931     switch (widget) {
00932       case WID_CS_START_DATE_TEXT:
00933         SetDParam(0, ConvertYMDToDate(MAX_YEAR, 0, 1));
00934         str = STR_BLACK_DATE_LONG;
00935         break;
00936 
00937       case WID_CS_MAPSIZE_X_PULLDOWN:
00938       case WID_CS_MAPSIZE_Y_PULLDOWN:
00939         SetDParam(0, MAX_MAP_SIZE);
00940         break;
00941 
00942       case WID_CS_FLAT_LAND_HEIGHT_TEXT:
00943         SetDParam(0, MAX_TILE_HEIGHT);
00944         break;
00945 
00946       default:
00947         return;
00948     }
00949     *size = GetStringBoundingBox(str);
00950     size->width += padding.width;
00951     size->height += padding.height;
00952   }
00953 
00954   virtual void OnClick(Point pt, int widget, int click_count)
00955   {
00956     switch (widget) {
00957       case WID_CS_TEMPERATE:
00958       case WID_CS_ARCTIC:
00959       case WID_CS_TROPICAL:
00960       case WID_CS_TOYLAND:
00961         this->RaiseWidget(_settings_newgame.game_creation.landscape + WID_CS_TEMPERATE);
00962         SetNewLandscapeType(widget - WID_CS_TEMPERATE);
00963         break;
00964 
00965       case WID_CS_MAPSIZE_X_PULLDOWN: // Mapsize X
00966         ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_x, WID_CS_MAPSIZE_X_PULLDOWN);
00967         break;
00968 
00969       case WID_CS_MAPSIZE_Y_PULLDOWN: // Mapsize Y
00970         ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_y, WID_CS_MAPSIZE_Y_PULLDOWN);
00971         break;
00972 
00973       case WID_CS_EMPTY_WORLD: // Empty world / flat world
00974         StartGeneratingLandscape(GLWM_SCENARIO);
00975         break;
00976 
00977       case WID_CS_RANDOM_WORLD: // Generate
00978         ShowGenerateLandscape();
00979         break;
00980 
00981       case WID_CS_START_DATE_DOWN:
00982       case WID_CS_START_DATE_UP: // Year buttons
00983         /* Don't allow too fast scrolling */
00984         if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
00985           this->HandleButtonClick(widget);
00986           this->SetDirty();
00987 
00988           _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_CS_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
00989         }
00990         _left_button_clicked = false;
00991         break;
00992 
00993       case WID_CS_START_DATE_TEXT: // Year text
00994         this->widget_id = WID_CS_START_DATE_TEXT;
00995         SetDParam(0, _settings_newgame.game_creation.starting_year);
00996         ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_NONE);
00997         break;
00998 
00999       case WID_CS_FLAT_LAND_HEIGHT_DOWN:
01000       case WID_CS_FLAT_LAND_HEIGHT_UP: // Height level buttons
01001         /* Don't allow too fast scrolling */
01002         if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
01003           this->HandleButtonClick(widget);
01004           this->SetDirty();
01005 
01006           _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);
01007         }
01008         _left_button_clicked = false;
01009         break;
01010 
01011       case WID_CS_FLAT_LAND_HEIGHT_TEXT: // Height level text
01012         this->widget_id = WID_CS_FLAT_LAND_HEIGHT_TEXT;
01013         SetDParam(0, _settings_newgame.game_creation.se_flat_world_height);
01014         ShowQueryString(STR_JUST_INT, STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_QUERY_CAPT, 3, this, CS_NUMERAL, QSF_NONE);
01015         break;
01016     }
01017   }
01018 
01019   virtual void OnTimeout()
01020   {
01021     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};
01022     for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) {
01023       if (this->IsWidgetLowered(*widget)) {
01024         this->RaiseWidget(*widget);
01025         this->SetWidgetDirty(*widget);
01026       }
01027     }
01028   }
01029 
01030   virtual void OnDropdownSelect(int widget, int index)
01031   {
01032     switch (widget) {
01033       case WID_CS_MAPSIZE_X_PULLDOWN: _settings_newgame.game_creation.map_x = index; break;
01034       case WID_CS_MAPSIZE_Y_PULLDOWN: _settings_newgame.game_creation.map_y = index; break;
01035     }
01036     this->SetDirty();
01037   }
01038 
01039   virtual void OnQueryTextFinished(char *str)
01040   {
01041     if (!StrEmpty(str)) {
01042       int32 value = atoi(str);
01043 
01044       switch (this->widget_id) {
01045         case WID_CS_START_DATE_TEXT:
01046           this->SetWidgetDirty(WID_CS_START_DATE_TEXT);
01047           _settings_newgame.game_creation.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
01048           break;
01049 
01050         case WID_CS_FLAT_LAND_HEIGHT_TEXT:
01051           this->SetWidgetDirty(WID_CS_FLAT_LAND_HEIGHT_TEXT);
01052           _settings_newgame.game_creation.se_flat_world_height = Clamp(value, 0, MAX_TILE_HEIGHT);
01053           break;
01054       }
01055 
01056       this->SetDirty();
01057     }
01058   }
01059 };
01060 
01061 static const NWidgetPart _nested_create_scenario_widgets[] = {
01062   NWidget(NWID_HORIZONTAL),
01063     NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
01064     NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_SE_MAPGEN_CAPTION, STR_NULL),
01065   EndContainer(),
01066   NWidget(WWT_PANEL, COLOUR_BROWN),
01067     NWidget(NWID_SPACER), SetMinimalSize(0, 10),
01068     /* Landscape style selection. */
01069     NWidget(NWID_HORIZONTAL), SetPIP(10, 3, 10),
01070       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
01071       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
01072       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
01073       NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
01074     EndContainer(),
01075     NWidget(NWID_HORIZONTAL), SetPIP(10, 8, 10),
01076       /* Green generation type buttons: 'Flat land' and 'Random land'. */
01077       NWidget(NWID_VERTICAL), SetPIP(10, 6, 10),
01078         NWidget(WWT_TEXTBTN, COLOUR_GREEN, WID_CS_EMPTY_WORLD), SetDataTip(STR_SE_MAPGEN_FLAT_WORLD, STR_SE_MAPGEN_FLAT_WORLD_TOOLTIP), SetFill(1, 1),
01079         NWidget(WWT_TEXTBTN, COLOUR_GREEN, WID_CS_RANDOM_WORLD), SetDataTip(STR_SE_MAPGEN_RANDOM_LAND, STR_TERRAFORM_TOOLTIP_GENERATE_RANDOM_LAND), SetFill(1, 1),
01080       EndContainer(),
01081       /* Labels + setting drop-downs */
01082       NWidget(NWID_VERTICAL), SetPIP(10, 6, 10),
01083         /* Map size. */
01084         NWidget(NWID_HORIZONTAL),
01085           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_NULL), SetPadding(1, 0, 0, 0),
01086           NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0),
01087           NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_CS_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetPadding(0, 4, 0, 0),
01088           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 2, 0, 0),
01089           NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_CS_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL),
01090         EndContainer(),
01091         /* Date. */
01092         NWidget(NWID_HORIZONTAL),
01093           NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetPadding(1, 0, 0, 0),
01094           NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0),
01095           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),
01096           NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_CS_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL),
01097           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),
01098         EndContainer(),
01099         /* Flat map height. */
01100         NWidget(NWID_HORIZONTAL),
01101           NWidget(WWT_TEXT, COLOUR_ORANGE),
01102                         SetDataTip(STR_SE_MAPGEN_FLAT_WORLD_HEIGHT, STR_NULL), SetPadding(1, 0, 0, 0),
01103           NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0),
01104           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),
01105           NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_CS_FLAT_LAND_HEIGHT_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL),
01106           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),
01107         EndContainer(),
01108       EndContainer(),
01109     EndContainer(),
01110   EndContainer(),
01111 };
01112 
01113 static const WindowDesc _create_scenario_desc(
01114   WDP_CENTER, 0, 0,
01115   WC_GENERATE_LANDSCAPE, WC_NONE,
01116   WDF_UNCLICK_BUTTONS,
01117   _nested_create_scenario_widgets, lengthof(_nested_create_scenario_widgets)
01118 );
01119 
01121 void ShowCreateScenario()
01122 {
01123   DeleteWindowByClass(WC_GENERATE_LANDSCAPE);
01124   new CreateScenarioWindow(&_create_scenario_desc, GLWM_SCENARIO);
01125 }
01126 
01127 static const NWidgetPart _nested_generate_progress_widgets[] = {
01128   NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_GENERATION_WORLD, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
01129   NWidget(WWT_PANEL, COLOUR_GREY),
01130     NWidget(NWID_HORIZONTAL), SetPIP(20, 0, 20),
01131       NWidget(NWID_VERTICAL), SetPIP(11, 8, 11),
01132         NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_BAR), SetFill(1, 0),
01133         NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_TEXT), SetFill(1, 0),
01134         NWidget(WWT_TEXTBTN, COLOUR_WHITE, WID_GP_ABORT), SetDataTip(STR_GENERATION_ABORT, STR_NULL), SetFill(1, 0),
01135       EndContainer(),
01136     EndContainer(),
01137   EndContainer(),
01138 };
01139 
01140 
01141 static const WindowDesc _generate_progress_desc(
01142   WDP_CENTER, 0, 0,
01143   WC_MODAL_PROGRESS, WC_NONE,
01144   WDF_UNCLICK_BUTTONS,
01145   _nested_generate_progress_widgets, lengthof(_nested_generate_progress_widgets)
01146 );
01147 
01148 struct GenWorldStatus {
01149   uint percent;
01150   StringID cls;
01151   uint current;
01152   uint total;
01153   int timer;
01154 };
01155 
01156 static GenWorldStatus _gws;
01157 
01158 static const StringID _generation_class_table[]  = {
01159   STR_GENERATION_WORLD_GENERATION,
01160   STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION,
01161   STR_GENERATION_RIVER_GENERATION,
01162   STR_GENERATION_CLEARING_TILES,
01163   STR_SCENEDIT_TOOLBAR_TOWN_GENERATION,
01164   STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION,
01165   STR_GENERATION_OBJECT_GENERATION,
01166   STR_GENERATION_TREE_GENERATION,
01167   STR_GENERATION_SETTINGUP_GAME,
01168   STR_GENERATION_PREPARING_TILELOOP,
01169   STR_GENERATION_PREPARING_SCRIPT,
01170   STR_GENERATION_PREPARING_GAME
01171 };
01172 assert_compile(lengthof(_generation_class_table) == GWP_CLASS_COUNT);
01173 
01174 
01175 static void AbortGeneratingWorldCallback(Window *w, bool confirmed)
01176 {
01177   if (confirmed) {
01178     AbortGeneratingWorld();
01179   } else if (HasModalProgress() && !IsGeneratingWorldAborted()) {
01180     SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
01181   }
01182 }
01183 
01184 struct GenerateProgressWindow : public Window {
01185 
01186   GenerateProgressWindow() : Window()
01187   {
01188     this->InitNested(&_generate_progress_desc);
01189   }
01190 
01191   virtual void OnClick(Point pt, int widget, int click_count)
01192   {
01193     switch (widget) {
01194       case WID_GP_ABORT:
01195         if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
01196         ShowQuery(
01197           STR_GENERATION_ABORT_CAPTION,
01198           STR_GENERATION_ABORT_MESSAGE,
01199           this,
01200           AbortGeneratingWorldCallback
01201         );
01202         break;
01203     }
01204   }
01205 
01206   virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
01207   {
01208     switch (widget) {
01209       case WID_GP_PROGRESS_BAR: {
01210         SetDParam(0, 100);
01211         *size = GetStringBoundingBox(STR_GENERATION_PROGRESS);
01212         /* We need some spacing for the 'border' */
01213         size->height += 8;
01214         size->width += 8;
01215         break;
01216       }
01217 
01218       case WID_GP_PROGRESS_TEXT:
01219         for (uint i = 0; i < GWP_CLASS_COUNT; i++) {
01220           size->width = max(size->width, GetStringBoundingBox(_generation_class_table[i]).width);
01221         }
01222         size->height = FONT_HEIGHT_NORMAL * 2 + WD_PAR_VSEP_NORMAL;
01223         break;
01224     }
01225   }
01226 
01227   virtual void DrawWidget(const Rect &r, int widget) const
01228   {
01229     switch (widget) {
01230       case WID_GP_PROGRESS_BAR:
01231         /* Draw the % complete with a bar and a text */
01232         DrawFrameRect(r.left, r.top, r.right, r.bottom, COLOUR_GREY, FR_BORDERONLY);
01233         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);
01234         SetDParam(0, _gws.percent);
01235         DrawString(r.left, r.right, r.top + 5, STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER);
01236         break;
01237 
01238       case WID_GP_PROGRESS_TEXT:
01239         /* Tell which class we are generating */
01240         DrawString(r.left, r.right, r.top, _gws.cls, TC_FROMSTRING, SA_HOR_CENTER);
01241 
01242         /* And say where we are in that class */
01243         SetDParam(0, _gws.current);
01244         SetDParam(1, _gws.total);
01245         DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL, STR_GENERATION_PROGRESS_NUM, TC_FROMSTRING, SA_HOR_CENTER);
01246     }
01247   }
01248 };
01249 
01253 void PrepareGenerateWorldProgress()
01254 {
01255   _gws.cls     = STR_GENERATION_WORLD_GENERATION;
01256   _gws.current = 0;
01257   _gws.total   = 0;
01258   _gws.percent = 0;
01259   _gws.timer   = 0; // Forces to paint the progress window immediately
01260 }
01261 
01265 void ShowGenerateWorldProgress()
01266 {
01267   if (BringWindowToFrontById(WC_MODAL_PROGRESS, 0)) return;
01268   new GenerateProgressWindow();
01269 }
01270 
01271 static void _SetGeneratingWorldProgress(GenWorldProgress cls, uint progress, uint total)
01272 {
01273   static const int percent_table[] = {0, 5, 14, 17, 20, 40, 60, 65, 80, 85, 95, 99, 100 };
01274   assert_compile(lengthof(percent_table) == GWP_CLASS_COUNT + 1);
01275   assert(cls < GWP_CLASS_COUNT);
01276 
01277   /* Do not run this function if we aren't in a thread */
01278   if (!IsGenerateWorldThreaded() && !_network_dedicated) return;
01279 
01280   if (IsGeneratingWorldAborted()) HandleGeneratingWorldAbortion();
01281 
01282   if (total == 0) {
01283     assert(_gws.cls == _generation_class_table[cls]);
01284     _gws.current += progress;
01285     assert(_gws.current <= _gws.total);
01286   } else {
01287     _gws.cls     = _generation_class_table[cls];
01288     _gws.current = progress;
01289     _gws.total   = total;
01290     _gws.percent = percent_table[cls];
01291   }
01292 
01293   /* Don't update the screen too often. So update it once in every once in a while... */
01294   if (!_network_dedicated && _gws.timer != 0 && _realtime_tick - _gws.timer < MODAL_PROGRESS_REDRAW_TIMEOUT) return;
01295 
01296   /* Percentage is about the number of completed tasks, so 'current - 1' */
01297   _gws.percent = percent_table[cls] + (percent_table[cls + 1] - percent_table[cls]) * (_gws.current == 0 ? 0 : _gws.current - 1) / _gws.total;
01298 
01299   if (_network_dedicated) {
01300     static uint last_percent = 0;
01301 
01302     /* Never display 0% */
01303     if (_gws.percent == 0) return;
01304     /* Reset if percent is lower than the last recorded */
01305     if (_gws.percent < last_percent) last_percent = 0;
01306     /* Display every 5%, but 6% is also very valid.. just not smaller steps than 5% */
01307     if (_gws.percent % 5 != 0 && _gws.percent <= last_percent + 5) return;
01308     /* Never show steps smaller than 2%, even if it is a mod 5% */
01309     if (_gws.percent <= last_percent + 2) return;
01310 
01311     DEBUG(net, 1, "Map generation percentage complete: %d", _gws.percent);
01312     last_percent = _gws.percent;
01313 
01314     /* Don't continue as dedicated never has a thread running */
01315     return;
01316   }
01317 
01318   SetWindowDirty(WC_MODAL_PROGRESS, 0);
01319   MarkWholeScreenDirty();
01320 
01321   /* Release the rights to the map generator, and acquire the rights to the
01322    * paint thread. The 'other' thread already has the paint thread rights so
01323    * this ensures us that we are waiting until the paint thread is done
01324    * before we reacquire the mapgen rights */
01325   _modal_progress_work_mutex->EndCritical();
01326   _modal_progress_paint_mutex->BeginCritical();
01327   _modal_progress_work_mutex->BeginCritical();
01328   _modal_progress_paint_mutex->EndCritical();
01329 
01330   _gws.timer = _realtime_tick;
01331 }
01332 
01341 void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
01342 {
01343   if (total == 0) return;
01344 
01345   _SetGeneratingWorldProgress(cls, 0, total);
01346 }
01347 
01355 void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
01356 {
01357   /* In fact the param 'class' isn't needed.. but for some security reasons, we want it around */
01358   _SetGeneratingWorldProgress(cls, 1, 0);
01359 }