src/genworld_gui.cpp
changeset 9179 780666b686ed
parent 9164 18e971e0b44f
child 9203 082fbf0500c4
equal deleted inserted replaced
9178:3235f895bf12 9179:780666b686ed
    27 #include "settings_type.h"
    27 #include "settings_type.h"
    28 #include "widgets/dropdown_type.h"
    28 #include "widgets/dropdown_type.h"
    29 #include "widgets/dropdown_func.h"
    29 #include "widgets/dropdown_func.h"
    30 #include "core/random_func.hpp"
    30 #include "core/random_func.hpp"
    31 #include "landscape_type.h"
    31 #include "landscape_type.h"
       
    32 #include "querystring_gui.h"
    32 
    33 
    33 #include "table/strings.h"
    34 #include "table/strings.h"
    34 #include "table/sprites.h"
    35 #include "table/sprites.h"
    35 
    36 
    36 /**
    37 /**
    41 	GLWP_HEIGHTMAP,
    42 	GLWP_HEIGHTMAP,
    42 	GLWP_SCENARIO,
    43 	GLWP_SCENARIO,
    43 	GLWP_END
    44 	GLWP_END
    44 };
    45 };
    45 
    46 
    46 struct generate_d {
       
    47 	uint widget_id;
       
    48 	uint x;
       
    49 	uint y;
       
    50 	char name[64];
       
    51 };
       
    52 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(generate_d));
       
    53 
       
    54 extern void SwitchMode(int new_mode);
    47 extern void SwitchMode(int new_mode);
    55 
    48 
    56 static inline void SetNewLandscapeType(byte landscape)
    49 static inline void SetNewLandscapeType(byte landscape)
    57 {
    50 {
    58 	_opt_newgame.landscape = landscape;
    51 	_opt_newgame.landscape = landscape;
   242 	}
   235 	}
   243 
   236 
   244 	return list;
   237 	return list;
   245 }
   238 }
   246 
   239 
   247 static void GenerateLandscapeWndProc(Window *w, WindowEvent *e)
   240 static const StringID _elevations[]  = {STR_682A_VERY_FLAT, STR_682B_FLAT, STR_682C_HILLY, STR_682D_MOUNTAINOUS, INVALID_STRING_ID};
   248 {
   241 static const StringID _sea_lakes[]   = {STR_VERY_LOW, STR_6820_LOW, STR_6821_MEDIUM, STR_6822_HIGH, INVALID_STRING_ID};
   249 	static const StringID elevations[]  = {STR_682A_VERY_FLAT, STR_682B_FLAT, STR_682C_HILLY, STR_682D_MOUNTAINOUS, INVALID_STRING_ID};
   242 static const StringID _smoothness[]  = {STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH, INVALID_STRING_ID};
   250 	static const StringID sea_lakes[]   = {STR_VERY_LOW, STR_6820_LOW, STR_6821_MEDIUM, STR_6822_HIGH, INVALID_STRING_ID};
   243 static const StringID _tree_placer[] = {STR_CONFIG_PATCHES_TREE_PLACER_NONE, STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL, STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED, INVALID_STRING_ID};
   251 	static const StringID smoothness[]  = {STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_SMOOTH, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_ROUGH, STR_CONFIG_PATCHES_ROUGHNESS_OF_TERRAIN_VERY_ROUGH, INVALID_STRING_ID};
   244 static const StringID _rotation[]    = {STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE, STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE, INVALID_STRING_ID};
   252 	static const StringID tree_placer[] = {STR_CONFIG_PATCHES_TREE_PLACER_NONE, STR_CONFIG_PATCHES_TREE_PLACER_ORIGINAL, STR_CONFIG_PATCHES_TREE_PLACER_IMPROVED, INVALID_STRING_ID};
   245 static const StringID _landscape[]   = {STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL, STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS, INVALID_STRING_ID};
   253 	static const StringID rotation[]    = {STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE, STR_CONFIG_PATCHES_HEIGHTMAP_ROTATION_CLOCKWISE, INVALID_STRING_ID};
   246 static const StringID _num_towns[]   = {STR_NUM_VERY_LOW, STR_6816_LOW, STR_6817_NORMAL, STR_6818_HIGH, INVALID_STRING_ID};
   254 	static const StringID landscape[]   = {STR_CONFIG_PATCHES_LAND_GENERATOR_ORIGINAL, STR_CONFIG_PATCHES_LAND_GENERATOR_TERRA_GENESIS, INVALID_STRING_ID};
   247 static const StringID _num_inds[]    = {STR_NONE, STR_NUM_VERY_LOW, STR_6816_LOW, STR_6817_NORMAL, STR_6818_HIGH, INVALID_STRING_ID};
   255 	static const StringID num_towns[]   = {STR_NUM_VERY_LOW, STR_6816_LOW, STR_6817_NORMAL, STR_6818_HIGH, INVALID_STRING_ID};
   248 
   256 	static const StringID num_inds[]    = {STR_NONE, STR_NUM_VERY_LOW, STR_6816_LOW, STR_6817_NORMAL, STR_6818_HIGH, INVALID_STRING_ID};
   249 struct GenerateLandscapeWindow : public QueryStringBaseWindow {
   257 
   250 	uint widget_id;
   258 	/* Data used for the generate seed edit box */
   251 	uint x;
   259 	static querystr_d _genseed_query;
   252 	uint y;
   260 	static char _genseed_buffer[11];
   253 	char name[64];
   261 
   254 	glwp_modes mode;
   262 	glwp_modes mode = (glwp_modes)w->window_number;
   255 
   263 
   256 	GenerateLandscapeWindow(const WindowDesc *desc, void *data = NULL, WindowNumber number = 0) : QueryStringBaseWindow(desc, NULL, number)
   264 	switch (e->event) {
   257 	{
   265 		case WE_CREATE:
   258 		this->LowerWidget(_opt_newgame.landscape + GLAND_TEMPERATE);
   266 			w->LowerWidget(_opt_newgame.landscape + GLAND_TEMPERATE);
   259 
   267 
   260 		snprintf(this->edit_str_buf, sizeof(this->edit_str_buf), "%u", _patches_newgame.generation_seed);
   268 			snprintf(_genseed_buffer, sizeof(_genseed_buffer), "%u", _patches_newgame.generation_seed);
   261 		InitializeTextBuffer(&this->text, this->edit_str_buf, lengthof(this->edit_str_buf), 120);
   269 			InitializeTextBuffer(&_genseed_query.text, _genseed_buffer, lengthof(_genseed_buffer), 120);
   262 		this->caption = STR_NULL;
   270 			_genseed_query.caption = STR_NULL;
   263 		this->afilter = CS_NUMERAL;
   271 			_genseed_query.afilter = CS_NUMERAL;
   264 
   272 			break;
   265 		this->mode = (glwp_modes)this->window_number;
   273 
   266 
   274 		case WE_PAINT:
   267 		this->FindWindowPlacementAndResize(desc);
   275 			/* You can't select smoothness if not terragenesis */
   268 	}
   276 			if (mode == GLWP_GENERATE) {
   269 
   277 				w->SetWidgetDisabledState(GLAND_SMOOTHNESS_PULLDOWN, _patches_newgame.land_generator == 0);
   270 	virtual void OnPaint()
       
   271 	{
       
   272 		/* You can't select smoothness if not terragenesis */
       
   273 		if (mode == GLWP_GENERATE) {
       
   274 			this->SetWidgetDisabledState(GLAND_SMOOTHNESS_PULLDOWN, _patches_newgame.land_generator == 0);
       
   275 		}
       
   276 		/* Disable snowline if not hilly */
       
   277 		this->SetWidgetDisabledState(GLAND_SNOW_LEVEL_TEXT, _opt_newgame.landscape != LT_ARCTIC);
       
   278 		/* Disable town, industry and trees in SE */
       
   279 		this->SetWidgetDisabledState(GLAND_TOWN_PULLDOWN,     _game_mode == GM_EDITOR);
       
   280 		this->SetWidgetDisabledState(GLAND_INDUSTRY_PULLDOWN, _game_mode == GM_EDITOR);
       
   281 		this->SetWidgetDisabledState(GLAND_TREE_PULLDOWN,     _game_mode == GM_EDITOR);
       
   282 
       
   283 		this->SetWidgetDisabledState(GLAND_START_DATE_DOWN, _patches_newgame.starting_year <= MIN_YEAR);
       
   284 		this->SetWidgetDisabledState(GLAND_START_DATE_UP,   _patches_newgame.starting_year >= MAX_YEAR);
       
   285 		this->SetWidgetDisabledState(GLAND_SNOW_LEVEL_DOWN, _patches_newgame.snow_line_height <= 2 || _opt_newgame.landscape != LT_ARCTIC);
       
   286 		this->SetWidgetDisabledState(GLAND_SNOW_LEVEL_UP,   _patches_newgame.snow_line_height >= MAX_SNOWLINE_HEIGHT || _opt_newgame.landscape != LT_ARCTIC);
       
   287 
       
   288 		this->SetWidgetLoweredState(GLAND_TEMPERATE, _opt_newgame.landscape == LT_TEMPERATE);
       
   289 		this->SetWidgetLoweredState(GLAND_ARCTIC,    _opt_newgame.landscape == LT_ARCTIC);
       
   290 		this->SetWidgetLoweredState(GLAND_TROPICAL,  _opt_newgame.landscape == LT_TROPIC);
       
   291 		this->SetWidgetLoweredState(GLAND_TOYLAND,   _opt_newgame.landscape == LT_TOYLAND);
       
   292 
       
   293 		if (_game_mode == GM_EDITOR) {
       
   294 			this->widget[GLAND_TOWN_PULLDOWN].data     = STR_6836_OFF;
       
   295 			this->widget[GLAND_INDUSTRY_PULLDOWN].data = STR_6836_OFF;
       
   296 		} else {
       
   297 			this->widget[GLAND_TOWN_PULLDOWN].data     = _num_towns[_opt_newgame.diff.number_towns];
       
   298 			this->widget[GLAND_INDUSTRY_PULLDOWN].data = _num_inds[_opt_newgame.diff.number_industries];
       
   299 		}
       
   300 
       
   301 		if (mode == GLWP_GENERATE) {
       
   302 			this->widget[GLAND_LANDSCAPE_PULLDOWN].data  = _landscape[_patches_newgame.land_generator];
       
   303 			this->widget[GLAND_TREE_PULLDOWN].data       = _tree_placer[_patches_newgame.tree_placer];
       
   304 			this->widget[GLAND_TERRAIN_PULLDOWN].data    = _elevations[_opt_newgame.diff.terrain_type];
       
   305 			this->widget[GLAND_WATER_PULLDOWN].data      = _sea_lakes[_opt_newgame.diff.quantity_sea_lakes];
       
   306 			this->widget[GLAND_SMOOTHNESS_PULLDOWN].data = _smoothness[_patches_newgame.tgen_smoothness];
       
   307 		} else {
       
   308 			this->widget[GLAND_TREE_PULLDOWN].data               = _tree_placer[_patches_newgame.tree_placer];
       
   309 			this->widget[GLAND_HEIGHTMAP_ROTATION_PULLDOWN].data = _rotation[_patches_newgame.heightmap_rotation];
       
   310 		}
       
   311 
       
   312 		/* Set parameters for widget text that requires them. */
       
   313 		SetDParam(0, ConvertYMDToDate(_patches_newgame.starting_year, 0, 1)); // GLAND_START_DATE_TEXT
       
   314 		SetDParam(1, 1 << _patches_newgame.map_x); // GLAND_MAPSIZE_X_PULLDOWN
       
   315 		SetDParam(2, 1 << _patches_newgame.map_y); // GLAND_MAPSIZE_Y_PULLDOWN
       
   316 		SetDParam(3, _patches_newgame.snow_line_height); // GLAND_SNOW_LEVEL_TEXT
       
   317 
       
   318 		DrawWindowWidgets(this);
       
   319 
       
   320 		this->DrawEditBox(GLAND_RANDOM_EDITBOX);
       
   321 
       
   322 		if (mode != GLWP_GENERATE) {
       
   323 			char buffer[512];
       
   324 
       
   325 			if (_patches_newgame.heightmap_rotation == HM_CLOCKWISE) {
       
   326 				SetDParam(0, this->y);
       
   327 				SetDParam(1, this->x);
       
   328 			} else {
       
   329 				SetDParam(0, this->x);
       
   330 				SetDParam(1, this->y);
   278 			}
   331 			}
   279 			/* Disable snowline if not hilly */
   332 			GetString(buffer, STR_HEIGHTMAP_SIZE, lastof(buffer));
   280 			w->SetWidgetDisabledState(GLAND_SNOW_LEVEL_TEXT, _opt_newgame.landscape != LT_ARCTIC);
   333 			DrawStringRightAligned(326, 91, STR_HEIGHTMAP_SIZE, TC_BLACK);
   281 			/* Disable town, industry and trees in SE */
   334 
   282 			w->SetWidgetDisabledState(GLAND_TOWN_PULLDOWN,     _game_mode == GM_EDITOR);
   335 			DrawString( 12,  91, STR_HEIGHTMAP_NAME, TC_BLACK);
   283 			w->SetWidgetDisabledState(GLAND_INDUSTRY_PULLDOWN, _game_mode == GM_EDITOR);
   336 			SetDParamStr(0, this->name);
   284 			w->SetWidgetDisabledState(GLAND_TREE_PULLDOWN,     _game_mode == GM_EDITOR);
   337 			DrawStringTruncated(114,  91, STR_ORANGE, TC_BLACK, 326 - 114 - GetStringBoundingBox(buffer).width - 5);
   285 
   338 		}
   286 			w->SetWidgetDisabledState(GLAND_START_DATE_DOWN, _patches_newgame.starting_year <= MIN_YEAR);
   339 	}
   287 			w->SetWidgetDisabledState(GLAND_START_DATE_UP,   _patches_newgame.starting_year >= MAX_YEAR);
   340 
   288 			w->SetWidgetDisabledState(GLAND_SNOW_LEVEL_DOWN, _patches_newgame.snow_line_height <= 2 || _opt_newgame.landscape != LT_ARCTIC);
   341 	virtual void OnClick(Point pt, int widget)
   289 			w->SetWidgetDisabledState(GLAND_SNOW_LEVEL_UP,   _patches_newgame.snow_line_height >= MAX_SNOWLINE_HEIGHT || _opt_newgame.landscape != LT_ARCTIC);
   342 	{
   290 
   343 		switch (widget) {
   291 			w->SetWidgetLoweredState(GLAND_TEMPERATE, _opt_newgame.landscape == LT_TEMPERATE);
   344 			case 0: delete this; break;
   292 			w->SetWidgetLoweredState(GLAND_ARCTIC,    _opt_newgame.landscape == LT_ARCTIC);
   345 
   293 			w->SetWidgetLoweredState(GLAND_TROPICAL,  _opt_newgame.landscape == LT_TROPIC);
   346 			case GLAND_TEMPERATE:
   294 			w->SetWidgetLoweredState(GLAND_TOYLAND,   _opt_newgame.landscape == LT_TOYLAND);
   347 			case GLAND_ARCTIC:
   295 
   348 			case GLAND_TROPICAL:
   296 			if (_game_mode == GM_EDITOR) {
   349 			case GLAND_TOYLAND:
   297 				w->widget[GLAND_TOWN_PULLDOWN].data     = STR_6836_OFF;
   350 				this->RaiseWidget(_opt_newgame.landscape + GLAND_TEMPERATE);
   298 				w->widget[GLAND_INDUSTRY_PULLDOWN].data = STR_6836_OFF;
   351 				SetNewLandscapeType(widget - GLAND_TEMPERATE);
   299 			} else {
   352 				break;
   300 				w->widget[GLAND_TOWN_PULLDOWN].data     = num_towns[_opt_newgame.diff.number_towns];
   353 
   301 				w->widget[GLAND_INDUSTRY_PULLDOWN].data = num_inds[_opt_newgame.diff.number_industries];
   354 			case GLAND_MAPSIZE_X_PULLDOWN: // Mapsize X
   302 			}
   355 				ShowDropDownList(this, BuildMapsizeDropDown(), _patches_newgame.map_x, GLAND_MAPSIZE_X_PULLDOWN);
   303 
   356 				break;
   304 			if (mode == GLWP_GENERATE) {
   357 
   305 				w->widget[GLAND_LANDSCAPE_PULLDOWN].data  = landscape[_patches_newgame.land_generator];
   358 			case GLAND_MAPSIZE_Y_PULLDOWN: // Mapsize Y
   306 				w->widget[GLAND_TREE_PULLDOWN].data       = tree_placer[_patches_newgame.tree_placer];
   359 				ShowDropDownList(this, BuildMapsizeDropDown(), _patches_newgame.map_y, GLAND_MAPSIZE_Y_PULLDOWN);
   307 				w->widget[GLAND_TERRAIN_PULLDOWN].data    = elevations[_opt_newgame.diff.terrain_type];
   360 				break;
   308 				w->widget[GLAND_WATER_PULLDOWN].data      = sea_lakes[_opt_newgame.diff.quantity_sea_lakes];
   361 
   309 				w->widget[GLAND_SMOOTHNESS_PULLDOWN].data = smoothness[_patches_newgame.tgen_smoothness];
   362 			case GLAND_TOWN_PULLDOWN: // Number of towns
   310 			} else {
   363 				ShowDropDownMenu(this, _num_towns, _opt_newgame.diff.number_towns, GLAND_TOWN_PULLDOWN, 0, 0);
   311 				w->widget[GLAND_TREE_PULLDOWN].data               = tree_placer[_patches_newgame.tree_placer];
   364 				break;
   312 				w->widget[GLAND_HEIGHTMAP_ROTATION_PULLDOWN].data = rotation[_patches_newgame.heightmap_rotation];
   365 
   313 			}
   366 			case GLAND_INDUSTRY_PULLDOWN: // Number of industries
   314 
   367 				ShowDropDownMenu(this, _num_inds, _opt_newgame.diff.number_industries, GLAND_INDUSTRY_PULLDOWN, 0, 0);
   315 			/* Set parameters for widget text that requires them. */
   368 				break;
   316 			SetDParam(0, ConvertYMDToDate(_patches_newgame.starting_year, 0, 1)); // GLAND_START_DATE_TEXT
   369 
   317 			SetDParam(1, 1 << _patches_newgame.map_x); // GLAND_MAPSIZE_X_PULLDOWN
   370 			case GLAND_RANDOM_BUTTON: // Random seed
   318 			SetDParam(2, 1 << _patches_newgame.map_y); // GLAND_MAPSIZE_Y_PULLDOWN
   371 				_patches_newgame.generation_seed = InteractiveRandom();
   319 			SetDParam(3, _patches_newgame.snow_line_height); // GLAND_SNOW_LEVEL_TEXT
   372 				snprintf(this->edit_str_buf, lengthof(this->edit_str_buf), "%u", _patches_newgame.generation_seed);
   320 
   373 				UpdateTextBufferSize(&this->text);
   321 			DrawWindowWidgets(w);
   374 				this->SetDirty();
   322 
   375 				break;
   323 			DrawEditBox(w, &_genseed_query, GLAND_RANDOM_EDITBOX);
   376 
   324 
   377 			case GLAND_RANDOM_EDITBOX: // edit box for random seed
   325 			if (mode != GLWP_GENERATE) {
   378 				ShowOnScreenKeyboard(this, GLAND_RANDOM_EDITBOX, 0, 0);
   326 				char buffer[512];
   379 				break;
   327 
   380 
   328 				if (_patches_newgame.heightmap_rotation == HM_CLOCKWISE) {
   381 			case GLAND_GENERATE_BUTTON: // Generate
   329 					SetDParam(0, WP(w, generate_d).y);
   382 				UpdatePatches();
   330 					SetDParam(1, WP(w, generate_d).x);
   383 
       
   384 				if (_patches.town_layout == TL_NO_ROADS) {
       
   385 					ShowQuery(
       
   386 						STR_TOWN_LAYOUT_WARNING_CAPTION,
       
   387 						STR_TOWN_LAYOUT_WARNING_MESSAGE,
       
   388 						this,
       
   389 						LandscapeGenerationCallback);
       
   390 				} else if (mode == GLWP_HEIGHTMAP &&
       
   391 						(this->x * 2 < (1U << _patches_newgame.map_x) ||
       
   392 						this->x / 2 > (1U << _patches_newgame.map_x) ||
       
   393 						this->y * 2 < (1U << _patches_newgame.map_y) ||
       
   394 						this->y / 2 > (1U << _patches_newgame.map_y))) {
       
   395 					ShowQuery(
       
   396 						STR_HEIGHTMAP_SCALE_WARNING_CAPTION,
       
   397 						STR_HEIGHTMAP_SCALE_WARNING_MESSAGE,
       
   398 						this,
       
   399 						LandscapeGenerationCallback);
   331 				} else {
   400 				} else {
   332 					SetDParam(0, WP(w, generate_d).x);
   401 					StartGeneratingLandscape(mode);
   333 					SetDParam(1, WP(w, generate_d).y);
       
   334 				}
   402 				}
   335 				GetString(buffer, STR_HEIGHTMAP_SIZE, lastof(buffer));
   403 				break;
   336 				DrawStringRightAligned(326, 91, STR_HEIGHTMAP_SIZE, TC_BLACK);
   404 
   337 
   405 			case GLAND_START_DATE_DOWN:
   338 				DrawString( 12,  91, STR_HEIGHTMAP_NAME, TC_BLACK);
   406 			case GLAND_START_DATE_UP: // Year buttons
   339 				SetDParamStr(0, WP(w, generate_d).name);
   407 				/* Don't allow too fast scrolling */
   340 				DrawStringTruncated(114,  91, STR_ORANGE, TC_BLACK, 326 - 114 - GetStringBoundingBox(buffer).width - 5);
   408 				if ((this->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
   341 			}
   409 					this->HandleButtonClick(widget);
   342 			break;
   410 					this->SetDirty();
   343 
   411 
   344 		case WE_CLICK:
   412 					_patches_newgame.starting_year = Clamp(_patches_newgame.starting_year + widget - GLAND_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
   345 			switch (e->we.click.widget) {
   413 				}
   346 				case 0: delete w; break;
   414 				_left_button_clicked = false;
   347 
   415 				break;
   348 				case GLAND_TEMPERATE:
   416 
   349 				case GLAND_ARCTIC:
   417 			case GLAND_START_DATE_TEXT: // Year text
   350 				case GLAND_TROPICAL:
   418 				this->widget_id = GLAND_START_DATE_TEXT;
   351 				case GLAND_TOYLAND:
   419 				SetDParam(0, _patches_newgame.starting_year);
   352 					w->RaiseWidget(_opt_newgame.landscape + GLAND_TEMPERATE);
   420 				ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_START_DATE_QUERY_CAPT, 8, 100, this, CS_NUMERAL);
   353 					SetNewLandscapeType(e->we.click.widget - GLAND_TEMPERATE);
   421 				break;
       
   422 
       
   423 			case GLAND_SNOW_LEVEL_DOWN:
       
   424 			case GLAND_SNOW_LEVEL_UP: // Snow line buttons
       
   425 				/* Don't allow too fast scrolling */
       
   426 				if ((this->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
       
   427 					this->HandleButtonClick(widget);
       
   428 					this->SetDirty();
       
   429 
       
   430 					_patches_newgame.snow_line_height = Clamp(_patches_newgame.snow_line_height + widget - GLAND_SNOW_LEVEL_TEXT, 2, MAX_SNOWLINE_HEIGHT);
       
   431 				}
       
   432 				_left_button_clicked = false;
       
   433 				break;
       
   434 
       
   435 			case GLAND_SNOW_LEVEL_TEXT: // Snow line text
       
   436 				this->widget_id = GLAND_SNOW_LEVEL_TEXT;
       
   437 				SetDParam(0, _patches_newgame.snow_line_height);
       
   438 				ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_SNOW_LINE_QUERY_CAPT, 3, 100, this, CS_NUMERAL);
       
   439 				break;
       
   440 
       
   441 			case GLAND_TREE_PULLDOWN: // Tree placer
       
   442 				ShowDropDownMenu(this, _tree_placer, _patches_newgame.tree_placer, GLAND_TREE_PULLDOWN, 0, 0);
       
   443 				break;
       
   444 
       
   445 			case GLAND_LANDSCAPE_PULLDOWN: // Landscape generator OR Heightmap rotation
       
   446 			/* case GLAND_HEIGHTMAP_ROTATION_TEXT: case GLAND_HEIGHTMAP_ROTATION_PULLDOWN:*/
       
   447 				if (mode == GLWP_HEIGHTMAP) {
       
   448 					ShowDropDownMenu(this, _rotation, _patches_newgame.heightmap_rotation, GLAND_HEIGHTMAP_ROTATION_PULLDOWN, 0, 0);
       
   449 				} else {
       
   450 					ShowDropDownMenu(this, _landscape, _patches_newgame.land_generator, GLAND_LANDSCAPE_PULLDOWN, 0, 0);
       
   451 				}
       
   452 				break;
       
   453 
       
   454 			case GLAND_TERRAIN_PULLDOWN: // Terrain type
       
   455 				ShowDropDownMenu(this, _elevations, _opt_newgame.diff.terrain_type, GLAND_TERRAIN_PULLDOWN, 0, 0);
       
   456 				break;
       
   457 
       
   458 			case GLAND_WATER_PULLDOWN: // Water quantity
       
   459 				ShowDropDownMenu(this, _sea_lakes, _opt_newgame.diff.quantity_sea_lakes, GLAND_WATER_PULLDOWN, 0, 0);
       
   460 				break;
       
   461 
       
   462 			case GLAND_SMOOTHNESS_PULLDOWN: // Map smoothness
       
   463 				ShowDropDownMenu(this, _smoothness, _patches_newgame.tgen_smoothness, GLAND_SMOOTHNESS_PULLDOWN, 0, 0);
       
   464 				break;
       
   465 		}
       
   466 	}
       
   467 
       
   468 	virtual void OnMouseLoop()
       
   469 	{
       
   470 		this->HandleEditBox(GLAND_RANDOM_EDITBOX);
       
   471 	}
       
   472 
       
   473 	virtual bool OnKeyPress(uint16 key, uint16 keycode)
       
   474 	{
       
   475 		bool cont;
       
   476 		this->HandleEditBoxKey(GLAND_RANDOM_EDITBOX, key, keycode, cont);
       
   477 		/* the seed is unsigned, therefore atoi cannot be used.
       
   478 			* As 2^32 - 1 (MAX_UVALUE(uint32)) is a 'magic' value
       
   479 			* (use random seed) it should not be possible to be
       
   480 			* entered into the input field; the generate seed
       
   481 			* button can be used instead. */
       
   482 		_patches_newgame.generation_seed = minu(strtoul(this->edit_str_buf, NULL, sizeof(this->edit_str_buf) - 1), MAX_UVALUE(uint32) - 1);
       
   483 		return cont;
       
   484 	}
       
   485 
       
   486 	virtual void OnDropdownSelect(int widget, int index)
       
   487 	{
       
   488 		switch (widget) {
       
   489 			case GLAND_MAPSIZE_X_PULLDOWN:  _patches_newgame.map_x = index; break;
       
   490 			case GLAND_MAPSIZE_Y_PULLDOWN:  _patches_newgame.map_y = index; break;
       
   491 			case GLAND_TREE_PULLDOWN:       _patches_newgame.tree_placer = index; break;
       
   492 			case GLAND_SMOOTHNESS_PULLDOWN: _patches_newgame.tgen_smoothness = index;  break;
       
   493 
       
   494 			case GLAND_TOWN_PULLDOWN:
       
   495 				_opt_newgame.diff.number_towns = index;
       
   496 				if (_opt_newgame.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
       
   497 				DoCommandP(0, 2, _opt_newgame.diff.number_towns, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
       
   498 				break;
       
   499 
       
   500 			case GLAND_INDUSTRY_PULLDOWN:
       
   501 				_opt_newgame.diff.number_industries = index;
       
   502 				if (_opt_newgame.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
       
   503 				DoCommandP(0, 3, _opt_newgame.diff.number_industries, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
       
   504 				break;
       
   505 
       
   506 			case GLAND_LANDSCAPE_PULLDOWN:
       
   507 			/* case GLAND_HEIGHTMAP_PULLDOWN: */
       
   508 				if (mode == GLWP_HEIGHTMAP) {
       
   509 					_patches_newgame.heightmap_rotation = index;
       
   510 				} else {
       
   511 					_patches_newgame.land_generator = index;
       
   512 				}
       
   513 				break;
       
   514 
       
   515 			case GLAND_TERRAIN_PULLDOWN:
       
   516 				_opt_newgame.diff.terrain_type = index;
       
   517 				if (_opt_newgame.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
       
   518 				DoCommandP(0, 12, _opt_newgame.diff.terrain_type, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
       
   519 				break;
       
   520 
       
   521 			case GLAND_WATER_PULLDOWN:
       
   522 				_opt_newgame.diff.quantity_sea_lakes = index;
       
   523 				if (_opt_newgame.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
       
   524 				DoCommandP(0, 13, _opt_newgame.diff.quantity_sea_lakes, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
       
   525 				break;
       
   526 		}
       
   527 		this->SetDirty();
       
   528 	}
       
   529 
       
   530 	virtual void OnQueryTextFinished(char *str)
       
   531 	{
       
   532 		if (!StrEmpty(str)) {
       
   533 			int32 value = atoi(str);
       
   534 
       
   535 			switch (this->widget_id) {
       
   536 				case GLAND_START_DATE_TEXT:
       
   537 					this->InvalidateWidget(GLAND_START_DATE_TEXT);
       
   538 					_patches_newgame.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
   354 					break;
   539 					break;
   355 
   540 
   356 				case GLAND_MAPSIZE_X_PULLDOWN: // Mapsize X
   541 				case GLAND_SNOW_LEVEL_TEXT:
   357 					ShowDropDownList(w, BuildMapsizeDropDown(), _patches_newgame.map_x, GLAND_MAPSIZE_X_PULLDOWN);
   542 					this->InvalidateWidget(GLAND_SNOW_LEVEL_TEXT);
   358 					break;
   543 					_patches_newgame.snow_line_height = Clamp(value, 2, MAX_SNOWLINE_HEIGHT);
   359 
       
   360 				case GLAND_MAPSIZE_Y_PULLDOWN: // Mapsize Y
       
   361 					ShowDropDownList(w, BuildMapsizeDropDown(), _patches_newgame.map_y, GLAND_MAPSIZE_Y_PULLDOWN);
       
   362 					break;
       
   363 
       
   364 				case GLAND_TOWN_PULLDOWN: // Number of towns
       
   365 					ShowDropDownMenu(w, num_towns, _opt_newgame.diff.number_towns, GLAND_TOWN_PULLDOWN, 0, 0);
       
   366 					break;
       
   367 
       
   368 				case GLAND_INDUSTRY_PULLDOWN: // Number of industries
       
   369 					ShowDropDownMenu(w, num_inds, _opt_newgame.diff.number_industries, GLAND_INDUSTRY_PULLDOWN, 0, 0);
       
   370 					break;
       
   371 
       
   372 				case GLAND_RANDOM_BUTTON: // Random seed
       
   373 					_patches_newgame.generation_seed = InteractiveRandom();
       
   374 					snprintf(_genseed_buffer, lengthof(_genseed_buffer), "%u", _patches_newgame.generation_seed);
       
   375 					UpdateTextBufferSize(&_genseed_query.text);
       
   376 					w->SetDirty();
       
   377 					break;
       
   378 
       
   379 				case GLAND_RANDOM_EDITBOX: // edit box for random seed
       
   380 					ShowOnScreenKeyboard(w, & _genseed_query, GLAND_RANDOM_EDITBOX, 0, 0);
       
   381 					break;
       
   382 
       
   383 				case GLAND_GENERATE_BUTTON: // Generate
       
   384 					UpdatePatches();
       
   385 
       
   386 					if (_patches.town_layout == TL_NO_ROADS) {
       
   387 						ShowQuery(
       
   388 							STR_TOWN_LAYOUT_WARNING_CAPTION,
       
   389 							STR_TOWN_LAYOUT_WARNING_MESSAGE,
       
   390 							w,
       
   391 							LandscapeGenerationCallback);
       
   392 					} else if (mode == GLWP_HEIGHTMAP &&
       
   393 							(WP(w, generate_d).x * 2 < (1U << _patches_newgame.map_x) ||
       
   394 							WP(w, generate_d).x / 2 > (1U << _patches_newgame.map_x) ||
       
   395 							WP(w, generate_d).y * 2 < (1U << _patches_newgame.map_y) ||
       
   396 							WP(w, generate_d).y / 2 > (1U << _patches_newgame.map_y))) {
       
   397 						ShowQuery(
       
   398 							STR_HEIGHTMAP_SCALE_WARNING_CAPTION,
       
   399 							STR_HEIGHTMAP_SCALE_WARNING_MESSAGE,
       
   400 							w,
       
   401 							LandscapeGenerationCallback);
       
   402 					} else {
       
   403 						StartGeneratingLandscape(mode);
       
   404 					}
       
   405 					break;
       
   406 
       
   407 				case GLAND_START_DATE_DOWN:
       
   408 				case GLAND_START_DATE_UP: // Year buttons
       
   409 					/* Don't allow too fast scrolling */
       
   410 					if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
       
   411 						w->HandleButtonClick(e->we.click.widget);
       
   412 						w->SetDirty();
       
   413 
       
   414 						_patches_newgame.starting_year = Clamp(_patches_newgame.starting_year + e->we.click.widget - GLAND_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
       
   415 					}
       
   416 					_left_button_clicked = false;
       
   417 					break;
       
   418 
       
   419 				case GLAND_START_DATE_TEXT: // Year text
       
   420 					WP(w, generate_d).widget_id = GLAND_START_DATE_TEXT;
       
   421 					SetDParam(0, _patches_newgame.starting_year);
       
   422 					ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_START_DATE_QUERY_CAPT, 8, 100, w, CS_NUMERAL);
       
   423 					break;
       
   424 
       
   425 				case GLAND_SNOW_LEVEL_DOWN:
       
   426 				case GLAND_SNOW_LEVEL_UP: // Snow line buttons
       
   427 					/* Don't allow too fast scrolling */
       
   428 					if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
       
   429 						w->HandleButtonClick(e->we.click.widget);
       
   430 						w->SetDirty();
       
   431 
       
   432 						_patches_newgame.snow_line_height = Clamp(_patches_newgame.snow_line_height + e->we.click.widget - GLAND_SNOW_LEVEL_TEXT, 2, MAX_SNOWLINE_HEIGHT);
       
   433 					}
       
   434 					_left_button_clicked = false;
       
   435 					break;
       
   436 
       
   437 				case GLAND_SNOW_LEVEL_TEXT: // Snow line text
       
   438 					WP(w, generate_d).widget_id = GLAND_SNOW_LEVEL_TEXT;
       
   439 					SetDParam(0, _patches_newgame.snow_line_height);
       
   440 					ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_SNOW_LINE_QUERY_CAPT, 3, 100, w, CS_NUMERAL);
       
   441 					break;
       
   442 
       
   443 				case GLAND_TREE_PULLDOWN: // Tree placer
       
   444 					ShowDropDownMenu(w, tree_placer, _patches_newgame.tree_placer, GLAND_TREE_PULLDOWN, 0, 0);
       
   445 					break;
       
   446 
       
   447 				case GLAND_LANDSCAPE_PULLDOWN: // Landscape generator OR Heightmap rotation
       
   448 				/* case GLAND_HEIGHTMAP_ROTATION_TEXT: case GLAND_HEIGHTMAP_ROTATION_PULLDOWN:*/
       
   449 					if (mode == GLWP_HEIGHTMAP) {
       
   450 						ShowDropDownMenu(w, rotation, _patches_newgame.heightmap_rotation, GLAND_HEIGHTMAP_ROTATION_PULLDOWN, 0, 0);
       
   451 					} else {
       
   452 						ShowDropDownMenu(w, landscape, _patches_newgame.land_generator, GLAND_LANDSCAPE_PULLDOWN, 0, 0);
       
   453 					}
       
   454 					break;
       
   455 
       
   456 				case GLAND_TERRAIN_PULLDOWN: // Terrain type
       
   457 					ShowDropDownMenu(w, elevations, _opt_newgame.diff.terrain_type, GLAND_TERRAIN_PULLDOWN, 0, 0);
       
   458 					break;
       
   459 
       
   460 				case GLAND_WATER_PULLDOWN: // Water quantity
       
   461 					ShowDropDownMenu(w, sea_lakes, _opt_newgame.diff.quantity_sea_lakes, GLAND_WATER_PULLDOWN, 0, 0);
       
   462 					break;
       
   463 
       
   464 				case GLAND_SMOOTHNESS_PULLDOWN: // Map smoothness
       
   465 					ShowDropDownMenu(w, smoothness, _patches_newgame.tgen_smoothness, GLAND_SMOOTHNESS_PULLDOWN, 0, 0);
       
   466 					break;
   544 					break;
   467 			}
   545 			}
   468 			break;
   546 
   469 
   547 			this->SetDirty();
   470 		case WE_MOUSELOOP:
   548 		}
   471 			HandleEditBox(w, &_genseed_query, GLAND_RANDOM_EDITBOX);
   549 	}
   472 			break;
   550 };
   473 
       
   474 		case WE_KEYPRESS:
       
   475 			HandleEditBoxKey(w, &_genseed_query, GLAND_RANDOM_EDITBOX, e);
       
   476 			/* the seed is unsigned, therefore atoi cannot be used.
       
   477 			 * As 2^32 - 1 (MAX_UVALUE(uint32)) is a 'magic' value
       
   478 			 * (use random seed) it should not be possible to be
       
   479 			 * entered into the input field; the generate seed
       
   480 			 * button can be used instead. */
       
   481 			_patches_newgame.generation_seed = minu(strtoul(_genseed_buffer, NULL, sizeof(_genseed_buffer) - 1), MAX_UVALUE(uint32) - 1);
       
   482 			break;
       
   483 
       
   484 		case WE_DROPDOWN_SELECT:
       
   485 			switch (e->we.dropdown.button) {
       
   486 				case GLAND_MAPSIZE_X_PULLDOWN:  _patches_newgame.map_x = e->we.dropdown.index; break;
       
   487 				case GLAND_MAPSIZE_Y_PULLDOWN:  _patches_newgame.map_y = e->we.dropdown.index; break;
       
   488 				case GLAND_TREE_PULLDOWN:       _patches_newgame.tree_placer = e->we.dropdown.index; break;
       
   489 				case GLAND_SMOOTHNESS_PULLDOWN: _patches_newgame.tgen_smoothness = e->we.dropdown.index;  break;
       
   490 
       
   491 				case GLAND_TOWN_PULLDOWN:
       
   492 					_opt_newgame.diff.number_towns = e->we.dropdown.index;
       
   493 					if (_opt_newgame.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
       
   494 					DoCommandP(0, 2, _opt_newgame.diff.number_towns, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
       
   495 					break;
       
   496 
       
   497 				case GLAND_INDUSTRY_PULLDOWN:
       
   498 					_opt_newgame.diff.number_industries = e->we.dropdown.index;
       
   499 					if (_opt_newgame.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
       
   500 					DoCommandP(0, 3, _opt_newgame.diff.number_industries, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
       
   501 					break;
       
   502 
       
   503 				case GLAND_LANDSCAPE_PULLDOWN:
       
   504 				/* case GLAND_HEIGHTMAP_PULLDOWN: */
       
   505 					if (mode == GLWP_HEIGHTMAP) {
       
   506 						_patches_newgame.heightmap_rotation = e->we.dropdown.index;
       
   507 					} else {
       
   508 						_patches_newgame.land_generator = e->we.dropdown.index;
       
   509 					}
       
   510 					break;
       
   511 
       
   512 				case GLAND_TERRAIN_PULLDOWN:
       
   513 					_opt_newgame.diff.terrain_type = e->we.dropdown.index;
       
   514 					if (_opt_newgame.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
       
   515 					DoCommandP(0, 12, _opt_newgame.diff.terrain_type, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
       
   516 					break;
       
   517 
       
   518 				case GLAND_WATER_PULLDOWN:
       
   519 					_opt_newgame.diff.quantity_sea_lakes = e->we.dropdown.index;
       
   520 					if (_opt_newgame.diff_level != 3) ShowErrorMessage(INVALID_STRING_ID, STR_DIFFICULTY_TO_CUSTOM, 0, 0);
       
   521 					DoCommandP(0, 13, _opt_newgame.diff.quantity_sea_lakes, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
       
   522 					break;
       
   523 			}
       
   524 			w->SetDirty();
       
   525 			break;
       
   526 
       
   527 		case WE_ON_EDIT_TEXT:
       
   528 			if (!StrEmpty(e->we.edittext.str)) {
       
   529 				int32 value = atoi(e->we.edittext.str);
       
   530 
       
   531 				switch (WP(w, generate_d).widget_id) {
       
   532 					case GLAND_START_DATE_TEXT:
       
   533 						w->InvalidateWidget(GLAND_START_DATE_TEXT);
       
   534 						_patches_newgame.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
       
   535 						break;
       
   536 
       
   537 					case GLAND_SNOW_LEVEL_TEXT:
       
   538 						w->InvalidateWidget(GLAND_SNOW_LEVEL_TEXT);
       
   539 						_patches_newgame.snow_line_height = Clamp(value, 2, MAX_SNOWLINE_HEIGHT);
       
   540 						break;
       
   541 				}
       
   542 
       
   543 				w->SetDirty();
       
   544 			}
       
   545 			break;
       
   546 	}
       
   547 }
       
   548 
   551 
   549 static const WindowDesc _generate_landscape_desc = {
   552 static const WindowDesc _generate_landscape_desc = {
   550 	WDP_CENTER, WDP_CENTER, 338, 268, 338, 268,
   553 	WDP_CENTER, WDP_CENTER, 338, 268, 338, 268,
   551 	WC_GENERATE_LANDSCAPE, WC_NONE,
   554 	WC_GENERATE_LANDSCAPE, WC_NONE,
   552 	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
   555 	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
   553 	_generate_landscape_widgets,
   556 	_generate_landscape_widgets,
   554 	GenerateLandscapeWndProc,
   557 	NULL,
   555 };
   558 };
   556 
   559 
   557 static const WindowDesc _heightmap_load_desc = {
   560 static const WindowDesc _heightmap_load_desc = {
   558 	WDP_CENTER, WDP_CENTER, 338, 236, 338, 236,
   561 	WDP_CENTER, WDP_CENTER, 338, 236, 338, 236,
   559 	WC_GENERATE_LANDSCAPE, WC_NONE,
   562 	WC_GENERATE_LANDSCAPE, WC_NONE,
   560 	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS,
   563 	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS,
   561 	_heightmap_load_widgets,
   564 	_heightmap_load_widgets,
   562 	GenerateLandscapeWndProc,
   565 	NULL,
   563 };
   566 };
   564 
   567 
   565 static void _ShowGenerateLandscape(glwp_modes mode)
   568 static void _ShowGenerateLandscape(glwp_modes mode)
   566 {
   569 {
   567 	uint x = 0;
   570 	uint x = 0;
   575 	if (mode == GLWP_HEIGHTMAP) {
   578 	if (mode == GLWP_HEIGHTMAP) {
   576 		/* If the function returns negative, it means there was a problem loading the heightmap */
   579 		/* If the function returns negative, it means there was a problem loading the heightmap */
   577 		if (!GetHeightmapDimensions(_file_to_saveload.name, &x, &y)) return;
   580 		if (!GetHeightmapDimensions(_file_to_saveload.name, &x, &y)) return;
   578 	}
   581 	}
   579 
   582 
   580 	Window *w = AllocateWindowDescFront<Window>((mode == GLWP_HEIGHTMAP) ? &_heightmap_load_desc : &_generate_landscape_desc, mode);
   583 	GenerateLandscapeWindow *w = AllocateWindowDescFront<GenerateLandscapeWindow>((mode == GLWP_HEIGHTMAP) ? &_heightmap_load_desc : &_generate_landscape_desc, mode);
   581 
       
   582 	if (w == NULL) return;
       
   583 
   584 
   584 	if (mode == GLWP_HEIGHTMAP) {
   585 	if (mode == GLWP_HEIGHTMAP) {
   585 		WP(w, generate_d).x = x;
   586 		w->x = x;
   586 		WP(w, generate_d).y = y;
   587 		w->y = y;
   587 		strecpy(WP(w, generate_d).name, _file_to_saveload.title, lastof(WP(w, generate_d).name));
   588 		strecpy(w->name, _file_to_saveload.title, lastof(w->name));
   588 	}
   589 	}
   589 
   590 
   590 	InvalidateWindow(WC_GENERATE_LANDSCAPE, mode);
   591 	InvalidateWindow(WC_GENERATE_LANDSCAPE, mode);
   591 }
   592 }
   592 
   593 
   637 	CSCEN_FLAT_LAND_HEIGHT_TEXT,
   638 	CSCEN_FLAT_LAND_HEIGHT_TEXT,
   638 	CSCEN_FLAT_LAND_HEIGHT_UP
   639 	CSCEN_FLAT_LAND_HEIGHT_UP
   639 };
   640 };
   640 
   641 
   641 
   642 
   642 static void CreateScenarioWndProc(Window *w, WindowEvent *e)
   643 struct CreateScenarioWindow : public Window
   643 {
   644 {
   644 	switch (e->event) {
   645 	uint widget_id;
   645 		case WE_CREATE:
   646 
   646 			w->LowerWidget(_opt_newgame.landscape + CSCEN_TEMPERATE);
   647 	CreateScenarioWindow(const WindowDesc *desc, WindowNumber window_number) : Window(desc, NULL, window_number)
   647 			break;
   648 	{
   648 
   649 		this->LowerWidget(_opt_newgame.landscape + CSCEN_TEMPERATE);
   649 		case WE_PAINT:
   650 	}
   650 			w->SetWidgetDisabledState(CSCEN_START_DATE_DOWN,       _patches_newgame.starting_year <= MIN_YEAR);
   651 
   651 			w->SetWidgetDisabledState(CSCEN_START_DATE_UP,         _patches_newgame.starting_year >= MAX_YEAR);
   652 	virtual void OnPaint()
   652 			w->SetWidgetDisabledState(CSCEN_FLAT_LAND_HEIGHT_DOWN, _patches_newgame.se_flat_world_height <= 0);
   653 	{
   653 			w->SetWidgetDisabledState(CSCEN_FLAT_LAND_HEIGHT_UP,   _patches_newgame.se_flat_world_height >= MAX_TILE_HEIGHT);
   654 		this->SetWidgetDisabledState(CSCEN_START_DATE_DOWN,       _patches_newgame.starting_year <= MIN_YEAR);
   654 
   655 		this->SetWidgetDisabledState(CSCEN_START_DATE_UP,         _patches_newgame.starting_year >= MAX_YEAR);
   655 			w->SetWidgetLoweredState(CSCEN_TEMPERATE, _opt_newgame.landscape == LT_TEMPERATE);
   656 		this->SetWidgetDisabledState(CSCEN_FLAT_LAND_HEIGHT_DOWN, _patches_newgame.se_flat_world_height <= 0);
   656 			w->SetWidgetLoweredState(CSCEN_ARCTIC,    _opt_newgame.landscape == LT_ARCTIC);
   657 		this->SetWidgetDisabledState(CSCEN_FLAT_LAND_HEIGHT_UP,   _patches_newgame.se_flat_world_height >= MAX_TILE_HEIGHT);
   657 			w->SetWidgetLoweredState(CSCEN_TROPICAL,  _opt_newgame.landscape == LT_TROPIC);
   658 
   658 			w->SetWidgetLoweredState(CSCEN_TOYLAND,   _opt_newgame.landscape == LT_TOYLAND);
   659 		this->SetWidgetLoweredState(CSCEN_TEMPERATE, _opt_newgame.landscape == LT_TEMPERATE);
   659 
   660 		this->SetWidgetLoweredState(CSCEN_ARCTIC,    _opt_newgame.landscape == LT_ARCTIC);
   660 			/* Set parameters for widget text that requires them */
   661 		this->SetWidgetLoweredState(CSCEN_TROPICAL,  _opt_newgame.landscape == LT_TROPIC);
   661 			SetDParam(0, ConvertYMDToDate(_patches_newgame.starting_year, 0, 1)); // CSCEN_START_DATE_TEXT
   662 		this->SetWidgetLoweredState(CSCEN_TOYLAND,   _opt_newgame.landscape == LT_TOYLAND);
   662 			SetDParam(1, 1 << _patches_newgame.map_x); // CSCEN_MAPSIZE_X_PULLDOWN
   663 
   663 			SetDParam(2, 1 << _patches_newgame.map_y); // CSCEN_MAPSIZE_Y_PULLDOWN
   664 		/* Set parameters for widget text that requires them */
   664 			SetDParam(3, _patches_newgame.se_flat_world_height); // CSCEN_FLAT_LAND_HEIGHT_TEXT
   665 		SetDParam(0, ConvertYMDToDate(_patches_newgame.starting_year, 0, 1)); // CSCEN_START_DATE_TEXT
   665 
   666 		SetDParam(1, 1 << _patches_newgame.map_x); // CSCEN_MAPSIZE_X_PULLDOWN
   666 			DrawWindowWidgets(w);
   667 		SetDParam(2, 1 << _patches_newgame.map_y); // CSCEN_MAPSIZE_Y_PULLDOWN
   667 
   668 		SetDParam(3, _patches_newgame.se_flat_world_height); // CSCEN_FLAT_LAND_HEIGHT_TEXT
   668 			break;
   669 
   669 
   670 		DrawWindowWidgets(this);
   670 		case WE_CLICK:
   671 	}
   671 			switch (e->we.click.widget) {
   672 
   672 				case CSCEN_TEMPERATE:
   673 	virtual void OnClick(Point pt, int widget)
   673 				case CSCEN_ARCTIC:
   674 	{
   674 				case CSCEN_TROPICAL:
   675 		switch (widget) {
   675 				case CSCEN_TOYLAND:
   676 			case CSCEN_TEMPERATE:
   676 					w->RaiseWidget(_opt_newgame.landscape + CSCEN_TEMPERATE);
   677 			case CSCEN_ARCTIC:
   677 					SetNewLandscapeType(e->we.click.widget - CSCEN_TEMPERATE);
   678 			case CSCEN_TROPICAL:
       
   679 			case CSCEN_TOYLAND:
       
   680 				this->RaiseWidget(_opt_newgame.landscape + CSCEN_TEMPERATE);
       
   681 				SetNewLandscapeType(widget - CSCEN_TEMPERATE);
       
   682 				break;
       
   683 
       
   684 			case CSCEN_MAPSIZE_X_PULLDOWN: // Mapsize X
       
   685 				ShowDropDownList(this, BuildMapsizeDropDown(), _patches_newgame.map_x, CSCEN_MAPSIZE_X_PULLDOWN);
       
   686 				break;
       
   687 
       
   688 			case CSCEN_MAPSIZE_Y_PULLDOWN: // Mapsize Y
       
   689 				ShowDropDownList(this, BuildMapsizeDropDown(), _patches_newgame.map_y, CSCEN_MAPSIZE_Y_PULLDOWN);
       
   690 				break;
       
   691 
       
   692 			case CSCEN_EMPTY_WORLD: // Empty world / flat world
       
   693 				StartGeneratingLandscape(GLWP_SCENARIO);
       
   694 				break;
       
   695 
       
   696 			case CSCEN_RANDOM_WORLD: // Generate
       
   697 				ShowGenerateLandscape();
       
   698 				break;
       
   699 
       
   700 			case CSCEN_START_DATE_DOWN:
       
   701 			case CSCEN_START_DATE_UP: // Year buttons
       
   702 				/* Don't allow too fast scrolling */
       
   703 				if ((this->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
       
   704 					this->HandleButtonClick(widget);
       
   705 					this->SetDirty();
       
   706 
       
   707 					_patches_newgame.starting_year = Clamp(_patches_newgame.starting_year + widget - CSCEN_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
       
   708 				}
       
   709 				_left_button_clicked = false;
       
   710 				break;
       
   711 
       
   712 			case CSCEN_START_DATE_TEXT: // Year text
       
   713 				this->widget_id = CSCEN_START_DATE_TEXT;
       
   714 				SetDParam(0, _patches_newgame.starting_year);
       
   715 				ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_START_DATE_QUERY_CAPT, 8, 100, this, CS_NUMERAL);
       
   716 				break;
       
   717 
       
   718 			case CSCEN_FLAT_LAND_HEIGHT_DOWN:
       
   719 			case CSCEN_FLAT_LAND_HEIGHT_UP: // Height level buttons
       
   720 				/* Don't allow too fast scrolling */
       
   721 				if ((this->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
       
   722 					this->HandleButtonClick(widget);
       
   723 					this->SetDirty();
       
   724 
       
   725 					_patches_newgame.se_flat_world_height = Clamp(_patches_newgame.se_flat_world_height + widget - CSCEN_FLAT_LAND_HEIGHT_TEXT, 0, MAX_TILE_HEIGHT);
       
   726 				}
       
   727 				_left_button_clicked = false;
       
   728 				break;
       
   729 
       
   730 			case CSCEN_FLAT_LAND_HEIGHT_TEXT: // Height level text
       
   731 				this->widget_id = CSCEN_FLAT_LAND_HEIGHT_TEXT;
       
   732 				SetDParam(0, _patches_newgame.se_flat_world_height);
       
   733 				ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_FLAT_WORLD_HEIGHT_QUERY_CAPT, 3, 100, this, CS_NUMERAL);
       
   734 				break;
       
   735 		}
       
   736 	}
       
   737 
       
   738 	virtual void OnDropdownSelect(int widget, int index)
       
   739 	{
       
   740 		switch (widget) {
       
   741 			case CSCEN_MAPSIZE_X_PULLDOWN: _patches_newgame.map_x = index; break;
       
   742 			case CSCEN_MAPSIZE_Y_PULLDOWN: _patches_newgame.map_y = index; break;
       
   743 		}
       
   744 		this->SetDirty();
       
   745 	}
       
   746 
       
   747 	virtual void OnQueryTextFinished(char *str)
       
   748 	{
       
   749 		if (!StrEmpty(str)) {
       
   750 			int32 value = atoi(str);
       
   751 
       
   752 			switch (this->widget_id) {
       
   753 				case CSCEN_START_DATE_TEXT:
       
   754 					this->InvalidateWidget(CSCEN_START_DATE_TEXT);
       
   755 					_patches_newgame.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
   678 					break;
   756 					break;
   679 
   757 
   680 				case CSCEN_MAPSIZE_X_PULLDOWN: // Mapsize X
   758 				case CSCEN_FLAT_LAND_HEIGHT_TEXT:
   681 					ShowDropDownList(w, BuildMapsizeDropDown(), _patches_newgame.map_x, CSCEN_MAPSIZE_X_PULLDOWN);
   759 					this->InvalidateWidget(CSCEN_FLAT_LAND_HEIGHT_TEXT);
   682 					break;
   760 					_patches_newgame.se_flat_world_height = Clamp(value, 0, MAX_TILE_HEIGHT);
   683 
       
   684 				case CSCEN_MAPSIZE_Y_PULLDOWN: // Mapsize Y
       
   685 					ShowDropDownList(w, BuildMapsizeDropDown(), _patches_newgame.map_y, CSCEN_MAPSIZE_Y_PULLDOWN);
       
   686 					break;
       
   687 
       
   688 				case CSCEN_EMPTY_WORLD: // Empty world / flat world
       
   689 					StartGeneratingLandscape(GLWP_SCENARIO);
       
   690 					break;
       
   691 
       
   692 				case CSCEN_RANDOM_WORLD: // Generate
       
   693 					ShowGenerateLandscape();
       
   694 					break;
       
   695 
       
   696 				case CSCEN_START_DATE_DOWN:
       
   697 				case CSCEN_START_DATE_UP: // Year buttons
       
   698 					/* Don't allow too fast scrolling */
       
   699 					if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
       
   700 						w->HandleButtonClick(e->we.click.widget);
       
   701 						w->SetDirty();
       
   702 
       
   703 						_patches_newgame.starting_year = Clamp(_patches_newgame.starting_year + e->we.click.widget - CSCEN_START_DATE_TEXT, MIN_YEAR, MAX_YEAR);
       
   704 					}
       
   705 					_left_button_clicked = false;
       
   706 					break;
       
   707 
       
   708 				case CSCEN_START_DATE_TEXT: // Year text
       
   709 					WP(w, generate_d).widget_id = CSCEN_START_DATE_TEXT;
       
   710 					SetDParam(0, _patches_newgame.starting_year);
       
   711 					ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_START_DATE_QUERY_CAPT, 8, 100, w, CS_NUMERAL);
       
   712 					break;
       
   713 
       
   714 				case CSCEN_FLAT_LAND_HEIGHT_DOWN:
       
   715 				case CSCEN_FLAT_LAND_HEIGHT_UP: // Height level buttons
       
   716 					/* Don't allow too fast scrolling */
       
   717 					if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
       
   718 						w->HandleButtonClick(e->we.click.widget);
       
   719 						w->SetDirty();
       
   720 
       
   721 						_patches_newgame.se_flat_world_height = Clamp(_patches_newgame.se_flat_world_height + e->we.click.widget - CSCEN_FLAT_LAND_HEIGHT_TEXT, 0, MAX_TILE_HEIGHT);
       
   722 					}
       
   723 					_left_button_clicked = false;
       
   724 					break;
       
   725 
       
   726 				case CSCEN_FLAT_LAND_HEIGHT_TEXT: // Height level text
       
   727 					WP(w, generate_d).widget_id = CSCEN_FLAT_LAND_HEIGHT_TEXT;
       
   728 					SetDParam(0, _patches_newgame.se_flat_world_height);
       
   729 					ShowQueryString(STR_CONFIG_PATCHES_INT32, STR_FLAT_WORLD_HEIGHT_QUERY_CAPT, 3, 100, w, CS_NUMERAL);
       
   730 					break;
   761 					break;
   731 			}
   762 			}
   732 			break;
   763 
   733 
   764 			this->SetDirty();
   734 		case WE_DROPDOWN_SELECT:
   765 		}
   735 			switch (e->we.dropdown.button) {
   766 	}
   736 				case CSCEN_MAPSIZE_X_PULLDOWN: _patches_newgame.map_x = e->we.dropdown.index; break;
   767 };
   737 				case CSCEN_MAPSIZE_Y_PULLDOWN: _patches_newgame.map_y = e->we.dropdown.index; break;
       
   738 			}
       
   739 			w->SetDirty();
       
   740 			break;
       
   741 
       
   742 		case WE_ON_EDIT_TEXT:
       
   743 			if (!StrEmpty(e->we.edittext.str)) {
       
   744 				int32 value = atoi(e->we.edittext.str);
       
   745 
       
   746 				switch (WP(w, generate_d).widget_id) {
       
   747 					case CSCEN_START_DATE_TEXT:
       
   748 						w->InvalidateWidget(CSCEN_START_DATE_TEXT);
       
   749 						_patches_newgame.starting_year = Clamp(value, MIN_YEAR, MAX_YEAR);
       
   750 						break;
       
   751 
       
   752 					case CSCEN_FLAT_LAND_HEIGHT_TEXT:
       
   753 						w->InvalidateWidget(CSCEN_FLAT_LAND_HEIGHT_TEXT);
       
   754 						_patches_newgame.se_flat_world_height = Clamp(value, 0, MAX_TILE_HEIGHT);
       
   755 						break;
       
   756 				}
       
   757 
       
   758 				w->SetDirty();
       
   759 			}
       
   760 			break;
       
   761 	}
       
   762 }
       
   763 
   768 
   764 static const Widget _create_scenario_widgets[] = {
   769 static const Widget _create_scenario_widgets[] = {
   765 {   WWT_CLOSEBOX, RESIZE_NONE, 13,   0,  10,   0,  13, STR_00C5,                STR_018B_CLOSE_WINDOW},
   770 {   WWT_CLOSEBOX, RESIZE_NONE, 13,   0,  10,   0,  13, STR_00C5,                STR_018B_CLOSE_WINDOW},
   766 {    WWT_CAPTION, RESIZE_NONE, 13,  11, 337,   0,  13, STR_SE_CAPTION,          STR_NULL},
   771 {    WWT_CAPTION, RESIZE_NONE, 13,  11, 337,   0,  13, STR_SE_CAPTION,          STR_NULL},
   767 {      WWT_PANEL, RESIZE_NONE, 13,   0, 337,  14, 169, 0x0,                     STR_NULL},
   772 {      WWT_PANEL, RESIZE_NONE, 13,   0, 337,  14, 169, 0x0,                     STR_NULL},
   794 static const WindowDesc _create_scenario_desc = {
   799 static const WindowDesc _create_scenario_desc = {
   795 	WDP_CENTER, WDP_CENTER, 338, 170, 338, 170,
   800 	WDP_CENTER, WDP_CENTER, 338, 170, 338, 170,
   796 	WC_GENERATE_LANDSCAPE, WC_NONE,
   801 	WC_GENERATE_LANDSCAPE, WC_NONE,
   797 	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS,
   802 	WDF_STD_TOOLTIPS | WDF_DEF_WIDGET | WDF_STD_BTN | WDF_UNCLICK_BUTTONS,
   798 	_create_scenario_widgets,
   803 	_create_scenario_widgets,
   799 	CreateScenarioWndProc,
   804 	NULL,
   800 };
   805 };
   801 
   806 
   802 void ShowCreateScenario()
   807 void ShowCreateScenario()
   803 {
   808 {
   804 	DeleteWindowByClass(WC_GENERATE_LANDSCAPE);
   809 	DeleteWindowByClass(WC_GENERATE_LANDSCAPE);
   805 	AllocateWindowDescFront<Window>(&_create_scenario_desc, GLWP_SCENARIO);
   810 	new CreateScenarioWindow(&_create_scenario_desc, GLWP_SCENARIO);
   806 }
   811 }
   807 
   812 
   808 
   813 
   809 static const Widget _show_terrain_progress_widgets[] = {
   814 static const Widget _show_terrain_progress_widgets[] = {
   810 {    WWT_CAPTION,   RESIZE_NONE,    14,     0,   180,     0,    13, STR_GENERATION_WORLD,   STR_018C_WINDOW_TITLE_DRAG_THIS},
   815 {    WWT_CAPTION,   RESIZE_NONE,    14,     0,   180,     0,    13, STR_GENERATION_WORLD,   STR_018C_WINDOW_TITLE_DRAG_THIS},