OpenTTD
genworld_gui.cpp
Go to the documentation of this file.
1 /* $Id: genworld_gui.cpp 27085 2014-12-18 18:20:59Z alberth $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8  */
9 
12 #include "stdafx.h"
13 #include "heightmap.h"
14 #include "debug.h"
15 #include "genworld.h"
16 #include "network/network.h"
17 #include "strings_func.h"
18 #include "window_func.h"
19 #include "date_func.h"
20 #include "sound_func.h"
21 #include "fios.h"
22 #include "string_func.h"
23 #include "widgets/dropdown_type.h"
24 #include "widgets/dropdown_func.h"
25 #include "querystring_gui.h"
26 #include "town.h"
27 #include "core/geometry_func.hpp"
28 #include "core/random_func.hpp"
29 #include "progress.h"
30 #include "error.h"
31 
33 
34 #include "safeguards.h"
35 
36 
37 extern void MakeNewgameSettingsLive();
38 
44 };
45 
50 void SetNewLandscapeType(byte landscape)
51 {
55 }
56 
60  NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
61  NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_MAPGEN_WORLD_GENERATION_CAPTION, STR_NULL),
62  EndContainer(),
63  NWidget(WWT_PANEL, COLOUR_BROWN),
65  /* Landscape selection. */
66  NWidget(NWID_HORIZONTAL), SetPIP(10, 0, 10),
67  NWidget(NWID_SPACER), SetFill(1, 0),
68  NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
69  NWidget(NWID_SPACER), SetFill(1, 0),
70  NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
71  NWidget(NWID_SPACER), SetFill(1, 0),
72  NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
73  NWidget(NWID_SPACER), SetFill(1, 0),
74  NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
75  NWidget(NWID_SPACER), SetFill(1, 0),
76  EndContainer(),
78  NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10),
79  NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
80  /* Left column with labels. */
82  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
83  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_LAND_GENERATOR, STR_NULL), SetFill(1, 1),
84  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1),
85  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TERRAIN_TYPE, STR_NULL), SetFill(1, 1),
86  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_VARIETY, STR_NULL), SetFill(1, 1),
87  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_SEA_LAKES, STR_NULL), SetFill(1, 1),
88  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TREE_PLACER, STR_NULL), SetFill(1, 1),
89  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BORDER_TYPE, STR_NULL), SetFill(1, 1),
90  EndContainer(),
91  /* Widgets at the right of the labels. */
93  /* Mapsize X * Y. */
94  NWidget(NWID_HORIZONTAL), SetPIP(0, 4, 0),
95  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0),
96  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(1, 1),
97  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0),
98  EndContainer(),
99  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_LANDSCAPE_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
100  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
101  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TERRAIN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
102  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_VARIETY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
103  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_WATER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
104  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TREE_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
105  NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_BORDERS_RANDOM), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
106  EndContainer(),
107  EndContainer(),
108  NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
109  NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
111  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAX_HEIGHTLEVEL, STR_NULL), SetFill(1, 1),
112  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SNOW_LINE_HEIGHT, STR_NULL), SetFill(1, 1),
113  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetFill(1, 1),
114  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1),
115  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SMOOTHNESS, STR_NULL), SetFill(1, 1),
116  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1),
117  EndContainer(),
119  /* Max. heightlevel. */
121  NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_MAX_HEIGHTLEVEL_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_MAX_HEIGHTLEVEL_DOWN), SetFill(0, 1),
122  NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_MAX_HEIGHTLEVEL_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0),
123  NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_MAX_HEIGHTLEVEL_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_MAX_HEIGHTLEVEL_UP), SetFill(0, 1),
124  EndContainer(),
125  /* Snow line. */
127  NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_LEVEL_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_SNOW_LINE_DOWN), SetFill(0, 1),
128  NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_SNOW_LEVEL_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0),
129  NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_LEVEL_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_SNOW_LINE_UP), SetFill(0, 1),
130  EndContainer(),
131  /* Starting date. */
133  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),
134  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL), SetFill(1, 0),
135  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),
136  EndContainer(),
137  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
138  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_SMOOTHNESS_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
139  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
140  EndContainer(),
141  EndContainer(),
142  NWidget(NWID_SPACER), SetFill(1, 1),
143  NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 30), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetFill(1, 0),
144  EndContainer(),
145  EndContainer(),
147  /* Map borders buttons for each edge. */
149  NWidget(NWID_HORIZONTAL), SetPIP(0, 0, 3),
150  NWidget(NWID_SPACER), SetFill(1, 1),
151  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NORTHWEST, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(0, 1),
152  EndContainer(),
153  NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_NW), SetDataTip(STR_JUST_STRING, STR_MAPGEN_NORTHWEST), SetFill(1, 1),
154  NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_NE), SetDataTip(STR_JUST_STRING, STR_MAPGEN_NORTHEAST), SetFill(1, 1),
155  NWidget(NWID_HORIZONTAL), SetPIP(3, 0, 0),
156  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NORTHEAST, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(0, 1),
157  NWidget(NWID_SPACER), SetFill(1, 1),
158  EndContainer(),
159  EndContainer(),
161  NWidget(NWID_HORIZONTAL), SetPIP(0, 0, 3),
162  NWidget(NWID_SPACER), SetFill(1, 1),
163  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SOUTHWEST, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(0, 1),
164  EndContainer(),
165  NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_SW), SetDataTip(STR_JUST_STRING, STR_MAPGEN_SOUTHWEST), SetFill(1, 1),
166  NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_SE), SetDataTip(STR_JUST_STRING, STR_MAPGEN_SOUTHEAST), SetFill(1, 1),
167  NWidget(NWID_HORIZONTAL), SetPIP(3, 0, 0),
168  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SOUTHEAST, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(0, 1),
169  NWidget(NWID_SPACER), SetFill(1, 1),
170  EndContainer(),
171  EndContainer(),
172  NWidget(NWID_SPACER), SetMinimalSize(0, 9), SetFill(1, 1),
173  EndContainer(),
174 };
175 
178  /* Window header. */
180  NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
181  NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_MAPGEN_WORLD_GENERATION_CAPTION, STR_NULL),
182  EndContainer(),
183  NWidget(WWT_PANEL, COLOUR_BROWN),
185  /* Landscape selection. */
186  NWidget(NWID_HORIZONTAL), SetPIP(10, 0, 10),
187  NWidget(NWID_SPACER), SetFill(1, 0),
188  NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
189  NWidget(NWID_SPACER), SetFill(1, 0),
190  NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
191  NWidget(NWID_SPACER), SetFill(1, 0),
192  NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
193  NWidget(NWID_SPACER), SetFill(1, 0),
194  NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
195  NWidget(NWID_SPACER), SetFill(1, 0),
196  EndContainer(),
197  NWidget(NWID_SPACER), SetMinimalSize(0, 11), SetFill(0, 1),
198  NWidget(NWID_HORIZONTAL), SetPIP(10, 3, 10),
199  /* Labels at the left side. */
201  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_NAME, STR_NULL), SetFill(1, 1),
202  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_NULL), SetFill(1, 1),
203  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_ROTATION, STR_NULL), SetFill(1, 1),
204  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1),
205  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1),
206  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1),
207  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TREE_PLACER, STR_NULL), SetFill(1, 1),
208  EndContainer(),
209  /* Widgets at the right of the labels. */
210  NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
211  NWidget(WWT_EMPTY, COLOUR_ORANGE, WID_GL_HEIGHTMAP_NAME_TEXT), SetFill(1, 0),
212  NWidget(NWID_HORIZONTAL), SetPIP(0, 5, 0),
214  /* Mapsize X * Y. */
215  NWidget(NWID_HORIZONTAL), SetPIP(0, 4, 0),
216  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetFill(1, 0),
217  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(1, 1),
218  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetFill(1, 0),
219  EndContainer(),
220  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_ROTATION_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
221  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
222  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
223  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
224  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TREE_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
225  EndContainer(),
226  NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
227  NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
229  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_SIZE_LABEL, STR_NULL), SetFill(1, 1),
230  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SNOW_LINE_HEIGHT, STR_NULL), SetFill(1, 1),
231  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAX_HEIGHTLEVEL, STR_NULL), SetFill(1, 1),
232  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetFill(1, 1),
233  EndContainer(),
235  NWidget(WWT_TEXT, COLOUR_ORANGE, WID_GL_HEIGHTMAP_SIZE_TEXT), SetDataTip(STR_MAPGEN_HEIGHTMAP_SIZE, STR_NULL), SetFill(1, 0),
237  NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_LEVEL_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_SNOW_LINE_DOWN), SetFill(0, 1),
238  NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_SNOW_LEVEL_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0),
239  NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_LEVEL_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_SNOW_LINE_UP), SetFill(0, 1),
240  EndContainer(),
242  NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_MAX_HEIGHTLEVEL_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_MAX_HEIGHTLEVEL_DOWN), SetFill(0, 1),
243  NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_MAX_HEIGHTLEVEL_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0),
244  NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_MAX_HEIGHTLEVEL_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_MAX_HEIGHTLEVEL_UP), SetFill(0, 1),
245  EndContainer(),
247  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),
248  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL), SetFill(1, 0),
249  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),
250  EndContainer(),
251  EndContainer(),
252  EndContainer(),
253  NWidget(NWID_SPACER), SetFill(1, 1),
254  NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 30), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetFill(1, 0),
255  EndContainer(),
256  EndContainer(),
257  EndContainer(),
258  EndContainer(),
259  NWidget(NWID_SPACER), SetMinimalSize(0, 9), SetFill(1, 1),
260  EndContainer(),
261 };
262 
263 static void StartGeneratingLandscape(GenenerateLandscapeWindowMode mode)
264 {
267 
268  /* Copy all XXX_newgame to XXX when coming from outside the editor */
269  MakeNewgameSettingsLive();
270  ResetGRFConfig(true);
271 
272  if (_settings_client.sound.confirm) SndPlayFx(SND_15_BEEP);
273  switch (mode) {
274  case GLWM_GENERATE: _switch_mode = (_game_mode == GM_EDITOR) ? SM_GENRANDLAND : SM_NEWGAME; break;
275  case GLWM_HEIGHTMAP: _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_HEIGHTMAP : SM_START_HEIGHTMAP; break;
276  case GLWM_SCENARIO: _switch_mode = SM_EDITOR; break;
277  default: NOT_REACHED();
278  }
279 }
280 
281 static void LandscapeGenerationCallback(Window *w, bool confirmed)
282 {
283  if (confirmed) StartGeneratingLandscape((GenenerateLandscapeWindowMode)w->window_number);
284 }
285 
286 static DropDownList *BuildMapsizeDropDown()
287 {
288  DropDownList *list = new DropDownList();
289 
290  for (uint i = MIN_MAP_SIZE_BITS; i <= MAX_MAP_SIZE_BITS; i++) {
291  DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false);
292  item->SetParam(0, 1 << i);
293  *list->Append() = item;
294  }
295 
296  return list;
297 }
298 
299 static const StringID _elevations[] = {STR_TERRAIN_TYPE_VERY_FLAT, STR_TERRAIN_TYPE_FLAT, STR_TERRAIN_TYPE_HILLY, STR_TERRAIN_TYPE_MOUNTAINOUS, STR_TERRAIN_TYPE_ALPINIST, INVALID_STRING_ID};
300 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};
301 static const StringID _rivers[] = {STR_RIVERS_NONE, STR_RIVERS_FEW, STR_RIVERS_MODERATE, STR_RIVERS_LOT, INVALID_STRING_ID};
302 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};
303 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};
304 static const StringID _rotation[] = {STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE, STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_CLOCKWISE, INVALID_STRING_ID};
305 static const StringID _landscape[] = {STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL, STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS, INVALID_STRING_ID};
306 static const StringID _num_towns[] = {STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, STR_NUM_CUSTOM, INVALID_STRING_ID};
307 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};
308 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};
309 
310 assert_compile(lengthof(_num_inds) == ID_END + 1);
311 
313  uint widget_id;
314  uint x;
315  uint y;
316  char name[64];
318 
319  GenerateLandscapeWindow(WindowDesc *desc, WindowNumber number = 0) : Window(desc)
320  {
321  this->InitNested(number);
322 
324 
325  this->mode = (GenenerateLandscapeWindowMode)this->window_number;
326 
327  /* Disable town, industry and trees in SE */
328  this->SetWidgetDisabledState(WID_GL_TOWN_PULLDOWN, _game_mode == GM_EDITOR);
329  this->SetWidgetDisabledState(WID_GL_INDUSTRY_PULLDOWN, _game_mode == GM_EDITOR);
330  this->SetWidgetDisabledState(WID_GL_TREE_PULLDOWN, _game_mode == GM_EDITOR);
331 
332  this->OnInvalidateData();
333  }
334 
335 
336  virtual void SetStringParameters(int widget) const
337  {
338  switch (widget) {
344 
346  if (_game_mode == GM_EDITOR) {
347  SetDParam(0, STR_CONFIG_SETTING_OFF);
349  SetDParam(0, STR_NUM_CUSTOM_NUMBER);
351  } else {
353  }
354  break;
355 
356  case WID_GL_INDUSTRY_PULLDOWN: SetDParam(0, _game_mode == GM_EDITOR ? STR_CONFIG_SETTING_OFF : _num_inds[_settings_newgame.difficulty.industry_density]); break;
360 
363  SetDParam(0, STR_SEA_LEVEL_CUSTOM_PERCENTAGE);
365  } else {
367  }
368  break;
369 
373  case WID_GL_BORDERS_RANDOM: SetDParam(0, (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? STR_MAPGEN_BORDER_RANDOMIZE : STR_MAPGEN_BORDER_MANUAL); break;
374  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;
375  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;
376  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;
377  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;
379 
382  SetDParam(0, this->y);
383  SetDParam(1, this->x);
384  } else {
385  SetDParam(0, this->x);
386  SetDParam(1, this->y);
387  }
388  break;
389  }
390  }
391 
397  virtual void OnInvalidateData(int data = 0, bool gui_scope = true)
398  {
399  if (!gui_scope) return;
400  /* Update the climate buttons */
405 
406  /* You can't select smoothness / non-water borders if not terragenesis */
407  if (mode == GLWM_GENERATE) {
413 
415 
420 
423  }
424 
425  /* Disable snowline if not arctic */
427 
428  /* Update availability of decreasing / increasing start date and snow level */
435 
436  /* Do not allow a custom sea level with the original land generator. */
440  }
441 
442  }
443 
444  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
445  {
446  const StringID *strs = NULL;
447  switch (widget) {
450  *size = GetStringBoundingBox(STR_JUST_INT);
451  break;
452 
455  *size = maxdim(*size, GetStringBoundingBox(STR_BLACK_DATE_LONG));
456  break;
457 
461  *size = maxdim(*size, GetStringBoundingBox(STR_JUST_INT));
462  break;
463 
466  *size = maxdim(*size, GetStringBoundingBox(STR_JUST_INT));
467  break;
468 
470  SetDParam(0, this->x);
471  SetDParam(1, this->y);
472  *size = maxdim(*size, GetStringBoundingBox(STR_MAPGEN_HEIGHTMAP_SIZE));
473  break;
474 
476  strs = _num_towns;
478  *size = maxdim(*size, GetStringBoundingBox(STR_NUM_CUSTOM_NUMBER));
479  break;
480 
481  case WID_GL_INDUSTRY_PULLDOWN: strs = _num_inds; break;
482  case WID_GL_LANDSCAPE_PULLDOWN: strs = _landscape; break;
483  case WID_GL_TREE_PULLDOWN: strs = _tree_placer; break;
484  case WID_GL_TERRAIN_PULLDOWN: strs = _elevations; break;
486  strs = _sea_lakes;
488  *size = maxdim(*size, GetStringBoundingBox(STR_SEA_LEVEL_CUSTOM_PERCENTAGE));
489  break;
490 
491  case WID_GL_RIVER_PULLDOWN: strs = _rivers; break;
492  case WID_GL_SMOOTHNESS_PULLDOWN: strs = _smoothness; break;
493  case WID_GL_VARIETY_PULLDOWN: strs = _variety; break;
494  case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: strs = _rotation; break;
496  *size = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOMIZE), GetStringBoundingBox(STR_MAPGEN_BORDER_MANUAL));
497  break;
498 
499  case WID_GL_WATER_NE:
500  case WID_GL_WATER_NW:
501  case WID_GL_WATER_SE:
502  case WID_GL_WATER_SW:
503  *size = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOM), maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_WATER), GetStringBoundingBox(STR_MAPGEN_BORDER_FREEFORM)));
504  break;
505 
507  size->width = 0;
508  break;
509 
510  default:
511  return;
512  }
513  if (strs != NULL) {
514  while (*strs != INVALID_STRING_ID) {
515  *size = maxdim(*size, GetStringBoundingBox(*strs++));
516  }
517  }
518  size->width += padding.width;
519  size->height = max(size->height, (uint)(FONT_HEIGHT_NORMAL + WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM));
520  }
521 
522  virtual void DrawWidget(const Rect &r, int widget) const
523  {
524  switch (widget) {
526  DrawString(r.left, r.right, r.top, this->name, TC_ORANGE);
527  break;
528  }
529  }
530  }
531 
532  virtual void OnClick(Point pt, int widget, int click_count)
533  {
534  switch (widget) {
535  case WID_GL_TEMPERATE:
536  case WID_GL_ARCTIC:
537  case WID_GL_TROPICAL:
538  case WID_GL_TOYLAND:
540  break;
541 
542  case WID_GL_MAPSIZE_X_PULLDOWN: // Mapsize X
544  break;
545 
546  case WID_GL_MAPSIZE_Y_PULLDOWN: // Mapsize Y
548  break;
549 
550  case WID_GL_TOWN_PULLDOWN: // Number of towns
552  break;
553 
554  case WID_GL_INDUSTRY_PULLDOWN: // Number of industries
556  break;
557 
558  case WID_GL_GENERATE_BUTTON: { // Generate
559  /* Get rotated map size. */
560  uint map_x;
561  uint map_y;
563  map_x = this->y;
564  map_y = this->x;
565  } else {
566  map_x = this->x;
567  map_y = this->y;
568  }
569  if (mode == GLWM_HEIGHTMAP &&
570  (map_x * 2 < (1U << _settings_newgame.game_creation.map_x) ||
571  map_x / 2 > (1U << _settings_newgame.game_creation.map_x) ||
572  map_y * 2 < (1U << _settings_newgame.game_creation.map_y) ||
573  map_y / 2 > (1U << _settings_newgame.game_creation.map_y))) {
574  ShowQuery(
575  STR_WARNING_HEIGHTMAP_SCALE_CAPTION,
576  STR_WARNING_HEIGHTMAP_SCALE_MESSAGE,
577  this,
578  LandscapeGenerationCallback);
579  } else {
580  StartGeneratingLandscape(mode);
581  }
582  break;
583  }
584 
586  case WID_GL_MAX_HEIGHTLEVEL_UP: // Height level buttons
587  /* Don't allow too fast scrolling */
588  if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
589  this->HandleButtonClick(widget);
590 
592  this->InvalidateData();
593  }
594  _left_button_clicked = false;
595  break;
596 
597  case WID_GL_MAX_HEIGHTLEVEL_TEXT: // Height level text
598  this->widget_id = WID_GL_MAX_HEIGHTLEVEL_TEXT;
600  ShowQueryString(STR_JUST_INT, STR_MAPGEN_MAX_HEIGHTLEVEL_QUERY_CAPT, 4, this, CS_NUMERAL, QSF_ENABLE_DEFAULT);
601  break;
602 
603 
605  case WID_GL_START_DATE_UP: // Year buttons
606  /* Don't allow too fast scrolling */
607  if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
608  this->HandleButtonClick(widget);
609 
611  this->InvalidateData();
612  }
613  _left_button_clicked = false;
614  break;
615 
616  case WID_GL_START_DATE_TEXT: // Year text
617  this->widget_id = WID_GL_START_DATE_TEXT;
619  ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ENABLE_DEFAULT);
620  break;
621 
623  case WID_GL_SNOW_LEVEL_UP: // Snow line buttons
624  /* Don't allow too fast scrolling */
625  if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
626  this->HandleButtonClick(widget);
627 
629  this->InvalidateData();
630  }
631  _left_button_clicked = false;
632  break;
633 
634  case WID_GL_SNOW_LEVEL_TEXT: // Snow line text
635  this->widget_id = WID_GL_SNOW_LEVEL_TEXT;
637  ShowQueryString(STR_JUST_INT, STR_MAPGEN_SNOW_LINE_QUERY_CAPT, 4, this, CS_NUMERAL, QSF_ENABLE_DEFAULT);
638  break;
639 
640  case WID_GL_TREE_PULLDOWN: // Tree placer
642  break;
643 
644  case WID_GL_LANDSCAPE_PULLDOWN: // Landscape generator
646  break;
647 
648  case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: // Heightmap rotation
650  break;
651 
652  case WID_GL_TERRAIN_PULLDOWN: // Terrain type
653  /* For the original map generation only the first four are valid. */
655  break;
656 
657  case WID_GL_WATER_PULLDOWN: { // Water quantity
658  uint32 hidden_mask = 0;
659  /* Disable custom water level when the original map generator is active. */
662  }
664  break;
665  }
666 
667  case WID_GL_RIVER_PULLDOWN: // Amount of rivers
669  break;
670 
671  case WID_GL_SMOOTHNESS_PULLDOWN: // Map smoothness
673  break;
674 
675  case WID_GL_VARIETY_PULLDOWN: // Map variety
677  break;
678 
679  /* Freetype map borders */
680  case WID_GL_WATER_NW:
682  this->InvalidateData();
683  break;
684 
685  case WID_GL_WATER_NE:
687  this->InvalidateData();
688  break;
689 
690  case WID_GL_WATER_SE:
692  this->InvalidateData();
693  break;
694 
695  case WID_GL_WATER_SW:
697  this->InvalidateData();
698  break;
699 
702  this->InvalidateData();
703  break;
704  }
705  }
706 
707  virtual void OnTimeout()
708  {
710  for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) {
711  if (this->IsWidgetLowered(*widget)) {
712  this->RaiseWidget(*widget);
713  this->SetWidgetDirty(*widget);
714  }
715  }
716  }
717 
718  virtual void OnDropdownSelect(int widget, int index)
719  {
720  switch (widget) {
727 
729  /* If original landgenerator is selected and alpinist terrain_type was selected, revert to mountainous. */
732  }
733  break;
734 
736 
738  if ((uint)index == CUSTOM_TOWN_NUMBER_DIFFICULTY) {
739  this->widget_id = widget;
741  ShowQueryString(STR_JUST_INT, STR_MAPGEN_NUMBER_OF_TOWNS, 5, this, CS_NUMERAL, QSF_NONE);
742  }
744  break;
745 
748 
749  case WID_GL_WATER_PULLDOWN: {
750  if ((uint)index == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) {
751  this->widget_id = widget;
753  ShowQueryString(STR_JUST_INT, STR_MAPGEN_QUANTITY_OF_SEA_LAKES, 3, this, CS_NUMERAL, QSF_NONE);
754  }
756  break;
757  }
758  }
759  this->InvalidateData();
760  }
761 
762  virtual void OnQueryTextFinished(char *str)
763  {
764  /* Was 'cancel' pressed? */
765  if (str == NULL) return;
766 
767  int32 value;
768  if (!StrEmpty(str)) {
769  value = atoi(str);
770  } else {
771  /* An empty string means revert to the default */
772  switch (this->widget_id) {
774  case WID_GL_START_DATE_TEXT: value = DEF_START_YEAR; break;
775  case WID_GL_SNOW_LEVEL_TEXT: value = DEF_SNOWLINE_HEIGHT; break;
776  case WID_GL_TOWN_PULLDOWN: value = 1; break;
778  default: NOT_REACHED();
779  }
780  }
781 
782  switch (this->widget_id) {
786  break;
787 
791  break;
792 
796  break;
797 
800  break;
801 
804  break;
805  }
806 
807  this->InvalidateData();
808  }
809 };
810 
811 static WindowDesc _generate_landscape_desc(
812  WDP_CENTER, NULL, 0, 0,
814  0,
815  _nested_generate_landscape_widgets, lengthof(_nested_generate_landscape_widgets)
816 );
817 
818 static WindowDesc _heightmap_load_desc(
819  WDP_CENTER, NULL, 0, 0,
821  0,
822  _nested_heightmap_load_widgets, lengthof(_nested_heightmap_load_widgets)
823 );
824 
825 static void _ShowGenerateLandscape(GenenerateLandscapeWindowMode mode)
826 {
827  uint x = 0;
828  uint y = 0;
829 
831 
832  /* Generate a new seed when opening the window */
833  _settings_newgame.game_creation.generation_seed = InteractiveRandom();
834 
835  if (mode == GLWM_HEIGHTMAP) {
836  /* If the function returns negative, it means there was a problem loading the heightmap */
837  if (!GetHeightmapDimensions(_file_to_saveload.name, &x, &y)) return;
838  }
839 
840  WindowDesc *desc = (mode == GLWM_HEIGHTMAP) ? &_heightmap_load_desc : &_generate_landscape_desc;
841  GenerateLandscapeWindow *w = AllocateWindowDescFront<GenerateLandscapeWindow>(desc, mode, true);
842 
843  if (mode == GLWM_HEIGHTMAP) {
844  w->x = x;
845  w->y = y;
846  strecpy(w->name, _file_to_saveload.title, lastof(w->name));
847  }
848 
850 }
851 
854 {
855  _ShowGenerateLandscape(GLWM_GENERATE);
856 }
857 
860 {
861  _ShowGenerateLandscape(GLWM_HEIGHTMAP);
862 }
863 
866 {
867  StartGeneratingLandscape(GLWM_SCENARIO);
868 }
869 
874 void StartNewGameWithoutGUI(uint seed)
875 {
876  /* GenerateWorld takes care of the possible GENERATE_NEW_SEED value in 'seed' */
878 
879  StartGeneratingLandscape(GLWM_GENERATE);
880 }
881 
883 {
884  uint widget_id;
885 
887  {
888  this->InitNested(window_number);
890  }
891 
892  virtual void SetStringParameters(int widget) const
893  {
894  switch (widget) {
897  break;
898 
901  break;
902 
905  break;
906 
909  break;
910  }
911  }
912 
913  virtual void OnPaint()
914  {
919 
924 
925  this->DrawWidgets();
926  }
927 
928  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
929  {
930  StringID str = STR_JUST_INT;
931  switch (widget) {
934  str = STR_BLACK_DATE_LONG;
935  break;
936 
940  break;
941 
944  break;
945 
946  default:
947  return;
948  }
949  *size = maxdim(*size, GetStringBoundingBox(str));
950  size->width += padding.width;
951  size->height += padding.height;
952  }
953 
954  virtual void OnClick(Point pt, int widget, int click_count)
955  {
956  switch (widget) {
957  case WID_CS_TEMPERATE:
958  case WID_CS_ARCTIC:
959  case WID_CS_TROPICAL:
960  case WID_CS_TOYLAND:
963  break;
964 
965  case WID_CS_MAPSIZE_X_PULLDOWN: // Mapsize X
967  break;
968 
969  case WID_CS_MAPSIZE_Y_PULLDOWN: // Mapsize Y
971  break;
972 
973  case WID_CS_EMPTY_WORLD: // Empty world / flat world
974  StartGeneratingLandscape(GLWM_SCENARIO);
975  break;
976 
977  case WID_CS_RANDOM_WORLD: // Generate
979  break;
980 
982  case WID_CS_START_DATE_UP: // Year buttons
983  /* Don't allow too fast scrolling */
984  if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
985  this->HandleButtonClick(widget);
986  this->SetDirty();
987 
989  }
990  _left_button_clicked = false;
991  break;
992 
993  case WID_CS_START_DATE_TEXT: // Year text
994  this->widget_id = WID_CS_START_DATE_TEXT;
996  ShowQueryString(STR_JUST_INT, STR_MAPGEN_START_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_NONE);
997  break;
998 
1000  case WID_CS_FLAT_LAND_HEIGHT_UP: // Height level buttons
1001  /* Don't allow too fast scrolling */
1002  if (!(this->flags & WF_TIMEOUT) || this->timeout_timer <= 1) {
1003  this->HandleButtonClick(widget);
1004  this->SetDirty();
1005 
1007  }
1008  _left_button_clicked = false;
1009  break;
1010 
1011  case WID_CS_FLAT_LAND_HEIGHT_TEXT: // Height level text
1012  this->widget_id = WID_CS_FLAT_LAND_HEIGHT_TEXT;
1014  ShowQueryString(STR_JUST_INT, STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_QUERY_CAPT, 4, this, CS_NUMERAL, QSF_NONE);
1015  break;
1016  }
1017  }
1018 
1019  virtual void OnTimeout()
1020  {
1022  for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) {
1023  if (this->IsWidgetLowered(*widget)) {
1024  this->RaiseWidget(*widget);
1025  this->SetWidgetDirty(*widget);
1026  }
1027  }
1028  }
1029 
1030  virtual void OnDropdownSelect(int widget, int index)
1031  {
1032  switch (widget) {
1035  }
1036  this->SetDirty();
1037  }
1038 
1039  virtual void OnQueryTextFinished(char *str)
1040  {
1041  if (!StrEmpty(str)) {
1042  int32 value = atoi(str);
1043 
1044  switch (this->widget_id) {
1048  break;
1049 
1053  break;
1054  }
1055 
1056  this->SetDirty();
1057  }
1058  }
1059 };
1060 
1061 static const NWidgetPart _nested_create_scenario_widgets[] = {
1063  NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
1064  NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_SE_MAPGEN_CAPTION, STR_NULL),
1065  EndContainer(),
1066  NWidget(WWT_PANEL, COLOUR_BROWN),
1068  /* Landscape style selection. */
1069  NWidget(NWID_HORIZONTAL), SetPIP(10, 3, 10),
1070  NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TEMPERATE), SetDataTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
1071  NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_ARCTIC), SetDataTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
1072  NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TROPICAL), SetDataTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
1073  NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TOYLAND), SetDataTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
1074  EndContainer(),
1075  NWidget(NWID_HORIZONTAL), SetPIP(10, 8, 10),
1076  /* Green generation type buttons: 'Flat land' and 'Random land'. */
1077  NWidget(NWID_VERTICAL), SetPIP(10, 6, 10),
1078  NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_CS_EMPTY_WORLD), SetDataTip(STR_SE_MAPGEN_FLAT_WORLD, STR_SE_MAPGEN_FLAT_WORLD_TOOLTIP), SetFill(1, 1),
1079  NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_CS_RANDOM_WORLD), SetDataTip(STR_SE_MAPGEN_RANDOM_LAND, STR_TERRAFORM_TOOLTIP_GENERATE_RANDOM_LAND), SetFill(1, 1),
1080  EndContainer(),
1081  /* Labels + setting drop-downs */
1082  NWidget(NWID_VERTICAL), SetPIP(10, 6, 10),
1083  /* Map size. */
1085  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_NULL), SetPadding(1, 0, 0, 0),
1086  NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0),
1087  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_CS_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetPadding(0, 4, 0, 0),
1088  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 2, 0, 0),
1089  NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_CS_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL),
1090  EndContainer(),
1091  /* Date. */
1093  NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetPadding(1, 0, 0, 0),
1094  NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0),
1095  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),
1096  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CS_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL),
1097  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),
1098  EndContainer(),
1099  /* Flat map height. */
1101  NWidget(WWT_TEXT, COLOUR_ORANGE),
1102  SetDataTip(STR_SE_MAPGEN_FLAT_WORLD_HEIGHT, STR_NULL), SetPadding(1, 0, 0, 0),
1103  NWidget(NWID_SPACER), SetMinimalSize(6, 0), SetFill(1, 0),
1104  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),
1105  NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CS_FLAT_LAND_HEIGHT_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL),
1106  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),
1107  EndContainer(),
1108  EndContainer(),
1109  EndContainer(),
1110  EndContainer(),
1111 };
1112 
1113 static WindowDesc _create_scenario_desc(
1114  WDP_CENTER, NULL, 0, 0,
1116  0,
1117  _nested_create_scenario_widgets, lengthof(_nested_create_scenario_widgets)
1118 );
1119 
1122 {
1124  new CreateScenarioWindow(&_create_scenario_desc, GLWM_SCENARIO);
1125 }
1126 
1127 static const NWidgetPart _nested_generate_progress_widgets[] = {
1128  NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_GENERATION_WORLD, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1129  NWidget(WWT_PANEL, COLOUR_GREY),
1130  NWidget(NWID_HORIZONTAL), SetPIP(20, 0, 20),
1131  NWidget(NWID_VERTICAL), SetPIP(11, 8, 11),
1132  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_BAR), SetFill(1, 0),
1133  NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_TEXT), SetFill(1, 0),
1134  NWidget(WWT_TEXTBTN, COLOUR_WHITE, WID_GP_ABORT), SetDataTip(STR_GENERATION_ABORT, STR_NULL), SetFill(1, 0),
1135  EndContainer(),
1136  EndContainer(),
1137  EndContainer(),
1138 };
1139 
1140 
1141 static WindowDesc _generate_progress_desc(
1142  WDP_CENTER, NULL, 0, 0,
1144  0,
1145  _nested_generate_progress_widgets, lengthof(_nested_generate_progress_widgets)
1146 );
1147 
1149  uint percent;
1150  StringID cls;
1151  uint current;
1152  uint total;
1153  int timer;
1154 };
1155 
1156 static GenWorldStatus _gws;
1157 
1158 static const StringID _generation_class_table[] = {
1159  STR_GENERATION_WORLD_GENERATION,
1160  STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION,
1161  STR_GENERATION_RIVER_GENERATION,
1162  STR_GENERATION_CLEARING_TILES,
1163  STR_SCENEDIT_TOOLBAR_TOWN_GENERATION,
1164  STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION,
1165  STR_GENERATION_OBJECT_GENERATION,
1166  STR_GENERATION_TREE_GENERATION,
1167  STR_GENERATION_SETTINGUP_GAME,
1168  STR_GENERATION_PREPARING_TILELOOP,
1169  STR_GENERATION_PREPARING_SCRIPT,
1170  STR_GENERATION_PREPARING_GAME
1171 };
1172 assert_compile(lengthof(_generation_class_table) == GWP_CLASS_COUNT);
1173 
1174 
1175 static void AbortGeneratingWorldCallback(Window *w, bool confirmed)
1176 {
1177  if (confirmed) {
1179  } else if (HasModalProgress() && !IsGeneratingWorldAborted()) {
1180  SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
1181  }
1182 }
1183 
1185 
1186  GenerateProgressWindow() : Window(&_generate_progress_desc)
1187  {
1188  this->InitNested();
1189  }
1190 
1191  virtual void OnClick(Point pt, int widget, int click_count)
1192  {
1193  switch (widget) {
1194  case WID_GP_ABORT:
1195  if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
1196  ShowQuery(
1197  STR_GENERATION_ABORT_CAPTION,
1198  STR_GENERATION_ABORT_MESSAGE,
1199  this,
1200  AbortGeneratingWorldCallback
1201  );
1202  break;
1203  }
1204  }
1205 
1206  virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
1207  {
1208  switch (widget) {
1209  case WID_GP_PROGRESS_BAR: {
1210  SetDParamMaxValue(0, 100);
1211  *size = GetStringBoundingBox(STR_GENERATION_PROGRESS);
1212  /* We need some spacing for the 'border' */
1213  size->height += 8;
1214  size->width += 8;
1215  break;
1216  }
1217 
1218  case WID_GP_PROGRESS_TEXT:
1219  for (uint i = 0; i < GWP_CLASS_COUNT; i++) {
1220  size->width = max(size->width, GetStringBoundingBox(_generation_class_table[i]).width);
1221  }
1222  size->height = FONT_HEIGHT_NORMAL * 2 + WD_PAR_VSEP_NORMAL;
1223  break;
1224  }
1225  }
1226 
1227  virtual void DrawWidget(const Rect &r, int widget) const
1228  {
1229  switch (widget) {
1230  case WID_GP_PROGRESS_BAR:
1231  /* Draw the % complete with a bar and a text */
1232  DrawFrameRect(r.left, r.top, r.right, r.bottom, COLOUR_GREY, FR_BORDERONLY);
1233  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);
1234  SetDParam(0, _gws.percent);
1235  DrawString(r.left, r.right, r.top + 5, STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER);
1236  break;
1237 
1238  case WID_GP_PROGRESS_TEXT:
1239  /* Tell which class we are generating */
1240  DrawString(r.left, r.right, r.top, _gws.cls, TC_FROMSTRING, SA_HOR_CENTER);
1241 
1242  /* And say where we are in that class */
1243  SetDParam(0, _gws.current);
1244  SetDParam(1, _gws.total);
1245  DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL, STR_GENERATION_PROGRESS_NUM, TC_FROMSTRING, SA_HOR_CENTER);
1246  }
1247  }
1248 };
1249 
1254 {
1255  _gws.cls = STR_GENERATION_WORLD_GENERATION;
1256  _gws.current = 0;
1257  _gws.total = 0;
1258  _gws.percent = 0;
1259  _gws.timer = 0; // Forces to paint the progress window immediately
1260 }
1261 
1266 {
1267  if (BringWindowToFrontById(WC_MODAL_PROGRESS, 0)) return;
1268  new GenerateProgressWindow();
1269 }
1270 
1271 static void _SetGeneratingWorldProgress(GenWorldProgress cls, uint progress, uint total)
1272 {
1273  static const int percent_table[] = {0, 5, 14, 17, 20, 40, 60, 65, 80, 85, 95, 99, 100 };
1274  assert_compile(lengthof(percent_table) == GWP_CLASS_COUNT + 1);
1275  assert(cls < GWP_CLASS_COUNT);
1276 
1277  /* Do not run this function if we aren't in a thread */
1278  if (!IsGenerateWorldThreaded() && !_network_dedicated) return;
1279 
1281 
1282  if (total == 0) {
1283  assert(_gws.cls == _generation_class_table[cls]);
1284  _gws.current += progress;
1285  assert(_gws.current <= _gws.total);
1286  } else {
1287  _gws.cls = _generation_class_table[cls];
1288  _gws.current = progress;
1289  _gws.total = total;
1290  _gws.percent = percent_table[cls];
1291  }
1292 
1293  /* Don't update the screen too often. So update it once in every once in a while... */
1294  if (!_network_dedicated && _gws.timer != 0 && _realtime_tick - _gws.timer < MODAL_PROGRESS_REDRAW_TIMEOUT) return;
1295 
1296  /* Percentage is about the number of completed tasks, so 'current - 1' */
1297  _gws.percent = percent_table[cls] + (percent_table[cls + 1] - percent_table[cls]) * (_gws.current == 0 ? 0 : _gws.current - 1) / _gws.total;
1298 
1299  if (_network_dedicated) {
1300  static uint last_percent = 0;
1301 
1302  /* Never display 0% */
1303  if (_gws.percent == 0) return;
1304  /* Reset if percent is lower than the last recorded */
1305  if (_gws.percent < last_percent) last_percent = 0;
1306  /* Display every 5%, but 6% is also very valid.. just not smaller steps than 5% */
1307  if (_gws.percent % 5 != 0 && _gws.percent <= last_percent + 5) return;
1308  /* Never show steps smaller than 2%, even if it is a mod 5% */
1309  if (_gws.percent <= last_percent + 2) return;
1310 
1311  DEBUG(net, 1, "Map generation percentage complete: %d", _gws.percent);
1312  last_percent = _gws.percent;
1313 
1314  /* Don't continue as dedicated never has a thread running */
1315  return;
1316  }
1317 
1320 
1321  /* Release the rights to the map generator, and acquire the rights to the
1322  * paint thread. The 'other' thread already has the paint thread rights so
1323  * this ensures us that we are waiting until the paint thread is done
1324  * before we reacquire the mapgen rights */
1329 
1330  _gws.timer = _realtime_tick;
1331 }
1332 
1342 {
1343  if (total == 0) return;
1344 
1345  _SetGeneratingWorldProgress(cls, 0, total);
1346 }
1347 
1356 {
1357  /* In fact the param 'class' isn't needed.. but for some security reasons, we want it around */
1358  _SetGeneratingWorldProgress(cls, 1, 0);
1359 }