OpenTTD Source 20260218-master-g2123fca5ea
genworld_gui.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
10#include "stdafx.h"
11#include "heightmap.h"
12#include "debug.h"
13#include "genworld.h"
14#include "network/network.h"
15#include "strings_func.h"
16#include "window_func.h"
18#include "sound_func.h"
19#include "fios.h"
20#include "string_func.h"
21#include "dropdown_type.h"
22#include "dropdown_func.h"
23#include "querystring_gui.h"
24#include "town.h"
26#include "core/random_func.hpp"
27#include "saveload/saveload.h"
28#include "progress.h"
29#include "error.h"
30#include "newgrf_townname.h"
31#include "townname_type.h"
33#include "ai/ai_gui.hpp"
34#include "game/game_gui.hpp"
35#include "industry.h"
37
39
40#include "table/strings.h"
41
43
44#include "safeguards.h"
45
46
47extern void MakeNewgameSettingsLive();
48
55
60static uint GetMapHeightLimit()
61{
62 if (_settings_newgame.construction.map_height_limit == 0) return MAX_MAP_HEIGHT_LIMIT;
63 return _settings_newgame.construction.map_height_limit;
64}
65
76
78static constexpr std::initializer_list<NWidgetPart> _nested_generate_landscape_widgets = {
80 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
81 NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_MAPGEN_WORLD_GENERATION_CAPTION),
83 NWidget(WWT_PANEL, COLOUR_BROWN),
85 /* Landscape selection. */
87 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TEMPERATE), SetSpriteTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
88 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_ARCTIC), SetSpriteTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
89 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TROPICAL), SetSpriteTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
90 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TOYLAND), SetSpriteTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
92
93 /* Generation options. */
95 /* Left half (land generation options) */
97 /* Labels on the left side (global column 1). */
99 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_MAPSIZE, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
100 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_TERRAIN_TYPE, STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT), SetFill(1, 1),
101 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_AVERAGE_HEIGHT, STR_CONFIG_SETTING_AVERAGE_HEIGHT_HELPTEXT), SetFill(1, 1),
102 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_VARIETY, STR_CONFIG_SETTING_VARIETY_HELPTEXT), SetFill(1, 1),
103 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_SMOOTHNESS, STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT), SetFill(1, 1),
104 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT), SetFill(1, 1),
105 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_BORDER_TYPE, STR_MAPGEN_BORDER_TYPE_TOOLTIP), SetFill(1, 1),
106 EndContainer(),
107
108 /* Widgets on the right side (global column 2). */
110 /* Mapsize X * Y. */
112 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_X_PULLDOWN), SetToolTip(STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
113 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_BY), SetFill(0, 1), SetAlignment(SA_CENTER),
114 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetToolTip(STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
115 EndContainer(),
116 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAX_HEIGHT_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT), SetFill(1, 1),
117 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_AVERAGE_HEIGHT_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_AVERAGE_HEIGHT_HELPTEXT), SetFill(1, 1),
118 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_VARIETY_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_VARIETY_HELPTEXT), SetFill(1, 1),
119 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_SMOOTHNESS_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT), SetFill(1, 1),
120 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT), SetFill(1, 1),
121 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_BORDERS_PULLDOWN), SetToolTip(STR_MAPGEN_BORDER_TYPE_TOOLTIP), SetFill(1, 1),
122 EndContainer(),
123 EndContainer(),
124
125 /* Right half (all other options) */
127 /* Labels on the left side (global column 3). */
130 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_SNOW_COVERAGE, STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT), SetFill(1, 1),
131 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_DESERT_COVERAGE, STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT), SetFill(1, 1),
133 EndContainer(),
134 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_DATE, STR_MAPGEN_DATE_TOOLTIP), SetFill(1, 1),
135 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_TOWN_NAME_LABEL, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 1),
136 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_MAPGEN_NUMBER_OF_TOWNS_TOOLTIP), SetFill(1, 1),
137 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_MAPGEN_NUMBER_OF_INDUSTRIES_TOOLTIP), SetFill(1, 1),
138 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_SEA_LEVEL, STR_MAPGEN_SEA_LEVEL_TOOLTIP), SetFill(1, 1),
139 /* Spacer due to fewer items in columns 3-4 than in 1-2. */
141 EndContainer(),
142
143 /* Widgets on the right side (global column 4). */
145 /* Climate selector. */
147 /* Snow coverage. */
149 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_DOWN), SetSpriteTip(SPR_ARROW_DOWN, STR_MAPGEN_SNOW_COVERAGE_DOWN_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
150 NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_TEXT), SetToolTip(STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT), SetFill(1, 1),
151 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_UP), SetSpriteTip(SPR_ARROW_UP, STR_MAPGEN_SNOW_COVERAGE_UP_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
152 EndContainer(),
153 /* Desert coverage. */
155 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_DOWN), SetSpriteTip(SPR_ARROW_DOWN, STR_MAPGEN_DESERT_COVERAGE_DOWN_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
156 NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_TEXT), SetToolTip(STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT), SetFill(1, 1),
157 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_UP), SetSpriteTip(SPR_ARROW_UP, STR_MAPGEN_DESERT_COVERAGE_UP_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
158 EndContainer(),
159 /* Temperate/Toyland spacer. */
161 EndContainer(),
162 /* Starting date. */
164 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_DOWN), SetSpriteTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_MOVE_THE_STARTING_DATE_BACKWARD_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
165 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetToolTip(STR_MAPGEN_DATE_TOOLTIP), SetFill(1, 1),
166 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetSpriteTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_MOVE_THE_STARTING_DATE_FORWARD_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
167 EndContainer(),
168 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetToolTip(STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 1),
169 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetToolTip(STR_MAPGEN_NUMBER_OF_TOWNS_TOOLTIP), SetFill(1, 1),
170 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetToolTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES_TOOLTIP), SetFill(1, 1),
171 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_WATER_PULLDOWN), SetToolTip(STR_MAPGEN_SEA_LEVEL_TOOLTIP), SetFill(1, 1),
172 /* Spacer due to fewer items in columns 3-4 than in 1-2. */
174 EndContainer(),
175 EndContainer(),
176 EndContainer(),
177
178 /* Map borders buttons for each edge. */
181 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_NORTHWEST), SetPadding(0, WidgetDimensions::unscaled.hsep_normal, 0, 0), SetFill(1, 1), SetAlignment(SA_RIGHT | SA_VERT_CENTER),
182 NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_NW), SetToolTip(STR_MAPGEN_NORTHWEST_TOOLTIP), SetFill(1, 1),
183 NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_NE), SetToolTip(STR_MAPGEN_NORTHEAST_TOOLTIP), SetFill(1, 1),
184 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_NORTHEAST), SetPadding(0, 0, 0, WidgetDimensions::unscaled.hsep_normal), SetFill(1, 1),
185 EndContainer(),
187 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_SOUTHWEST), SetPadding(0, WidgetDimensions::unscaled.hsep_normal, 0, 0), SetFill(1, 1), SetAlignment(SA_RIGHT | SA_VERT_CENTER),
188 NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_SW), SetToolTip(STR_MAPGEN_SOUTHWEST_TOOLTIP), SetFill(1, 1),
189 NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_WATER_SE), SetToolTip(STR_MAPGEN_SOUTHEAST_TOOLTIP), SetFill(1, 1),
190 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_SOUTHEAST), SetPadding(0, 0, 0, WidgetDimensions::unscaled.hsep_normal), SetFill(1, 1),
191 EndContainer(),
192 EndContainer(),
193
194 /* AI, GS, and NewGRF settings */
196 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_AI_BUTTON), SetMinimalTextLines(2, 0), SetStringTip(STR_MAPGEN_AI_SETTINGS, STR_MAPGEN_AI_SETTINGS_TOOLTIP), SetFill(1, 0),
197 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_GS_BUTTON), SetMinimalTextLines(2, 0), SetStringTip(STR_MAPGEN_GS_SETTINGS, STR_MAPGEN_GS_SETTINGS_TOOLTIP), SetFill(1, 0),
198 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_NEWGRF_BUTTON), SetMinimalTextLines(2, 0), SetStringTip(STR_MAPGEN_NEWGRF_SETTINGS, STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP), SetFill(1, 0),
199 EndContainer(),
200
201 /* Generate */
202 NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalTextLines(3, 0), SetStringTip(STR_MAPGEN_GENERATE, STR_MAPGEN_GENERATE_TOOLTIP), SetFill(1, 1),
203 EndContainer(),
204 EndContainer(),
205};
206
208static constexpr std::initializer_list<NWidgetPart> _nested_heightmap_load_widgets = {
209 /* Window header. */
211 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
212 NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_MAPGEN_WORLD_GENERATION_CAPTION),
213 EndContainer(),
214 NWidget(WWT_PANEL, COLOUR_BROWN),
216 /* Landscape selection. */
218 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TEMPERATE), SetSpriteTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
219 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_ARCTIC), SetSpriteTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
220 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TROPICAL), SetSpriteTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
221 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_GL_TOYLAND), SetSpriteTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
222 EndContainer(),
223
225 /* Heightmap name label. */
226 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_HEIGHTMAP_NAME, STR_MAPGEN_HEIGHTMAP_NAME_TOOLTIP),
227 NWidget(WWT_TEXT, INVALID_COLOUR, WID_GL_HEIGHTMAP_NAME_TEXT), SetTextStyle(TC_ORANGE), SetToolTip(STR_MAPGEN_HEIGHTMAP_NAME_TOOLTIP), SetFill(1, 0),
228 EndContainer(),
229
230 /* Generation options. */
232 /* Left half (land generation options) */
234 /* Labels on the left side (global column 1). */
236 /* Land generation option labels. */
237 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_HEIGHTMAP_SIZE_LABEL, STR_MAPGEN_HEIGHTMAP_SIZE_LABEL_TOOLTIP), SetFill(1, 1),
238 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_MAPSIZE, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
239 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_HEIGHTMAP_ROTATION, STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_TOOLTIP), SetFill(1, 1),
240 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_HEIGHTMAP_HEIGHT, STR_MAPGEN_HEIGHTMAP_HEIGHT_TOOLTIP), SetFill(1, 1),
241 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT), SetFill(1, 1),
242 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_BORDER_TYPE, STR_MAPGEN_BORDER_TYPE_TOOLTIP), SetFill(1, 1),
243 EndContainer(),
244
245 /* Left half widgets (global column 2) */
247 NWidget(WWT_TEXT, INVALID_COLOUR, WID_GL_HEIGHTMAP_SIZE_TEXT), SetStringTip(STR_MAPGEN_HEIGHTMAP_SIZE, STR_MAPGEN_HEIGHTMAP_SIZE_LABEL_TOOLTIP), SetFill(1, 1),
248 /* Mapsize X * Y. */
250 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_X_PULLDOWN), SetToolTip(STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
251 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_BY), SetFill(0, 1), SetAlignment(SA_CENTER),
252 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetToolTip(STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
253 EndContainer(),
254 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_ROTATION_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_TOOLTIP), SetFill(1, 1),
255 /* Heightmap highest peak. */
257 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_DOWN), SetSpriteTip(SPR_ARROW_DOWN, STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
258 NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_TEXT), SetToolTip(STR_MAPGEN_HEIGHTMAP_HEIGHT_TOOLTIP), SetFill(1, 1),
259 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_UP), SetSpriteTip(SPR_ARROW_UP, STR_MAPGEN_HEIGHTMAP_HEIGHT_UP_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
260 EndContainer(),
261 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetToolTip(STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT), SetFill(1, 1),
262 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_BORDERS_PULLDOWN), SetToolTip(STR_MAPGEN_BORDER_TYPE_TOOLTIP), SetFill(1, 1),
263 EndContainer(),
264 EndContainer(),
265
266 /* Right half (all other options) */
268 /* Right half labels (global column 3) */
271 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_SNOW_COVERAGE, STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT), SetFill(1, 1),
272 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_DESERT_COVERAGE, STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT), SetFill(1, 1),
274 EndContainer(),
275 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_DATE, STR_MAPGEN_DATE_TOOLTIP), SetFill(1, 1),
276 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_TOWN_NAME_LABEL, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 1),
277 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_MAPGEN_NUMBER_OF_TOWNS_TOOLTIP), SetFill(1, 1),
278 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_MAPGEN_NUMBER_OF_INDUSTRIES_TOOLTIP), SetFill(1, 1),
280 EndContainer(),
281
282 /* Right half widgets (global column 4) */
284 /* Climate selector. */
286 /* Snow coverage. */
288 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_DOWN), SetSpriteTip(SPR_ARROW_DOWN, STR_MAPGEN_SNOW_COVERAGE_DOWN_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
289 NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_TEXT), SetToolTip(STR_CONFIG_SETTING_SNOW_COVERAGE_HELPTEXT), SetFill(1, 1),
290 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_UP), SetSpriteTip(SPR_ARROW_UP, STR_MAPGEN_SNOW_COVERAGE_UP_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
291 EndContainer(),
292 /* Desert coverage. */
294 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_DOWN), SetSpriteTip(SPR_ARROW_DOWN, STR_MAPGEN_DESERT_COVERAGE_DOWN_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
295 NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_TEXT), SetToolTip(STR_CONFIG_SETTING_DESERT_COVERAGE_HELPTEXT), SetFill(1, 1),
296 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_UP), SetSpriteTip(SPR_ARROW_UP, STR_MAPGEN_DESERT_COVERAGE_UP_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
297 EndContainer(),
298 /* Temperate/Toyland spacer. */
300 EndContainer(),
301 /* Starting date. */
303 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_DOWN), SetSpriteTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_MOVE_THE_STARTING_DATE_BACKWARD_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
304 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetToolTip(STR_MAPGEN_DATE_TOOLTIP), SetFill(1, 1),
305 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetSpriteTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_MOVE_THE_STARTING_DATE_FORWARD_TOOLTIP), SetFill(0, 1), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
306 EndContainer(),
307 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetToolTip(STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 1),
308 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetToolTip(STR_MAPGEN_NUMBER_OF_TOWNS_TOOLTIP), SetFill(1, 1),
309 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetToolTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES_TOOLTIP), SetFill(1, 1),
311 EndContainer(),
312 EndContainer(),
313 EndContainer(),
314
315 /* AI, GS, and NewGRF settings */
317 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_AI_BUTTON), SetMinimalTextLines(2, 0), SetStringTip(STR_MAPGEN_AI_SETTINGS, STR_MAPGEN_AI_SETTINGS_TOOLTIP), SetFill(1, 0),
318 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_GS_BUTTON), SetMinimalTextLines(2, 0), SetStringTip(STR_MAPGEN_GS_SETTINGS, STR_MAPGEN_GS_SETTINGS_TOOLTIP), SetFill(1, 0),
319 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_NEWGRF_BUTTON), SetMinimalTextLines(2, 0), SetStringTip(STR_MAPGEN_NEWGRF_SETTINGS, STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP), SetFill(1, 0),
320 EndContainer(),
321
322 /* Generate */
323 NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalTextLines(3, 0), SetStringTip(STR_MAPGEN_GENERATE, STR_MAPGEN_GENERATE_TOOLTIP), SetFill(1, 1),
324 EndContainer(),
325 EndContainer(),
326};
327
328static void StartGeneratingLandscape(GenerateLandscapeWindowMode mode)
329{
332
333 /* Copy all XXX_newgame to XXX when coming from outside the editor */
334 MakeNewgameSettingsLive();
335 ResetGRFConfig(true);
336
338 switch (mode) {
339 case GLWM_GENERATE: _switch_mode = (_game_mode == GM_EDITOR) ? SM_GENRANDLAND : SM_NEWGAME; break;
340 case GLWM_HEIGHTMAP: _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_HEIGHTMAP : SM_START_HEIGHTMAP; break;
341 case GLWM_SCENARIO: _switch_mode = SM_EDITOR; break;
342 default: NOT_REACHED();
343 }
344}
345
346static void LandscapeGenerationCallback(Window *w, bool confirmed)
347{
348 if (confirmed) StartGeneratingLandscape(w->window_number);
349}
350
351static DropDownList BuildMapsizeDropDown()
352{
353 DropDownList list;
354
355 for (uint i = MIN_MAP_SIZE_BITS; i <= MAX_MAP_SIZE_BITS; i++) {
356 list.push_back(MakeDropDownListStringItem(GetString(STR_JUST_INT, 1ULL << i), i));
357 }
358
359 return list;
360}
361
362static DropDownList BuildTownNameDropDown()
363{
364 DropDownList list;
365
366 /* Add and sort newgrf townnames generators */
367 const auto &grf_names = GetGRFTownNameList();
368 for (uint i = 0; i < grf_names.size(); i++) {
369 list.push_back(MakeDropDownListStringItem(grf_names[i], BUILTIN_TOWNNAME_GENERATOR_COUNT + i));
370 }
371 std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc);
372
373 size_t newgrf_size = list.size();
374 /* Insert newgrf_names at the top of the list */
375 if (newgrf_size > 0) {
376 list.push_back(MakeDropDownListDividerItem()); // separator line
377 newgrf_size++;
378 }
379
380 /* Add and sort original townnames generators */
381 for (uint i = 0; i < BUILTIN_TOWNNAME_GENERATOR_COUNT; i++) {
382 list.push_back(MakeDropDownListStringItem(STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH + i, i));
383 }
384 std::sort(list.begin() + newgrf_size, list.end(), DropDownListStringItem::NatSortFunc);
385
386 return list;
387}
388
389
390static const StringID _max_height[] = {STR_TERRAIN_TYPE_VERY_FLAT, STR_TERRAIN_TYPE_FLAT, STR_TERRAIN_TYPE_HILLY, STR_TERRAIN_TYPE_MOUNTAINOUS, STR_TERRAIN_TYPE_ALPINIST, STR_TERRAIN_TYPE_CUSTOM};
391static 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};
392static const StringID _rivers[] = {STR_RIVERS_NONE, STR_RIVERS_FEW, STR_RIVERS_MODERATE, STR_RIVERS_LOT};
393static const StringID _borders[] = {STR_MAPGEN_BORDER_RANDOMIZE, STR_MAPGEN_BORDER_MANUAL, STR_MAPGEN_BORDER_INFINITE_WATER};
394static 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};
395static const StringID _rotation[] = {STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE, STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_CLOCKWISE};
396static const StringID _num_towns[] = {STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, STR_NUM_CUSTOM};
397static const StringID _num_inds[] = {STR_FUNDING_ONLY, STR_MINIMAL, STR_NUM_VERY_LOW, STR_NUM_LOW, STR_NUM_NORMAL, STR_NUM_HIGH, STR_NUM_CUSTOM};
398static const StringID _variety[] = {STR_VARIETY_NONE, STR_VARIETY_VERY_LOW, STR_VARIETY_LOW, STR_VARIETY_MEDIUM, STR_VARIETY_HIGH, STR_VARIETY_VERY_HIGH};
399static const StringID _average_height[] = {STR_CONFIG_SETTING_AVERAGE_HEIGHT_AUTO, STR_CONFIG_SETTING_AVERAGE_HEIGHT_LOWLANDS, STR_CONFIG_SETTING_AVERAGE_HEIGHT_NORMAL, STR_CONFIG_SETTING_AVERAGE_HEIGHT_PLATEAUS};
400
401static_assert(std::size(_num_inds) == to_underlying(IndustryDensity::End));
402
403struct GenerateLandscapeWindow : public Window {
404 WidgetID widget_id{};
405 uint x = 0;
406 uint y = 0;
407 EncodedString name{};
409
410 GenerateLandscapeWindow(WindowDesc &desc, WindowNumber number = 0) : Window(desc)
411 {
412 this->InitNested(number);
413
414 this->LowerWidget(to_underlying(_settings_newgame.game_creation.landscape) + WID_GL_TEMPERATE);
415
416 this->mode = this->window_number;
417
418 /* Disable town and industry in SE */
419 this->SetWidgetDisabledState(WID_GL_TOWN_PULLDOWN, _game_mode == GM_EDITOR);
420 this->SetWidgetDisabledState(WID_GL_INDUSTRY_PULLDOWN, _game_mode == GM_EDITOR);
421
422 /* In case the map_height_limit is changed, clamp heightmap_height and custom_terrain_type. */
423 _settings_newgame.game_creation.heightmap_height = Clamp(_settings_newgame.game_creation.heightmap_height, MIN_HEIGHTMAP_HEIGHT, GetMapHeightLimit());
424 _settings_newgame.game_creation.custom_terrain_type = Clamp(_settings_newgame.game_creation.custom_terrain_type, MIN_CUSTOM_TERRAIN_TYPE, GetMapHeightLimit());
425
426 /* If original landgenerator is selected and alpinist terrain_type was selected, revert to mountainous. */
427 if (_settings_newgame.game_creation.land_generator == LG_ORIGINAL) {
428 _settings_newgame.difficulty.terrain_type = Clamp(_settings_newgame.difficulty.terrain_type, GenworldMaxHeight::VeryFlat, GenworldMaxHeight::Mountainous);
429 }
430
431 this->OnInvalidateData();
432 }
433
434
435 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
436 {
437 switch (widget) {
438 case WID_GL_START_DATE_TEXT: return GetString(STR_JUST_DATE_LONG, TimerGameCalendar::ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1));
439 case WID_GL_MAPSIZE_X_PULLDOWN: return GetString(STR_JUST_INT, 1LL << _settings_newgame.game_creation.map_x);
440 case WID_GL_MAPSIZE_Y_PULLDOWN: return GetString(STR_JUST_INT, 1LL << _settings_newgame.game_creation.map_y);
441 case WID_GL_HEIGHTMAP_HEIGHT_TEXT: return GetString(STR_JUST_INT, _settings_newgame.game_creation.heightmap_height);
442 case WID_GL_SNOW_COVERAGE_TEXT: return GetString(STR_MAPGEN_SNOW_COVERAGE_TEXT, _settings_newgame.game_creation.snow_coverage);
443 case WID_GL_DESERT_COVERAGE_TEXT: return GetString(STR_MAPGEN_DESERT_COVERAGE_TEXT, _settings_newgame.game_creation.desert_coverage);
444
446 if (_game_mode == GM_EDITOR) {
447 return GetString(STR_CONFIG_SETTING_OFF);
448 }
449 if (_settings_newgame.difficulty.number_towns == CUSTOM_TOWN_NUMBER_DIFFICULTY) {
450 return GetString(STR_NUM_CUSTOM_NUMBER, _settings_newgame.game_creation.custom_town_number);
451 }
452 return GetString(_num_towns[_settings_newgame.difficulty.number_towns]);
453
455 uint gen = _settings_newgame.game_creation.town_name;
457 STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH + gen :
458 GetGRFTownNameName(gen - BUILTIN_TOWNNAME_GENERATOR_COUNT);
459 return GetString(name);
460 }
461
463 if (_game_mode == GM_EDITOR) {
464 return GetString(STR_CONFIG_SETTING_OFF);
465 }
466 if (_settings_newgame.difficulty.industry_density == IndustryDensity::Custom) {
467 return GetString(STR_NUM_CUSTOM_NUMBER, _settings_newgame.game_creation.custom_industry_number);
468 }
469 return GetString(_num_inds[to_underlying(_settings_newgame.difficulty.industry_density)]);
470
472 if (_settings_newgame.difficulty.terrain_type == GenworldMaxHeight::Custom) {
473 return GetString(STR_TERRAIN_TYPE_CUSTOM_VALUE, _settings_newgame.game_creation.custom_terrain_type);
474 }
475 return GetString(_max_height[to_underlying(_settings_newgame.difficulty.terrain_type)]);
476
478 if (_settings_newgame.difficulty.quantity_sea_lakes == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) {
479 return GetString(STR_SEA_LEVEL_CUSTOM_PERCENTAGE, _settings_newgame.game_creation.custom_sea_level);
480 }
481 return GetString(_sea_lakes[_settings_newgame.difficulty.quantity_sea_lakes]);
482
483 case WID_GL_HEIGHTMAP_NAME_TEXT: return this->name.GetDecodedString();
484 case WID_GL_RIVER_PULLDOWN: return GetString(_rivers[_settings_newgame.game_creation.amount_of_rivers]);
485 case WID_GL_SMOOTHNESS_PULLDOWN: return GetString(_smoothness[_settings_newgame.game_creation.tgen_smoothness]);
486 case WID_GL_VARIETY_PULLDOWN: return GetString(_variety[_settings_newgame.game_creation.variety]);
487 case WID_GL_AVERAGE_HEIGHT_PULLDOWN: return GetString(_average_height[to_underlying(_settings_newgame.game_creation.average_height)]);
488 case WID_GL_BORDERS_PULLDOWN: return GetString(_borders[to_underlying(_settings_newgame.game_creation.water_border_presets)]);
489 case WID_GL_WATER_NE: return GetString((_settings_newgame.game_creation.water_borders == BorderFlag::Random) ? STR_MAPGEN_BORDER_RANDOM : _settings_newgame.game_creation.water_borders.Test(BorderFlag::NorthEast) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM);
490 case WID_GL_WATER_NW: return GetString((_settings_newgame.game_creation.water_borders == BorderFlag::Random) ? STR_MAPGEN_BORDER_RANDOM : _settings_newgame.game_creation.water_borders.Test(BorderFlag::NorthWest) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM);
491 case WID_GL_WATER_SE: return GetString((_settings_newgame.game_creation.water_borders == BorderFlag::Random) ? STR_MAPGEN_BORDER_RANDOM : _settings_newgame.game_creation.water_borders.Test(BorderFlag::SouthEast) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM);
492 case WID_GL_WATER_SW: return GetString((_settings_newgame.game_creation.water_borders == BorderFlag::Random) ? STR_MAPGEN_BORDER_RANDOM : _settings_newgame.game_creation.water_borders.Test(BorderFlag::SouthWest) ? STR_MAPGEN_BORDER_WATER : STR_MAPGEN_BORDER_FREEFORM);
493 case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: return GetString(_rotation[_settings_newgame.game_creation.heightmap_rotation]);
494
496 if (_settings_newgame.game_creation.heightmap_rotation == HM_CLOCKWISE) {
497 return GetString(STR_MAPGEN_HEIGHTMAP_SIZE, this->y, this->x);
498 }
499 return GetString(STR_MAPGEN_HEIGHTMAP_SIZE, this->x, this->y);
500
501 default:
502 return this->Window::GetWidgetString(widget, stringid);
503 }
504 }
505
511 void OnInvalidateData([[maybe_unused]] int data = 0, [[maybe_unused]] bool gui_scope = true) override
512 {
513 if (!gui_scope) return;
514 /* Update the climate buttons */
519
520 /* You can't select smoothness / non-water borders if not terragenesis */
521 if (mode == GLWM_GENERATE) {
523 this->SetWidgetDisabledState(WID_GL_VARIETY_PULLDOWN, _settings_newgame.game_creation.land_generator == LG_ORIGINAL);
524 this->SetWidgetDisabledState(WID_GL_BORDERS_PULLDOWN, _settings_newgame.game_creation.land_generator == LG_ORIGINAL);
525 this->SetWidgetsDisabledState(_settings_newgame.game_creation.land_generator == LG_ORIGINAL || !_settings_newgame.construction.freeform_edges || _settings_newgame.game_creation.water_borders == BorderFlag::Random,
527
528 this->SetWidgetLoweredState(WID_GL_WATER_NW, _settings_newgame.game_creation.water_borders.Test(BorderFlag::NorthWest));
529 this->SetWidgetLoweredState(WID_GL_WATER_NE, _settings_newgame.game_creation.water_borders.Test(BorderFlag::NorthEast));
530 this->SetWidgetLoweredState(WID_GL_WATER_SE, _settings_newgame.game_creation.water_borders.Test(BorderFlag::SouthEast));
531 this->SetWidgetLoweredState(WID_GL_WATER_SW, _settings_newgame.game_creation.water_borders.Test(BorderFlag::SouthWest));
532
533 this->SetWidgetsDisabledState(_settings_newgame.game_creation.land_generator == LG_ORIGINAL && (_settings_newgame.game_creation.landscape == LandscapeType::Arctic || _settings_newgame.game_creation.landscape == LandscapeType::Tropic),
535 }
536
537 /* Disable snowline if not arctic */
539 /* Disable desert if not tropic */
541
542 /* Set snow/rainforest selections */
543 int climate_plane = 0;
544 switch (_settings_newgame.game_creation.landscape) {
545 case LandscapeType::Temperate: climate_plane = 2; break;
546 case LandscapeType::Arctic: climate_plane = 0; break;
547 case LandscapeType::Tropic: climate_plane = 1; break;
548 case LandscapeType::Toyland: climate_plane = 2; break;
549 }
550 this->GetWidget<NWidgetStacked>(WID_GL_CLIMATE_SEL_LABEL)->SetDisplayedPlane(climate_plane);
551 this->GetWidget<NWidgetStacked>(WID_GL_CLIMATE_SEL_SELECTOR)->SetDisplayedPlane(climate_plane);
552
553 /* Update availability of decreasing / increasing start date and snow level */
554 if (mode == GLWM_HEIGHTMAP) {
557 }
560 this->SetWidgetDisabledState(WID_GL_SNOW_COVERAGE_DOWN, _settings_newgame.game_creation.snow_coverage <= 0 || _settings_newgame.game_creation.landscape != LandscapeType::Arctic);
561 this->SetWidgetDisabledState(WID_GL_SNOW_COVERAGE_UP, _settings_newgame.game_creation.snow_coverage >= 100 || _settings_newgame.game_creation.landscape != LandscapeType::Arctic);
562 this->SetWidgetDisabledState(WID_GL_DESERT_COVERAGE_DOWN, _settings_newgame.game_creation.desert_coverage <= 0 || _settings_newgame.game_creation.landscape != LandscapeType::Tropic);
563 this->SetWidgetDisabledState(WID_GL_DESERT_COVERAGE_UP, _settings_newgame.game_creation.desert_coverage >= 100 || _settings_newgame.game_creation.landscape != LandscapeType::Tropic);
564
565 /* Do not allow a custom sea level or terrain type with the original land generator. */
566 if (_settings_newgame.game_creation.land_generator == LG_ORIGINAL) {
567 if (_settings_newgame.difficulty.quantity_sea_lakes == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) {
568 _settings_newgame.difficulty.quantity_sea_lakes = 1;
569 }
570 if (_settings_newgame.difficulty.terrain_type == GenworldMaxHeight::Custom) {
571 _settings_newgame.difficulty.terrain_type = GenworldMaxHeight::Flat;
572 }
573 }
574
575 }
576
577 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
578 {
580 std::span<const StringID> strs;
581 switch (widget) {
584 size.width += WidgetDimensions::scaled.fullbevel.Horizontal();
585 size.height += WidgetDimensions::scaled.fullbevel.Vertical();
586 break;
587
590 break;
591
594 break;
595
599 break;
600
602 d = GetStringBoundingBox(GetString(STR_MAPGEN_SNOW_COVERAGE_TEXT, GetParamMaxValue(MAX_TILE_HEIGHT)));
603 break;
604
606 d = GetStringBoundingBox(GetString(STR_MAPGEN_DESERT_COVERAGE_TEXT, GetParamMaxValue(MAX_TILE_HEIGHT)));
607 break;
608
610 d = GetStringBoundingBox(GetString(STR_MAPGEN_HEIGHTMAP_SIZE, this->x, this->y));
611 break;
612
614 strs = _num_towns;
616 break;
617
619 strs = _num_inds;
621 break;
622
624 strs = _max_height;
625 d = GetStringBoundingBox(GetString(STR_TERRAIN_TYPE_CUSTOM_VALUE, GetParamMaxValue(MAX_MAP_HEIGHT_LIMIT)));
626 break;
627
629 strs = _sea_lakes;
631 break;
632
633 case WID_GL_RIVER_PULLDOWN: strs = _rivers; break;
634 case WID_GL_SMOOTHNESS_PULLDOWN: strs = _smoothness; break;
635 case WID_GL_AVERAGE_HEIGHT_PULLDOWN: strs = _variety; break;
636 case WID_GL_VARIETY_PULLDOWN: strs = _variety; break;
637 case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: strs = _rotation; break;
638 case WID_GL_BORDERS_PULLDOWN: strs = _borders; break;
639 case WID_GL_WATER_NE:
640 case WID_GL_WATER_NW:
641 case WID_GL_WATER_SE:
642 case WID_GL_WATER_SW:
643 d = maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_RANDOM), maxdim(GetStringBoundingBox(STR_MAPGEN_BORDER_WATER), GetStringBoundingBox(STR_MAPGEN_BORDER_FREEFORM)));
644 break;
645
647 size.width = 0;
648 break;
649
650 default:
651 return;
652 }
653 d = maxdim(d, GetStringListBoundingBox(strs));
654 d.width += padding.width;
655 d.height += padding.height;
656 size = maxdim(size, d);
657 }
658
659 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
660 {
661 switch (widget) {
662 case WID_GL_TEMPERATE:
663 case WID_GL_ARCTIC:
664 case WID_GL_TROPICAL:
665 case WID_GL_TOYLAND:
667 SndClickBeep();
668 break;
669
670 case WID_GL_MAPSIZE_X_PULLDOWN: // Mapsize X
671 ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_x, WID_GL_MAPSIZE_X_PULLDOWN);
672 break;
673
674 case WID_GL_MAPSIZE_Y_PULLDOWN: // Mapsize Y
675 ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_y, WID_GL_MAPSIZE_Y_PULLDOWN);
676 break;
677
678 case WID_GL_TOWN_PULLDOWN: // Number of towns
679 ShowDropDownMenu(this, _num_towns, _settings_newgame.difficulty.number_towns, WID_GL_TOWN_PULLDOWN, 0, 0);
680 break;
681
682 case WID_GL_TOWNNAME_DROPDOWN: // Townname generator
683 ShowDropDownList(this, BuildTownNameDropDown(), _settings_newgame.game_creation.town_name, WID_GL_TOWNNAME_DROPDOWN);
684 break;
685
686 case WID_GL_INDUSTRY_PULLDOWN: // Number of industries
687 ShowDropDownMenu(this, _num_inds, to_underlying(_settings_newgame.difficulty.industry_density), WID_GL_INDUSTRY_PULLDOWN, 0, 0);
688 break;
689
690 case WID_GL_GENERATE_BUTTON: { // Generate
691 /* Get rotated map size. */
692 uint map_x;
693 uint map_y;
694 if (_settings_newgame.game_creation.heightmap_rotation == HM_CLOCKWISE) {
695 map_x = this->y;
696 map_y = this->x;
697 } else {
698 map_x = this->x;
699 map_y = this->y;
700 }
701 if (mode == GLWM_HEIGHTMAP &&
702 (map_x * 2 < (1U << _settings_newgame.game_creation.map_x) ||
703 map_x / 2 > (1U << _settings_newgame.game_creation.map_x) ||
704 map_y * 2 < (1U << _settings_newgame.game_creation.map_y) ||
705 map_y / 2 > (1U << _settings_newgame.game_creation.map_y))) {
706 ShowQuery(
707 GetEncodedString(STR_WARNING_HEIGHTMAP_SCALE_CAPTION),
708 GetEncodedString(STR_WARNING_HEIGHTMAP_SCALE_MESSAGE),
709 this,
710 LandscapeGenerationCallback);
711 } else {
712 StartGeneratingLandscape(mode);
713 }
714 break;
715 }
716
718 case WID_GL_HEIGHTMAP_HEIGHT_UP: // Height level buttons
719 /* Don't allow too fast scrolling */
720 if (!this->flags.Test(WindowFlag::Timeout) || this->timeout_timer <= 1) {
721 this->HandleButtonClick(widget);
722
723 _settings_newgame.game_creation.heightmap_height = Clamp(_settings_newgame.game_creation.heightmap_height + widget - WID_GL_HEIGHTMAP_HEIGHT_TEXT, MIN_HEIGHTMAP_HEIGHT, GetMapHeightLimit());
724 this->InvalidateData();
725 }
726 _left_button_clicked = false;
727 break;
728
729 case WID_GL_HEIGHTMAP_HEIGHT_TEXT: // Height level text
730 this->widget_id = WID_GL_HEIGHTMAP_HEIGHT_TEXT;
731 ShowQueryString(GetString(STR_JUST_INT, _settings_newgame.game_creation.heightmap_height), STR_MAPGEN_HEIGHTMAP_HEIGHT_QUERY_CAPT, 4, this, CS_NUMERAL, QueryStringFlag::EnableDefault);
732 SndClickBeep();
733 break;
734
735
737 case WID_GL_START_DATE_UP: // Year buttons
738 /* Don't allow too fast scrolling */
739 if (!this->flags.Test(WindowFlag::Timeout) || this->timeout_timer <= 1) {
740 this->HandleButtonClick(widget);
741
742 _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_GL_START_DATE_TEXT, CalendarTime::MIN_YEAR, CalendarTime::MAX_YEAR);
743 this->InvalidateData();
744 }
745 _left_button_clicked = false;
746 break;
747
748 case WID_GL_START_DATE_TEXT: // Year text
749 this->widget_id = WID_GL_START_DATE_TEXT;
750 ShowQueryString(GetString(STR_JUST_INT, _settings_newgame.game_creation.starting_year), STR_MAPGEN_START_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, QueryStringFlag::EnableDefault);
751 break;
752
754 case WID_GL_SNOW_COVERAGE_UP: // Snow coverage buttons
755 /* Don't allow too fast scrolling */
756 if (!this->flags.Test(WindowFlag::Timeout) || this->timeout_timer <= 1) {
757 this->HandleButtonClick(widget);
758
759 _settings_newgame.game_creation.snow_coverage = Clamp(_settings_newgame.game_creation.snow_coverage + (widget - WID_GL_SNOW_COVERAGE_TEXT) * 10, 0, 100);
760 this->InvalidateData();
761 }
762 _left_button_clicked = false;
763 break;
764
765 case WID_GL_SNOW_COVERAGE_TEXT: // Snow coverage text
766 this->widget_id = WID_GL_SNOW_COVERAGE_TEXT;
767 ShowQueryString(GetString(STR_JUST_INT, _settings_newgame.game_creation.snow_coverage), STR_MAPGEN_SNOW_COVERAGE_QUERY_CAPT, 4, this, CS_NUMERAL, QueryStringFlag::EnableDefault);
768 SndClickBeep();
769 break;
770
772 case WID_GL_DESERT_COVERAGE_UP: // Desert coverage buttons
773 /* Don't allow too fast scrolling */
774 if (!this->flags.Test(WindowFlag::Timeout) || this->timeout_timer <= 1) {
775 this->HandleButtonClick(widget);
776
777 _settings_newgame.game_creation.desert_coverage = Clamp(_settings_newgame.game_creation.desert_coverage + (widget - WID_GL_DESERT_COVERAGE_TEXT) * 10, 0, 100);
778 this->InvalidateData();
779 }
780 _left_button_clicked = false;
781 break;
782
783 case WID_GL_DESERT_COVERAGE_TEXT: // Desert line text
784 this->widget_id = WID_GL_DESERT_COVERAGE_TEXT;
785 ShowQueryString(GetString(STR_JUST_INT, _settings_newgame.game_creation.desert_coverage), STR_MAPGEN_DESERT_COVERAGE_QUERY_CAPT, 4, this, CS_NUMERAL, QueryStringFlag::EnableDefault);
786 SndClickBeep();
787 break;
788
789 case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: // Heightmap rotation
790 ShowDropDownMenu(this, _rotation, _settings_newgame.game_creation.heightmap_rotation, WID_GL_HEIGHTMAP_ROTATION_PULLDOWN, 0, 0);
791 break;
792
793 case WID_GL_MAX_HEIGHT_PULLDOWN: // Max height
794 /* For the original map generation only the first four are valid. */
795 ShowDropDownMenu(this, _max_height, to_underlying(_settings_newgame.difficulty.terrain_type), WID_GL_MAX_HEIGHT_PULLDOWN, 0, _settings_newgame.game_creation.land_generator == LG_ORIGINAL ? ~0xF : 0);
796 break;
797
798 case WID_GL_WATER_PULLDOWN: { // Water quantity
799 uint32_t hidden_mask = 0;
800 /* Disable custom water level when the original map generator is active. */
801 if (_settings_newgame.game_creation.land_generator == LG_ORIGINAL) {
803 }
804 ShowDropDownMenu(this, _sea_lakes, _settings_newgame.difficulty.quantity_sea_lakes, WID_GL_WATER_PULLDOWN, 0, hidden_mask);
805 break;
806 }
807
808 case WID_GL_RIVER_PULLDOWN: // Amount of rivers
809 ShowDropDownMenu(this, _rivers, _settings_newgame.game_creation.amount_of_rivers, WID_GL_RIVER_PULLDOWN, 0, 0);
810 break;
811
812 case WID_GL_SMOOTHNESS_PULLDOWN: // Map smoothness
813 ShowDropDownMenu(this, _smoothness, _settings_newgame.game_creation.tgen_smoothness, WID_GL_SMOOTHNESS_PULLDOWN, 0, 0);
814 break;
815
816 case WID_GL_VARIETY_PULLDOWN: // Map variety
817 ShowDropDownMenu(this, _variety, _settings_newgame.game_creation.variety, WID_GL_VARIETY_PULLDOWN, 0, 0);
818 break;
819
820 case WID_GL_AVERAGE_HEIGHT_PULLDOWN: // Average height
821 ShowDropDownMenu(this, _average_height, to_underlying(_settings_newgame.game_creation.average_height), WID_GL_AVERAGE_HEIGHT_PULLDOWN, 0, 0);
822 break;
823
824 /* Map borders */
826 /* WHen loading a heightmap, hide the first option "Random". */
827 ShowDropDownMenu(this, _borders, to_underlying(_settings_newgame.game_creation.water_border_presets), WID_GL_BORDERS_PULLDOWN, 0, mode == GLWM_HEIGHTMAP ? (1U << 0) : 0);
828 break;
829
830 case WID_GL_WATER_NW:
831 _settings_newgame.game_creation.water_borders.Flip(BorderFlag::NorthWest);
832 SndClickBeep();
833 this->InvalidateData();
834 break;
835
836 case WID_GL_WATER_NE:
837 _settings_newgame.game_creation.water_borders.Flip(BorderFlag::NorthEast);
838 SndClickBeep();
839 this->InvalidateData();
840 break;
841
842 case WID_GL_WATER_SE:
843 _settings_newgame.game_creation.water_borders.Flip(BorderFlag::SouthEast);
844 SndClickBeep();
845 this->InvalidateData();
846 break;
847
848 case WID_GL_WATER_SW:
849 _settings_newgame.game_creation.water_borders.Flip(BorderFlag::SouthWest);
850 SndClickBeep();
851 this->InvalidateData();
852 break;
853
854 case WID_GL_AI_BUTTON:
856 break;
857
858 case WID_GL_GS_BUTTON:
860 break;
861
863 ShowNewGRFSettings(true, true, false, _grfconfig_newgame);
864 break;
865 }
866 }
867
876
877 void OnDropdownSelect(WidgetID widget, int index, int) override
878 {
879 switch (widget) {
880 case WID_GL_MAPSIZE_X_PULLDOWN: _settings_newgame.game_creation.map_x = index; break;
881 case WID_GL_MAPSIZE_Y_PULLDOWN: _settings_newgame.game_creation.map_y = index; break;
882 case WID_GL_RIVER_PULLDOWN: _settings_newgame.game_creation.amount_of_rivers = index; break;
883 case WID_GL_SMOOTHNESS_PULLDOWN: _settings_newgame.game_creation.tgen_smoothness = index; break;
884 case WID_GL_VARIETY_PULLDOWN: _settings_newgame.game_creation.variety = index; break;
885 case WID_GL_AVERAGE_HEIGHT_PULLDOWN: _settings_newgame.game_creation.average_height = static_cast<GenworldAverageHeight>(index); break;
886
887 case WID_GL_HEIGHTMAP_ROTATION_PULLDOWN: _settings_newgame.game_creation.heightmap_rotation = index; break;
888
890 if ((uint)index == CUSTOM_TOWN_NUMBER_DIFFICULTY) {
891 this->widget_id = widget;
892 ShowQueryString(GetString(STR_JUST_INT, _settings_newgame.game_creation.custom_town_number), STR_MAPGEN_NUMBER_OF_TOWNS, 5, this, CS_NUMERAL, {});
893 }
894 _settings_newgame.difficulty.number_towns = index;
895 break;
896
897 case WID_GL_TOWNNAME_DROPDOWN: // Town names
898 if (_game_mode == GM_MENU || Town::GetNumItems() == 0) {
899 _settings_newgame.game_creation.town_name = index;
901 }
902 break;
903
905 if (static_cast<IndustryDensity>(index) == IndustryDensity::Custom) {
906 this->widget_id = widget;
907 ShowQueryString(GetString(STR_JUST_INT, _settings_newgame.game_creation.custom_industry_number), STR_MAPGEN_NUMBER_OF_INDUSTRIES, 5, this, CS_NUMERAL, {});
908 }
909 _settings_newgame.difficulty.industry_density = static_cast<IndustryDensity>(index);
910 break;
911
913 if (static_cast<GenworldMaxHeight>(index) == GenworldMaxHeight::Custom) {
914 this->widget_id = widget;
915 ShowQueryString(GetString(STR_JUST_INT, _settings_newgame.game_creation.custom_terrain_type), STR_MAPGEN_TERRAIN_TYPE_QUERY_CAPT, 4, this, CS_NUMERAL, {});
916 }
917 _settings_newgame.difficulty.terrain_type = static_cast<GenworldMaxHeight>(index);
918 break;
919 }
920
922 switch (static_cast<BorderFlagPresets>(index)) {
923 case BorderFlagPresets::Random:
924 _settings_newgame.game_creation.water_borders = BorderFlag::Random;
925 _settings_newgame.construction.freeform_edges = true;
926 break;
927 case BorderFlagPresets::Manual:
928 _settings_newgame.game_creation.water_borders = {};
929 _settings_newgame.construction.freeform_edges = true;
930 break;
931 case BorderFlagPresets::InfiniteWater:
932 _settings_newgame.game_creation.water_borders = BORDERFLAGS_ALL;
933 _settings_newgame.construction.freeform_edges = false;
934 break;
935 }
936 _settings_newgame.game_creation.water_border_presets = static_cast<BorderFlagPresets>(index);
937 break;
938 }
939
941 if ((uint)index == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) {
942 this->widget_id = widget;
943 ShowQueryString(GetString(STR_JUST_INT, _settings_newgame.game_creation.custom_sea_level), STR_MAPGEN_SEA_LEVEL, 3, this, CS_NUMERAL, {});
944 }
945 _settings_newgame.difficulty.quantity_sea_lakes = index;
946 break;
947 }
948 }
949 this->InvalidateData();
950 }
951
952 void OnQueryTextFinished(std::optional<std::string> str) override
953 {
954 /* Was 'cancel' pressed? */
955 if (!str.has_value()) return;
956
957 int32_t value;
958 if (!str->empty()) {
959 auto val = ParseInteger<int32_t>(*str, 10, true);
960 if (!val.has_value()) return;
961 value = *val;
962 } else {
963 /* An empty string means revert to the default */
964 switch (this->widget_id) {
966 case WID_GL_START_DATE_TEXT: value = CalendarTime::DEF_START_YEAR.base(); break;
967 case WID_GL_SNOW_COVERAGE_TEXT: value = DEF_SNOW_COVERAGE; break;
969 case WID_GL_TOWN_PULLDOWN: value = 1; break;
970 case WID_GL_INDUSTRY_PULLDOWN: value = 1; break;
973 default: NOT_REACHED();
974 }
975 }
976
977 switch (this->widget_id) {
980 _settings_newgame.game_creation.heightmap_height = Clamp(value, MIN_HEIGHTMAP_HEIGHT, GetMapHeightLimit());
981 break;
982
985 _settings_newgame.game_creation.starting_year = Clamp(TimerGameCalendar::Year(value), CalendarTime::MIN_YEAR, CalendarTime::MAX_YEAR);
986 break;
987
990 _settings_newgame.game_creation.snow_coverage = Clamp(value, 0, 100);
991 break;
992
995 _settings_newgame.game_creation.desert_coverage = Clamp(value, 0, 100);
996 break;
997
999 _settings_newgame.game_creation.custom_town_number = Clamp(value, 1, CUSTOM_TOWN_MAX_NUMBER);
1000 break;
1001
1003 _settings_newgame.game_creation.custom_industry_number = Clamp(value, 1, IndustryPool::MAX_SIZE);
1004 break;
1005
1007 _settings_newgame.game_creation.custom_terrain_type = Clamp(value, MIN_CUSTOM_TERRAIN_TYPE, GetMapHeightLimit());
1008 break;
1009
1012 break;
1013 }
1014
1015 this->InvalidateData();
1016 }
1017};
1018
1019static WindowDesc _generate_landscape_desc(
1020 WDP_CENTER, {}, 0, 0,
1022 {},
1024);
1025
1026static WindowDesc _heightmap_load_desc(
1027 WDP_CENTER, {}, 0, 0,
1029 {},
1031);
1032
1033static void _ShowGenerateLandscape(GenerateLandscapeWindowMode mode)
1034{
1035 uint x = 0;
1036 uint y = 0;
1037
1039
1040 /* Generate a new seed when opening the window */
1041 _settings_newgame.game_creation.generation_seed = InteractiveRandom();
1042
1043 if (mode == GLWM_HEIGHTMAP) {
1044 /* If the function returns negative, it means there was a problem loading the heightmap */
1045 if (!GetHeightmapDimensions(_file_to_saveload.ftype.detailed, _file_to_saveload.name, &x, &y)) return;
1046 }
1047
1048 WindowDesc &desc = (mode == GLWM_HEIGHTMAP) ? _heightmap_load_desc : _generate_landscape_desc;
1050
1051 if (mode == GLWM_HEIGHTMAP) {
1052 w->x = x;
1053 w->y = y;
1054 w->name = _file_to_saveload.title;
1055 }
1056
1058}
1059
1062{
1063 _ShowGenerateLandscape(GLWM_GENERATE);
1064}
1065
1068{
1069 _ShowGenerateLandscape(GLWM_HEIGHTMAP);
1070}
1071
1074{
1075 StartGeneratingLandscape(GLWM_SCENARIO);
1076}
1077
1082void StartNewGameWithoutGUI(uint32_t seed)
1083{
1084 /* GenerateWorld takes care of the possible GENERATE_NEW_SEED value in 'seed' */
1085 _settings_newgame.game_creation.generation_seed = seed;
1086
1087 StartGeneratingLandscape(GLWM_GENERATE);
1088}
1089
1090struct CreateScenarioWindow : public Window
1091{
1092 WidgetID widget_id{};
1093
1094 CreateScenarioWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
1095 {
1096 this->InitNested(window_number);
1097 this->LowerWidget(to_underlying(_settings_newgame.game_creation.landscape) + WID_CS_TEMPERATE);
1098 }
1099
1100 std::string GetWidgetString(WidgetID widget, StringID stringid) const override
1101 {
1102 switch (widget) {
1104 return GetString(STR_JUST_DATE_LONG, TimerGameCalendar::ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1));
1105
1107 return GetString(STR_JUST_INT, 1LL << _settings_newgame.game_creation.map_x);
1108
1110 return GetString(STR_JUST_INT, 1LL << _settings_newgame.game_creation.map_y);
1111
1113 return GetString(STR_JUST_INT, _settings_newgame.game_creation.se_flat_world_height);
1114
1115 default:
1116 return this->Window::GetWidgetString(widget, stringid);
1117 }
1118 }
1119
1120 void OnPaint() override
1121 {
1124 this->SetWidgetDisabledState(WID_CS_FLAT_LAND_HEIGHT_DOWN, _settings_newgame.game_creation.se_flat_world_height <= 0);
1125 this->SetWidgetDisabledState(WID_CS_FLAT_LAND_HEIGHT_UP, _settings_newgame.game_creation.se_flat_world_height >= GetMapHeightLimit());
1126
1131
1132 this->DrawWidgets();
1133 }
1134
1135 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
1136 {
1137 std::string str;
1138 switch (widget) {
1141 size.width += WidgetDimensions::scaled.fullbevel.Horizontal();
1142 size.height += WidgetDimensions::scaled.fullbevel.Vertical();
1143 return;
1144
1147 break;
1148
1151 str = GetString(STR_JUST_INT, GetParamMaxValue(MAX_MAP_SIZE));
1152 break;
1153
1155 str = GetString(STR_JUST_INT, GetParamMaxValue(MAX_TILE_HEIGHT));
1156 break;
1157
1158 default:
1159 return;
1160 }
1162 d.width += padding.width;
1163 d.height += padding.height;
1164 size = maxdim(size, d);
1165 }
1166
1167 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1168 {
1169 switch (widget) {
1170 case WID_CS_TEMPERATE:
1171 case WID_CS_ARCTIC:
1172 case WID_CS_TROPICAL:
1173 case WID_CS_TOYLAND:
1174 this->RaiseWidget(to_underlying(_settings_newgame.game_creation.landscape) + WID_CS_TEMPERATE);
1176 break;
1177
1178 case WID_CS_MAPSIZE_X_PULLDOWN: // Mapsize X
1179 ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_x, WID_CS_MAPSIZE_X_PULLDOWN);
1180 break;
1181
1182 case WID_CS_MAPSIZE_Y_PULLDOWN: // Mapsize Y
1183 ShowDropDownList(this, BuildMapsizeDropDown(), _settings_newgame.game_creation.map_y, WID_CS_MAPSIZE_Y_PULLDOWN);
1184 break;
1185
1186 case WID_CS_EMPTY_WORLD: // Empty world / flat world
1187 StartGeneratingLandscape(GLWM_SCENARIO);
1188 break;
1189
1190 case WID_CS_RANDOM_WORLD: // Generate
1192 break;
1193
1195 case WID_CS_START_DATE_UP: // Year buttons
1196 /* Don't allow too fast scrolling */
1197 if (!this->flags.Test(WindowFlag::Timeout) || this->timeout_timer <= 1) {
1198 this->HandleButtonClick(widget);
1199 this->SetDirty();
1200
1201 _settings_newgame.game_creation.starting_year = Clamp(_settings_newgame.game_creation.starting_year + widget - WID_CS_START_DATE_TEXT, CalendarTime::MIN_YEAR, CalendarTime::MAX_YEAR);
1202 }
1203 _left_button_clicked = false;
1204 break;
1205
1206 case WID_CS_START_DATE_TEXT: // Year text
1207 this->widget_id = WID_CS_START_DATE_TEXT;
1208 ShowQueryString(GetString(STR_JUST_INT, _settings_newgame.game_creation.starting_year), STR_MAPGEN_START_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, {});
1209 break;
1210
1212 case WID_CS_FLAT_LAND_HEIGHT_UP: // Height level buttons
1213 /* Don't allow too fast scrolling */
1214 if (!this->flags.Test(WindowFlag::Timeout) || this->timeout_timer <= 1) {
1215 this->HandleButtonClick(widget);
1216 this->SetDirty();
1217
1218 _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, GetMapHeightLimit());
1219 }
1220 _left_button_clicked = false;
1221 break;
1222
1223 case WID_CS_FLAT_LAND_HEIGHT_TEXT: // Height level text
1224 this->widget_id = WID_CS_FLAT_LAND_HEIGHT_TEXT;
1225 ShowQueryString(GetString(STR_JUST_INT, _settings_newgame.game_creation.se_flat_world_height), STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_QUERY_CAPT, 4, this, CS_NUMERAL, {});
1226 break;
1227 }
1228 }
1229
1234
1235 void OnDropdownSelect(WidgetID widget, int index, int) override
1236 {
1237 switch (widget) {
1238 case WID_CS_MAPSIZE_X_PULLDOWN: _settings_newgame.game_creation.map_x = index; break;
1239 case WID_CS_MAPSIZE_Y_PULLDOWN: _settings_newgame.game_creation.map_y = index; break;
1240 }
1241 this->SetDirty();
1242 }
1243
1244 void OnQueryTextFinished(std::optional<std::string> str) override
1245 {
1246 if (!str.has_value()) return;
1247
1248 auto value = ParseInteger<int32_t>(*str, 10, true);
1249 if (!value.has_value()) return;
1250
1251 switch (this->widget_id) {
1254 _settings_newgame.game_creation.starting_year = Clamp(TimerGameCalendar::Year(*value), CalendarTime::MIN_YEAR, CalendarTime::MAX_YEAR);
1255 break;
1256
1259 _settings_newgame.game_creation.se_flat_world_height = Clamp(*value, 0, GetMapHeightLimit());
1260 break;
1261 }
1262
1263 this->SetDirty();
1264 }
1265};
1266
1267static constexpr std::initializer_list<NWidgetPart> _nested_create_scenario_widgets = {
1269 NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
1270 NWidget(WWT_CAPTION, COLOUR_BROWN), SetStringTip(STR_SE_MAPGEN_CAPTION),
1271 EndContainer(),
1272 NWidget(WWT_PANEL, COLOUR_BROWN),
1274 /* Landscape style selection. */
1276 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TEMPERATE), SetSpriteTip(SPR_SELECT_TEMPERATE, STR_INTRO_TOOLTIP_TEMPERATE),
1277 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_ARCTIC), SetSpriteTip(SPR_SELECT_SUB_ARCTIC, STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE),
1278 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TROPICAL), SetSpriteTip(SPR_SELECT_SUB_TROPICAL, STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE),
1279 NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_CS_TOYLAND), SetSpriteTip(SPR_SELECT_TOYLAND, STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE),
1280 EndContainer(),
1281
1283 /* Green generation type buttons: 'Flat land' and 'Random land'. */
1285 NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_CS_EMPTY_WORLD), SetStringTip(STR_SE_MAPGEN_FLAT_WORLD, STR_SE_MAPGEN_FLAT_WORLD_TOOLTIP), SetFill(1, 1),
1286 NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_CS_RANDOM_WORLD), SetStringTip(STR_SE_MAPGEN_RANDOM_LAND, STR_TERRAFORM_TOOLTIP_GENERATE_RANDOM_LAND), SetFill(1, 1),
1287 EndContainer(),
1288
1289 /* Labels + setting drop-downs */
1291 /* Labels. */
1293 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_MAPSIZE, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(0, 1),
1294 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_DATE, STR_MAPGEN_DATE_TOOLTIP), SetFill(0, 1),
1295 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_SE_MAPGEN_FLAT_WORLD_HEIGHT, STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_TOOLTIP), SetFill(0, 1),
1296 EndContainer(),
1297
1299 /* Map size. */
1301 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_CS_MAPSIZE_X_PULLDOWN), SetToolTip(STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
1302 NWidget(WWT_TEXT, INVALID_COLOUR), SetStringTip(STR_MAPGEN_BY), SetFill(0, 1), SetAlignment(SA_CENTER),
1303 NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_CS_MAPSIZE_Y_PULLDOWN), SetToolTip(STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
1304 EndContainer(),
1305
1306 /* Date. */
1308 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_CS_START_DATE_DOWN), SetFill(0, 1), SetSpriteTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_MOVE_THE_STARTING_DATE_BACKWARD_TOOLTIP), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
1309 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CS_START_DATE_TEXT), SetFill(1, 1), SetToolTip(STR_MAPGEN_DATE_TOOLTIP),
1310 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_CS_START_DATE_UP), SetFill(0, 1), SetSpriteTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_MOVE_THE_STARTING_DATE_FORWARD_TOOLTIP), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
1311 EndContainer(),
1312
1313 /* Flat map height. */
1315 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_CS_FLAT_LAND_HEIGHT_DOWN), SetFill(0, 1), SetSpriteTip(SPR_ARROW_DOWN, STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_DOWN_TOOLTIP), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
1316 NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_CS_FLAT_LAND_HEIGHT_TEXT), SetFill(1, 1), SetToolTip(STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_TOOLTIP),
1317 NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_CS_FLAT_LAND_HEIGHT_UP), SetFill(0, 1), SetSpriteTip(SPR_ARROW_UP, STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_UP_TOOLTIP), SetAspect(WidgetDimensions::ASPECT_UP_DOWN_BUTTON),
1318 EndContainer(),
1319 EndContainer(),
1320 EndContainer(),
1321 EndContainer(),
1322 EndContainer(),
1323 EndContainer(),
1324};
1325
1326static WindowDesc _create_scenario_desc(
1327 WDP_CENTER, {}, 0, 0,
1329 {},
1330 _nested_create_scenario_widgets
1331);
1332
1335{
1337 new CreateScenarioWindow(_create_scenario_desc, GLWM_SCENARIO);
1338}
1339
1340static constexpr std::initializer_list<NWidgetPart> _nested_generate_progress_widgets = {
1341 NWidget(WWT_CAPTION, COLOUR_GREY), SetStringTip(STR_GENERATION_WORLD, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
1342 NWidget(WWT_PANEL, COLOUR_GREY),
1344 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_BAR), SetFill(1, 0),
1345 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_TEXT), SetFill(1, 0),
1346 NWidget(WWT_TEXTBTN, COLOUR_WHITE, WID_GP_ABORT), SetStringTip(STR_GENERATION_ABORT), SetFill(1, 0),
1347 EndContainer(),
1348 EndContainer(),
1349};
1350
1351
1352static WindowDesc _generate_progress_desc(
1353 WDP_CENTER, {}, 0, 0,
1356 _nested_generate_progress_widgets
1357);
1358
1360 static inline uint percent;
1361 static inline StringID cls;
1362 static inline uint current;
1363 static inline uint total;
1364};
1365
1366static const StringID _generation_class_table[] = {
1367 STR_GENERATION_WORLD_GENERATION,
1368 STR_GENERATION_LANDSCAPE_GENERATION,
1369 STR_GENERATION_RIVER_GENERATION,
1370 STR_GENERATION_CLEARING_TILES,
1371 STR_GENERATION_TOWN_GENERATION,
1372 STR_GENERATION_LAND_INDUSTRY_GENERATION,
1373 STR_GENERATION_WATER_INDUSTRY_GENERATION,
1374 STR_GENERATION_OBJECT_GENERATION,
1375 STR_GENERATION_TREE_GENERATION,
1376 STR_GENERATION_SETTINGUP_GAME,
1377 STR_GENERATION_PREPARING_TILELOOP,
1378 STR_GENERATION_PREPARING_SCRIPT,
1379 STR_GENERATION_PREPARING_GAME
1380};
1381static_assert(lengthof(_generation_class_table) == GWP_CLASS_COUNT);
1382
1383
1384static void AbortGeneratingWorldCallback(Window *, bool confirmed)
1385{
1386 if (confirmed) {
1388 } else if (HasModalProgress() && !IsGeneratingWorldAborted()) {
1389 SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
1390 }
1391}
1392
1393struct GenerateProgressWindow : public Window {
1394
1395 GenerateProgressWindow() : Window(_generate_progress_desc)
1396 {
1397 this->InitNested();
1398 }
1399
1400 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
1401 {
1402 switch (widget) {
1403 case WID_GP_ABORT:
1404 SetMouseCursorBusy(false);
1405 ShowQuery(
1406 GetEncodedString(STR_GENERATION_ABORT_CAPTION),
1407 GetEncodedString(STR_GENERATION_ABORT_MESSAGE),
1408 this,
1409 AbortGeneratingWorldCallback
1410 );
1411 break;
1412 }
1413 }
1414
1415 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
1416 {
1417 switch (widget) {
1418 case WID_GP_PROGRESS_BAR: {
1419 size = GetStringBoundingBox(GetString(STR_GENERATION_PROGRESS, GetParamMaxValue(100)));
1420 /* We need some spacing for the 'border' */
1421 size.height += WidgetDimensions::scaled.frametext.Horizontal();
1422 size.width += WidgetDimensions::scaled.frametext.Vertical();
1423 break;
1424 }
1425
1427 for (uint i = 0; i < GWP_CLASS_COUNT; i++) {
1428 size.width = std::max(size.width, GetStringBoundingBox(_generation_class_table[i]).width + padding.width);
1429 }
1430 size.height = GetCharacterHeight(FS_NORMAL) * 2 + WidgetDimensions::scaled.vsep_normal;
1431 break;
1432 }
1433 }
1434
1435 void DrawWidget(const Rect &r, WidgetID widget) const override
1436 {
1437 switch (widget) {
1438 case WID_GP_PROGRESS_BAR: {
1439 /* Draw the % complete with a bar and a text */
1441 Rect br = r.Shrink(WidgetDimensions::scaled.bevel);
1442 DrawFrameRect(br.WithWidth(br.Width() * GenWorldStatus::percent / 100, _current_text_dir == TD_RTL), COLOUR_MAUVE, {});
1443 DrawString(br.CentreToHeight(GetCharacterHeight(FS_NORMAL)), GetString(STR_GENERATION_PROGRESS, GenWorldStatus::percent), TC_FROMSTRING, SA_HOR_CENTER);
1444 break;
1445 }
1446
1448 /* Tell which class we are generating */
1449 DrawString(r.left, r.right, r.top, GenWorldStatus::cls, TC_FROMSTRING, SA_HOR_CENTER);
1450
1451 /* And say where we are in that class */
1452 DrawString(r.left, r.right, r.top + GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.vsep_normal,
1453 GetString(STR_GENERATION_PROGRESS_NUM, GenWorldStatus::current, GenWorldStatus::total), TC_FROMSTRING, SA_HOR_CENTER);
1454 }
1455 }
1456};
1457
1462{
1463 GenWorldStatus::cls = STR_GENERATION_WORLD_GENERATION;
1464 GenWorldStatus::current = 0;
1465 GenWorldStatus::total = 0;
1466 GenWorldStatus::percent = 0;
1467}
1468
1477
1478static void _SetGeneratingWorldProgress(GenWorldProgress cls, uint progress, uint total)
1479{
1480 static const int percent_table[] = {0, 5, 14, 17, 20, 40, 55, 60, 65, 80, 85, 95, 99, 100 };
1481 static_assert(lengthof(percent_table) == GWP_CLASS_COUNT + 1);
1482 assert(cls < GWP_CLASS_COUNT);
1483
1484 /* Check if we really are generating the world.
1485 * For example, placing trees via the SE also calls this function, but
1486 * shouldn't try to update the progress.
1487 */
1488 if (!HasModalProgress()) return;
1489
1492 return;
1493 }
1494
1495 if (total == 0) {
1496 assert(GenWorldStatus::cls == _generation_class_table[cls]);
1497 GenWorldStatus::current += progress;
1498 assert(GenWorldStatus::current <= GenWorldStatus::total);
1499 } else {
1500 GenWorldStatus::cls = _generation_class_table[cls];
1501 GenWorldStatus::current = progress;
1502 GenWorldStatus::total = total;
1503 GenWorldStatus::percent = percent_table[cls];
1504 }
1505
1506 /* Percentage is about the number of completed tasks, so 'current - 1' */
1507 GenWorldStatus::percent = percent_table[cls] + (percent_table[cls + 1] - percent_table[cls]) * (GenWorldStatus::current == 0 ? 0 : GenWorldStatus::current - 1) / GenWorldStatus::total;
1508
1509 if (_network_dedicated) {
1510 static uint last_percent = 0;
1511
1512 /* Never display 0% */
1513 if (GenWorldStatus::percent == 0) return;
1514 /* Reset if percent is lower than the last recorded */
1515 if (GenWorldStatus::percent < last_percent) last_percent = 0;
1516 /* Display every 5%, but 6% is also very valid.. just not smaller steps than 5% */
1517 if (GenWorldStatus::percent % 5 != 0 && GenWorldStatus::percent <= last_percent + 5) return;
1518 /* Never show steps smaller than 2%, even if it is a mod 5% */
1519 if (GenWorldStatus::percent <= last_percent + 2) return;
1520
1521 Debug(net, 3, "Map generation percentage complete: {}", GenWorldStatus::percent);
1522 last_percent = GenWorldStatus::percent;
1523
1524 return;
1525 }
1526
1528
1530}
1531
1541{
1542 if (total == 0) return;
1543
1544 _SetGeneratingWorldProgress(cls, 0, total);
1545}
1546
1555{
1556 /* In fact the param 'class' isn't needed.. but for some security reasons, we want it around */
1557 _SetGeneratingWorldProgress(cls, 1, 0);
1558}
void ShowAIConfigWindow()
Open the AI config window.
Definition ai_gui.cpp:334
Window for configuring the AIs.
constexpr T SetBit(T &x, const uint8_t y)
Set a bit in a variable.
static bool NatSortFunc(std::unique_ptr< const DropDownListItem > const &first, std::unique_ptr< const DropDownListItem > const &second)
Container for an encoded string, created by GetEncodedString.
std::string GetDecodedString() const
Decode the encoded string.
Definition strings.cpp:207
static Date ConvertYMDToDate(Year year, Month month, Day day)
Converts a tuple of Year, Month and Day to a Date.
static constexpr TimerGame< struct Calendar >::Year DEF_START_YEAR
static constexpr TimerGame< struct Calendar >::Year MIN_YEAR
static constexpr TimerGame< struct Calendar >::Year MAX_YEAR
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
void GameLoopPause()
Pause the game-loop for a bit, releasing the game-state lock.
static WidgetDimensions scaled
Widget dimensions scaled for current zoom level.
Definition window_gui.h:30
static const WidgetDimensions unscaled
Unscaled widget dimensions.
Definition window_gui.h:93
Functions related to debugging.
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
void ShowDropDownMenu(Window *w, std::span< const StringID > strings, int selected, WidgetID button, uint32_t disabled_mask, uint32_t hidden_mask, uint width)
Show a dropdown menu window near a widget of the parent window.
Definition dropdown.cpp:459
void ShowDropDownList(Window *w, DropDownList &&list, int selected, WidgetID button, uint width, DropDownOptions options)
Show a drop down list.
Definition dropdown.cpp:419
Common drop down list components.
Functions related to the drop down widget.
Types related to the drop down widget.
std::vector< std::unique_ptr< const DropDownListItem > > DropDownList
A drop down list is a collection of drop down list items.
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23).
Definition enum_type.hpp:21
Functions related to errors.
void ClearErrorMessages()
Clear all errors from the queue.
Declarations for savegames operations.
int GetCharacterHeight(FontSize size)
Get height of a character for a given font size.
Definition fontcache.cpp:87
void ShowGSConfigWindow()
Open the GS config window.
Definition game_gui.cpp:425
Window for configuring GS.
void HandleGeneratingWorldAbortion()
Really handle the abortion, i.e.
Definition genworld.cpp:278
void AbortGeneratingWorld()
Initializes the abortion process.
Definition genworld.cpp:261
bool IsGeneratingWorldAborted()
Is the generation being aborted?
Definition genworld.cpp:270
Functions related to world/map generation.
static const uint MAP_HEIGHT_LIMIT_AUTO_MINIMUM
When map height limit is auto, make this the lowest possible map height limit.
Definition genworld.h:52
@ LG_ORIGINAL
The original landscape generator.
Definition genworld.h:21
static const uint CUSTOM_SEA_LEVEL_MAX_PERCENTAGE
Maximum percentage a user can specify for custom sea level.
Definition genworld.h:48
static const uint CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY
Value for custom sea level in difficulty settings.
Definition genworld.h:46
GenWorldProgress
Current stage of world generation process.
Definition genworld.h:59
static const uint CUSTOM_SEA_LEVEL_MIN_PERCENTAGE
Minimum percentage a user can specify for custom sea level.
Definition genworld.h:47
static constexpr std::initializer_list< NWidgetPart > _nested_generate_landscape_widgets
Widgets of GenerateLandscapeWindow when generating world.
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
void ShowGenerateWorldProgress()
Show the window where a user can follow the process of the map generation.
void ShowGenerateLandscape()
Start with a normal game.
void ShowCreateScenario()
Show the window to create a scenario.
static constexpr std::initializer_list< NWidgetPart > _nested_heightmap_load_widgets
Widgets of GenerateLandscapeWindow when loading heightmap.
static uint GetMapHeightLimit()
Get the map height limit, or if set to "auto", the absolute limit.
void SetNewLandscapeType(LandscapeType landscape)
Changes landscape type and sets genworld window dirty.
void StartScenarioEditor()
Start with a scenario editor.
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
Set the total of a stage of the world generation.
void PrepareGenerateWorldProgress()
Initializes the progress counters to the starting point.
GenerateLandscapeWindowMode
Enum for the modes we can generate in.
@ GLWM_GENERATE
Generate new game.
@ GLWM_HEIGHTMAP
Load from heightmap.
@ GLWM_SCENARIO
Generate flat land.
void ShowHeightmapLoad()
Start with loading a heightmap.
void StartNewGameWithoutGUI(uint32_t seed)
Start a normal game without the GUI.
Types related to the genworld widgets.
@ WID_CS_TROPICAL
Select tropical landscape style.
@ WID_CS_TEMPERATE
Select temperate landscape style.
@ WID_CS_MAPSIZE_X_PULLDOWN
Pull-down arrow for x map size.
@ WID_CS_TOYLAND
Select toy-land landscape style.
@ WID_CS_FLAT_LAND_HEIGHT_TEXT
Clickable flat land height value.
@ WID_CS_START_DATE_TEXT
Clickable start date value.
@ WID_CS_START_DATE_DOWN
Decrease start year (start earlier).
@ WID_CS_EMPTY_WORLD
Generate an empty flat world.
@ WID_CS_ARCTIC
Select arctic landscape style.
@ WID_CS_MAPSIZE_Y_PULLDOWN
Pull-down arrow for y map size.
@ WID_CS_FLAT_LAND_HEIGHT_DOWN
Decrease flat land height.
@ WID_CS_FLAT_LAND_HEIGHT_UP
Increase flat land height.
@ WID_CS_RANDOM_WORLD
Generate random land button.
@ WID_CS_START_DATE_UP
Increase start year (start later).
@ WID_GL_TOWNNAME_DROPDOWN
Dropdown 'Townnames'.
@ WID_GL_WATER_SE
SE 'Water'/'Freeform'.
@ WID_GL_WATER_PULLDOWN
Dropdown 'Sea level'.
@ WID_GL_MAPSIZE_X_PULLDOWN
Dropdown 'map X size'.
@ WID_GL_SNOW_COVERAGE_TEXT
Snow coverage.
@ WID_GL_WATER_NE
NE 'Water'/'Freeform'.
@ WID_GL_VARIETY_PULLDOWN
Dropdown 'Variety distribution'.
@ WID_GL_TOYLAND
Button with icon "Toyland".
@ WID_GL_GENERATE_BUTTON
'Generate' button.
@ WID_GL_ARCTIC
Button with icon "Arctic".
@ WID_GL_HEIGHTMAP_HEIGHT_TEXT
Max. heightmap highest mountain.
@ WID_GL_HEIGHTMAP_ROTATION_PULLDOWN
Dropdown 'Heightmap rotation'.
@ WID_GL_MAPSIZE_Y_PULLDOWN
Dropdown 'map Y size'.
@ WID_GL_TROPICAL
Button with icon "Tropical".
@ WID_GL_HEIGHTMAP_NAME_TEXT
Heightmap name.
@ WID_GL_RIVER_PULLDOWN
Dropdown 'Rivers'.
@ WID_GL_DESERT_COVERAGE_TEXT
Desert coverage.
@ WID_GL_AI_BUTTON
'AI Settings' button.
@ WID_GL_SNOW_COVERAGE_DOWN
Decrease snow coverage.
@ WID_GL_HEIGHTMAP_HEIGHT_UP
Increase max. heightmap highest mountain.
@ WID_GL_NEWGRF_BUTTON
'NewGRF Settings' button.
@ WID_GL_CLIMATE_SEL_LABEL
NWID_SELECTION for snow or desert coverage label.
@ WID_GL_HEIGHTMAP_SIZE_TEXT
Size of heightmap.
@ WID_GL_AVERAGE_HEIGHT_PULLDOWN
Dropdown 'Average height'.
@ WID_GL_WATER_NW
NW 'Water'/'Freeform'.
@ WID_GL_BORDERS_PULLDOWN
Dropdown 'Map edges'.
@ WID_GL_TEMPERATE
Button with icon "Temperate".
@ WID_GL_SMOOTHNESS_PULLDOWN
Dropdown 'Smoothness'.
@ WID_GL_GS_BUTTON
'Game Script Settings' button.
@ WID_GL_START_DATE_DOWN
Decrease start year.
@ WID_GL_START_DATE_TEXT
Start year.
@ WID_GL_CLIMATE_SEL_SELECTOR
NWID_SELECTION for snow or desert coverage selector.
@ WID_GL_DESERT_COVERAGE_UP
Increase desert coverage.
@ WID_GL_TOWN_PULLDOWN
Dropdown 'No. of towns'.
@ WID_GL_MAX_HEIGHT_PULLDOWN
Dropdown 'Maximum height'.
@ WID_GL_HEIGHTMAP_HEIGHT_DOWN
Decrease heightmap highest mountain.
@ WID_GL_WATER_SW
SW 'Water'/'Freeform'.
@ WID_GL_SNOW_COVERAGE_UP
Increase snow coverage.
@ WID_GL_INDUSTRY_PULLDOWN
Dropdown 'No. of industries'.
@ WID_GL_DESERT_COVERAGE_DOWN
Decrease desert coverage.
@ WID_GL_START_DATE_UP
Increase start year.
@ WID_GP_PROGRESS_TEXT
Text with the progress bar.
@ WID_GP_PROGRESS_BAR
Progress bar.
@ WID_GP_ABORT
Abort button.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
Geometry functions.
void SetMouseCursor(CursorID sprite, PaletteID pal)
Assign a single non-animated sprite to the cursor.
Definition gfx.cpp:1711
Dimension GetStringBoundingBox(std::string_view str, FontSize start_fontsize)
Return the string dimension in pixels.
Definition gfx.cpp:900
Dimension GetStringListBoundingBox(std::span< const StringID > list, FontSize fontsize)
Get maximum dimension of a list of strings.
Definition gfx.cpp:939
int DrawString(int left, int right, int top, std::string_view str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
Definition gfx.cpp:669
bool _left_button_clicked
Is left mouse button clicked?
Definition gfx.cpp:43
void SetMouseCursorBusy(bool busy)
Set or unset the ZZZ cursor.
Definition gfx.cpp:1695
SwitchMode _switch_mode
The next mainloop command.
Definition gfx.cpp:50
@ FS_NORMAL
Index of the normal font in the font tables.
Definition gfx_type.h:249
@ SA_RIGHT
Right align the text (must be a single bit).
Definition gfx_type.h:390
@ SA_HOR_CENTER
Horizontally center the text.
Definition gfx_type.h:389
@ SA_CENTER
Center both horizontally and vertically.
Definition gfx_type.h:398
@ SA_VERT_CENTER
Vertically center the text.
Definition gfx_type.h:394
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
constexpr NWidgetPart SetSpriteTip(SpriteID sprite, StringID tip={})
Widget part function for setting the sprite and tooltip.
constexpr NWidgetPart SetPIP(uint8_t pre, uint8_t inter, uint8_t post)
Widget part function for setting a pre/inter/post spaces.
constexpr NWidgetPart SetPadding(uint8_t top, uint8_t right, uint8_t bottom, uint8_t left)
Widget part function for setting additional space around a widget.
constexpr NWidgetPart SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
constexpr NWidgetPart SetAspect(float ratio, AspectFlags flags=AspectFlag::ResizeX)
Widget part function for setting the aspect ratio.
constexpr NWidgetPart SetTextStyle(TextColour colour, FontSize size=FS_NORMAL)
Widget part function for setting the text style.
constexpr NWidgetPart SetToolTip(StringID tip)
Widget part function for setting tooltip and clearing the widget data.
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=INVALID_WIDGET)
Widget part function for starting a new 'real' widget.
constexpr NWidgetPart SetMinimalTextLines(uint8_t lines, uint8_t spacing, FontSize size=FS_NORMAL)
Widget part function for setting the minimal text lines.
constexpr NWidgetPart SetAlignment(StringAlignment align)
Widget part function for setting the alignment of text/images.
constexpr NWidgetPart SetPIPRatio(uint8_t ratio_pre, uint8_t ratio_inter, uint8_t ratio_post)
Widget part function for setting a pre/inter/post ratio.
void SetDirty() const
Mark entire window as dirty (in need of re-paint).
Definition window.cpp:967
bool GetHeightmapDimensions(DetailedFileType dft, std::string_view filename, uint *x, uint *y)
Get the dimensions of a heightmap.
Functions related to creating heightmaps from files.
@ HM_CLOCKWISE
Rotate the map clockwise 45 degrees.
Definition heightmap.h:21
Base of all industries.
static constexpr BorderFlags BORDERFLAGS_ALL
Border on all sides.
LandscapeType
Landscape types.
@ Arctic
Landscape with snow levels.
@ Toyland
Landscape with funky industries and vehicles.
@ Tropic
Landscape with distinct rainforests and deserts,.
@ Temperate
Base landscape.
@ NorthWest
Border on North West.
@ Random
Randomise borders.
@ NorthEast
Border on North East.
@ SouthEast
Border on South East.
@ SouthWest
Border on South West.
#define Point
Macro that prevents name conflicts between included headers.
static const uint MIN_MAP_SIZE_BITS
Minimal and maximal map width and height.
Definition map_type.h:37
static const uint MAX_MAP_SIZE
Maximal map size = 4096.
Definition map_type.h:40
static const uint MAX_MAP_SIZE_BITS
Maximal size of map is equal to 2 ^ MAX_MAP_SIZE_BITS.
Definition map_type.h:38
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
void ShowQuery(EncodedString &&caption, EncodedString &&message, Window *parent, QueryCallbackProc *callback, bool focus)
Show a confirmation window with standard 'yes' and 'no' buttons The window is aligned to the centre o...
void ShowQueryString(std::string_view str, StringID caption, uint maxsize, Window *parent, CharSetFilter afilter, QueryStringFlags flags)
Show a query popup window with a textbox in it.
bool _network_dedicated
are we a dedicated server?
Definition network.cpp:69
Basic functions/variables used all over the place.
void ResetGRFConfig(bool defaults)
Reset the current GRF Config to either blank or newgame settings.
GRFConfigList _grfconfig_newgame
First item in list of default GRF set up.
void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfigList &config)
Setup the NewGRF gui.
Header of Action 0F "universal holder" structure and functions.
@ SM_START_HEIGHTMAP
Load a heightmap and start a new game from it.
Definition openttd.h:38
@ SM_GENRANDLAND
Generate random land within scenario editor.
Definition openttd.h:36
@ SM_LOAD_HEIGHTMAP
Load heightmap from scenario editor.
Definition openttd.h:39
@ SM_EDITOR
Switch to scenario editor.
Definition openttd.h:31
@ SM_NEWGAME
New Game --> 'Random game'.
Definition openttd.h:28
Functions related to modal progress.
bool HasModalProgress()
Check if we are currently in a modal progress state.
Definition progress.h:17
Base for the GUIs that have an edit box in them.
Pseudo random number generator.
A number of safeguards to prevent using unsafe methods.
FileToSaveLoad _file_to_saveload
File to save or load in the openttd loop.
Definition saveload.cpp:78
Functions/types related to saving and loading games.
GameSettings _settings_newgame
Game settings for new games (updated from the intro screen).
Definition settings.cpp:62
IndustryDensity
Available industry map generation densities.
@ End
Number of industry density settings.
@ Custom
Custom number of industries.
BorderFlagPresets
Possible options for the Borders pulldown in the Genworld GUI.
GenworldAverageHeight
Possible options for the Average Height pulldown in the Genworld GUI.
GenworldMaxHeight
Possible options for the Maximum Height pulldown in the Genworld GUI.
void SndConfirmBeep()
Play a beep sound for a confirm event if enabled in settings.
Definition sound.cpp:261
void SndClickBeep()
Play a beep sound for a click event if enabled in settings.
Definition sound.cpp:253
Functions related to sound.
Definition of base types and functions in a cross-platform compatible way.
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
Parse strings.
static std::optional< T > ParseInteger(std::string_view arg, int base=10, bool clamp=false)
Change a string into its number representation.
Functions related to low-level strings.
@ CS_NUMERAL
Only numeric ones.
Definition string_type.h:26
uint64_t GetParamMaxValue(uint64_t max_value, uint min_count, FontSize size)
Get some number that is suitable for string size computations.
Definition strings.cpp:236
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
std::string GetString(StringID string)
Resolve the given StringID into a std::string with formatting but no parameters.
Definition strings.cpp:424
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static constexpr uint32_t BUILTIN_TOWNNAME_GENERATOR_COUNT
The number of builtin generators for town names.
@ TD_RTL
Text is written right-to-left by default.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
void OnDropdownSelect(WidgetID widget, int index, int) override
A dropdown option associated to this window has been selected.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
void OnPaint() override
The window must be repainted.
void OnTimeout() override
Called when this window's timeout has been reached.
Dimensions (a width and height) of a rectangle in 2D.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
void OnDropdownSelect(WidgetID widget, int index, int) override
A dropdown option associated to this window has been selected.
void OnTimeout() override
Called when this window's timeout has been reached.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
std::string GetWidgetString(WidgetID widget, StringID stringid) const override
Get the raw string for a widget.
void OnQueryTextFinished(std::optional< std::string > str) override
The query window opened from this window has closed.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
void UpdateWidgetSize(WidgetID widget, Dimension &size, const Dimension &padding, Dimension &fill, Dimension &resize) override
Update size and resize step of a widget in the window.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
static constexpr size_t MAX_SIZE
Specification of a rectangle with absolute coordinates of all edges.
Rect Shrink(int s) const
Copy and shrink Rect by s pixels.
High level window description.
Definition window_gui.h:168
Number to differentiate different windows of the same class.
Data structure for an opened window.
Definition window_gui.h:274
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:766
void InvalidateData(int data=0, bool gui_scope=true)
Mark this window's data as invalid (in need of re-computing).
Definition window.cpp:3247
void RaiseWidget(WidgetID widget_index)
Marks a widget as raised.
Definition window_gui.h:470
void SetWidgetDirty(WidgetID widget_index) const
Invalidate a widget, i.e.
Definition window.cpp:557
virtual std::string GetWidgetString(WidgetID widget, StringID stringid) const
Get the raw string for a widget.
Definition window.cpp:505
ResizeInfo resize
Resize information.
Definition window_gui.h:315
void SetWidgetsDisabledState(bool disab_stat, Args... widgets)
Sets the enabled/disabled status of a list of widgets.
Definition window_gui.h:516
void SetWidgetLoweredState(WidgetID widget_index, bool lowered_stat)
Sets the lowered/raised status of a widget.
Definition window_gui.h:442
void RaiseWidgetsWhenLowered(Args... widgets)
Raises the widgets and sets widgets dirty that are lowered.
Definition window_gui.h:537
Window(WindowDesc &desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition window.cpp:1832
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:986
void LowerWidget(WidgetID widget_index)
Marks a widget as lowered.
Definition window_gui.h:461
void HandleButtonClick(WidgetID widget)
Do all things to make a button look clicked and mark it to be unclicked in a few ticks.
Definition window.cpp:596
void InitNested(WindowNumber number=0)
Perform complete initialization of the Window with nested widgets, to allow use.
Definition window.cpp:1822
WindowFlags flags
Window flags.
Definition window_gui.h:301
void SetWidgetDisabledState(WidgetID widget_index, bool disab_stat)
Sets the enabled/disabled status of a widget.
Definition window_gui.h:382
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:312
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:303
@ EnableDefault
enable the 'Default' button ("\0" is returned)
Definition textbuf_gui.h:20
static constexpr uint MAX_TILE_HEIGHT
Maximum allowed tile height.
Definition tile_type.h:24
static constexpr uint MIN_CUSTOM_TERRAIN_TYPE
Lowest possible peak value for world generation.
Definition tile_type.h:27
static constexpr uint DEF_DESERT_COVERAGE
Default desert coverage.
Definition tile_type.h:37
static constexpr uint MIN_MAP_HEIGHT_LIMIT
Lower bound of maximum allowed heightlevel (in the construction settings).
Definition tile_type.h:29
static constexpr uint MAX_MAP_HEIGHT_LIMIT
Upper bound of maximum allowed heightlevel (in the construction settings).
Definition tile_type.h:30
static constexpr uint MIN_HEIGHTMAP_HEIGHT
Lowest possible peak value for heightmap creation.
Definition tile_type.h:26
static constexpr uint DEF_SNOW_COVERAGE
Default snow coverage.
Definition tile_type.h:36
Definition of the game-calendar-timer.
Base of the town class.
static const uint CUSTOM_TOWN_MAX_NUMBER
this is the maximum number of towns a user can specify in customisation
Definition town.h:30
static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY
value for custom town number in difficulty settings
Definition town.h:29
Definition of structures used for generating town names.
Base of all video drivers.
void DrawFrameRect(int left, int top, int right, int bottom, Colours colour, FrameFlags flags)
Draw frame rectangle.
Definition widget.cpp:289
@ WWT_PUSHTXTBTN
Normal push-button (no toggle button) with text caption.
@ WWT_IMGBTN
(Toggle) Button with image
Definition widget_type.h:41
@ WWT_IMGBTN_2
(Toggle) Button with diff image when clicked
Definition widget_type.h:42
@ NWID_SPACER
Invisible widget that takes some space.
Definition widget_type.h:70
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:66
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:44
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:39
@ WWT_CAPTION
Window caption (window title between closebox and stickybox).
Definition widget_type.h:52
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:68
@ WWT_CLOSEBOX
Close box (at top-left of a window).
Definition widget_type.h:60
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition widget_type.h:37
@ WWT_DROPDOWN
Drop down list.
Definition widget_type.h:61
@ WWT_TEXT
Pure simple text.
Definition widget_type.h:49
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:71
@ EqualSize
Containers should keep all their (resizing) children equally large.
void CloseWindowByClass(WindowClass cls, int data)
Close all windows of a given class.
Definition window.cpp:1209
Window * BringWindowToFrontById(WindowClass cls, WindowNumber number)
Find a window and make it the relative top-window on the screen.
Definition window.cpp:1280
void CloseAllNonVitalWindows()
It is possible that a stickied window gets to a position where the 'close' button is outside the gami...
Definition window.cpp:3369
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting).
Definition window.cpp:3185
void InvalidateWindowClassesData(WindowClass cls, int data, bool gui_scope)
Mark window data of all windows of a given class as invalid (in need of re-computing) Note that by de...
Definition window.cpp:3325
Window functions not directly related to making/drawing windows.
@ NoClose
This window can't be interactively closed.
Definition window_gui.h:156
@ BorderOnly
Draw border only, no background.
Definition window_gui.h:26
@ Lowered
If set the frame is lowered and the background colour brighter (ie. buttons when pressed).
Definition window_gui.h:27
Twindow * AllocateWindowDescFront(WindowDesc &desc, WindowNumber window_number, Targs... extra_arguments)
Open a new window.
@ Timeout
Window timeout counter.
Definition window_gui.h:227
@ WDP_CENTER
Center the window.
Definition window_gui.h:145
int WidgetID
Widget ID.
Definition window_type.h:20
@ WN_GAME_OPTIONS_GAME_OPTIONS
Game options.
Definition window_type.h:31
@ WC_SELECT_GAME
Select game window; Window numbers:
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:50
@ WC_GENERATE_LANDSCAPE
Generate landscape (newgame); Window numbers:
@ WC_GAME_OPTIONS
Game options window; Window numbers:
@ WC_MODAL_PROGRESS
Progress report of landscape generation; Window numbers: