src/town_gui.cpp
branchNewGRF_ports
changeset 10210 a2131f7a315d
parent 10184 fcf5fb2548eb
child 10211 c1391c8ed5c6
equal deleted inserted replaced
10200:aba3af04cdbd 10210:a2131f7a315d
   140 }
   140 }
   141 
   141 
   142 static void TownAuthorityWndProc(Window *w, WindowEvent *e)
   142 static void TownAuthorityWndProc(Window *w, WindowEvent *e)
   143 {
   143 {
   144 	switch (e->event) {
   144 	switch (e->event) {
   145 	case WE_PAINT: {
   145 		case WE_PAINT: {
   146 		const Town *t = GetTown(w->window_number);
   146 			const Town *t = GetTown(w->window_number);
   147 		int numact;
   147 			int numact;
   148 		uint buttons = GetMaskOfTownActions(&numact, _local_player, t);
   148 			uint buttons = GetMaskOfTownActions(&numact, _local_player, t);
   149 
   149 
   150 		SetVScrollCount(w, numact + 1);
   150 			SetVScrollCount(w, numact + 1);
   151 
   151 
   152 		if (WP(w, def_d).data_1 != -1 && !HasBit(buttons, WP(w,def_d).data_1))
   152 			if (WP(w, def_d).data_1 != -1 && !HasBit(buttons, WP(w,def_d).data_1))
   153 			WP(w, def_d).data_1 = -1;
   153 				WP(w, def_d).data_1 = -1;
   154 
   154 
   155 		w->SetWidgetDisabledState(6, WP(w, def_d).data_1 == -1);
   155 			w->SetWidgetDisabledState(6, WP(w, def_d).data_1 == -1);
   156 
   156 
   157 		{
   157 			{
   158 			int y;
   158 				int y;
   159 			const Player *p;
   159 				const Player *p;
   160 			int r;
   160 				int r;
   161 			StringID str;
   161 				StringID str;
   162 
   162 
   163 			SetDParam(0, w->window_number);
   163 				SetDParam(0, w->window_number);
   164 			DrawWindowWidgets(w);
   164 				DrawWindowWidgets(w);
   165 
   165 
   166 			DrawString(2, 15, STR_2023_TRANSPORT_COMPANY_RATINGS, TC_FROMSTRING);
   166 				DrawString(2, 15, STR_2023_TRANSPORT_COMPANY_RATINGS, TC_FROMSTRING);
   167 
   167 
   168 			/* Draw list of players */
   168 				/* Draw list of players */
   169 			y = 25;
   169 				y = 25;
   170 			FOR_ALL_PLAYERS(p) {
   170 				FOR_ALL_PLAYERS(p) {
   171 				if (p->is_active && (HasBit(t->have_ratings, p->index) || t->exclusivity == p->index)) {
   171 					if (p->is_active && (HasBit(t->have_ratings, p->index) || t->exclusivity == p->index)) {
   172 					DrawPlayerIcon(p->index, 2, y);
   172 						DrawPlayerIcon(p->index, 2, y);
   173 
   173 
   174 					SetDParam(0, p->index);
   174 						SetDParam(0, p->index);
   175 					SetDParam(1, p->index);
   175 						SetDParam(1, p->index);
   176 
   176 
   177 					r = t->ratings[p->index];
   177 						r = t->ratings[p->index];
   178 					(str = STR_3035_APPALLING, r <= RATING_APPALLING) || // Apalling
   178 						(str = STR_3035_APPALLING, r <= RATING_APPALLING) || // Apalling
   179 					(str++,                    r <= RATING_VERYPOOR)  || // Very Poor
   179 						(str++,                    r <= RATING_VERYPOOR)  || // Very Poor
   180 					(str++,                    r <= RATING_POOR)      || // Poor
   180 						(str++,                    r <= RATING_POOR)      || // Poor
   181 					(str++,                    r <= RATING_MEDIOCRE)  || // Mediocore
   181 						(str++,                    r <= RATING_MEDIOCRE)  || // Mediocore
   182 					(str++,                    r <= RATING_GOOD)      || // Good
   182 						(str++,                    r <= RATING_GOOD)      || // Good
   183 					(str++,                    r <= RATING_VERYGOOD)  || // Very Good
   183 						(str++,                    r <= RATING_VERYGOOD)  || // Very Good
   184 					(str++,                    r <= RATING_EXCELLENT) || // Excellent
   184 						(str++,                    r <= RATING_EXCELLENT) || // Excellent
   185 					(str++,                    true);                    // Outstanding
   185 						(str++,                    true);                    // Outstanding
   186 
   186 
   187 					SetDParam(2, str);
   187 						SetDParam(2, str);
   188 					if (t->exclusivity == p->index) { // red icon for player with exclusive rights
   188 						if (t->exclusivity == p->index) { // red icon for player with exclusive rights
   189 						DrawSprite(SPR_BLOT, PALETTE_TO_RED, 18, y);
   189 							DrawSprite(SPR_BLOT, PALETTE_TO_RED, 18, y);
       
   190 						}
       
   191 
       
   192 						DrawString(28, y, STR_2024, TC_FROMSTRING);
       
   193 						y += 10;
   190 					}
   194 					}
   191 
   195 				}
   192 					DrawString(28, y, STR_2024, TC_FROMSTRING);
   196 			}
       
   197 
       
   198 			/* Draw actions list */
       
   199 			{
       
   200 				int y = 107, i;
       
   201 				int pos = w->vscroll.pos;
       
   202 
       
   203 				if (--pos < 0) {
       
   204 					DrawString(2, y, STR_2045_ACTIONS_AVAILABLE, TC_FROMSTRING);
   193 					y += 10;
   205 					y += 10;
   194 				}
   206 				}
   195 			}
   207 
   196 		}
   208 				for (i = 0; buttons; i++, buttons >>= 1) {
   197 
   209 					if (pos <= -5) break; ///< Draw only the 5 fitting lines
   198 		/* Draw actions list */
   210 
   199 		{
   211 					if ((buttons & 1) && --pos < 0) {
   200 			int y = 107, i;
   212 						DrawString(3, y, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i, TC_ORANGE);
   201 			int pos = w->vscroll.pos;
   213 						y += 10;
   202 
   214 					}
   203 			if (--pos < 0) {
       
   204 				DrawString(2, y, STR_2045_ACTIONS_AVAILABLE, TC_FROMSTRING);
       
   205 				y += 10;
       
   206 			}
       
   207 			for (i = 0; buttons; i++, buttons >>= 1) {
       
   208 				if (pos <= -5) break; ///< Draw only the 5 fitting lines
       
   209 
       
   210 				if ((buttons & 1) && --pos < 0) {
       
   211 					DrawString(3, y, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i, TC_ORANGE);
       
   212 					y += 10;
       
   213 				}
   215 				}
   214 			}
   216 			}
   215 		}
   217 
   216 
   218 			{
   217 		{
   219 				int i = WP(w, def_d).data_1;
   218 			int i = WP(w, def_d).data_1;
   220 
   219 
   221 				if (i != -1) {
   220 			if (i != -1) {
   222 					SetDParam(1, (_price.build_industry >> 8) * _town_action_costs[i]);
   221 				SetDParam(1, (_price.build_industry >> 8) * _town_action_costs[i]);
   223 					SetDParam(0, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i);
   222 				SetDParam(0, STR_2046_SMALL_ADVERTISING_CAMPAIGN + i);
   224 					DrawStringMultiLine(2, 159, STR_204D_INITIATE_A_SMALL_LOCAL + i, 313);
   223 				DrawStringMultiLine(2, 159, STR_204D_INITIATE_A_SMALL_LOCAL + i, 313);
       
   224 			}
       
   225 		}
       
   226 
       
   227 	} break;
       
   228 
       
   229 	case WE_DOUBLE_CLICK:
       
   230 	case WE_CLICK:
       
   231 		switch (e->we.click.widget) {
       
   232 			case TWA_COMMAND_LIST: {
       
   233 				const Town *t = GetTown(w->window_number);
       
   234 				int y = (e->we.click.pt.y - 0x6B) / 10;
       
   235 
       
   236 				if (!IsInsideMM(y, 0, 5)) return;
       
   237 
       
   238 				y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_player, t), y + w->vscroll.pos - 1);
       
   239 				if (y >= 0) {
       
   240 					WP(w, def_d).data_1 = y;
       
   241 					SetWindowDirty(w);
       
   242 				}
   225 				}
   243 				/* Fall through to clicking in case we are double-clicked */
   226 			}
   244 				if (e->event != WE_DOUBLE_CLICK || y < 0) break;
   227 
   245 			}
   228 		} break;
   246 
   229 
   247 			case TWA_EXECUTE:
   230 		case WE_DOUBLE_CLICK:
   248 				DoCommandP(GetTown(w->window_number)->xy, w->window_number, WP(w, def_d).data_1, NULL, CMD_DO_TOWN_ACTION | CMD_MSG(STR_00B4_CAN_T_DO_THIS));
   231 		case WE_CLICK:
   249 				break;
   232 			switch (e->we.click.widget) {
   250 		}
   233 				case TWA_COMMAND_LIST: {
   251 		break;
   234 					const Town *t = GetTown(w->window_number);
   252 
   235 					int y = (e->we.click.pt.y - 0x6B) / 10;
   253 	case WE_4:
   236 
   254 		SetWindowDirty(w);
   237 					if (!IsInsideMM(y, 0, 5)) return;
   255 		break;
   238 
       
   239 					y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_player, t), y + w->vscroll.pos - 1);
       
   240 					if (y >= 0) {
       
   241 						WP(w, def_d).data_1 = y;
       
   242 						SetWindowDirty(w);
       
   243 					}
       
   244 					/* Fall through to clicking in case we are double-clicked */
       
   245 					if (e->event != WE_DOUBLE_CLICK || y < 0) break;
       
   246 				}
       
   247 
       
   248 				case TWA_EXECUTE:
       
   249 					DoCommandP(GetTown(w->window_number)->xy, w->window_number, WP(w, def_d).data_1, NULL, CMD_DO_TOWN_ACTION | CMD_MSG(STR_00B4_CAN_T_DO_THIS));
       
   250 					break;
       
   251 			}
       
   252 			break;
       
   253 
       
   254 		case WE_4:
       
   255 			SetWindowDirty(w);
       
   256 			break;
   256 	}
   257 	}
   257 }
   258 }
   258 
   259 
   259 static const WindowDesc _town_authority_desc = {
   260 static const WindowDesc _town_authority_desc = {
   260 	WDP_AUTO, WDP_AUTO, 317, 222, 317, 222,
   261 	WDP_AUTO, WDP_AUTO, 317, 222, 317, 222,
   272 		w->vscroll.cap = 5;
   273 		w->vscroll.cap = 5;
   273 		WP(w, def_d).data_1 = -1;
   274 		WP(w, def_d).data_1 = -1;
   274 	}
   275 	}
   275 }
   276 }
   276 
   277 
       
   278 
       
   279 enum TownViewWidget {
       
   280 	TVW_CAPTION = 1,
       
   281 	TVW_CENTERVIEW = 6,
       
   282 	TVW_SHOWAUTORITY,
       
   283 	TVW_CHANGENAME,
       
   284 	TVW_EXPAND,
       
   285 	TVW_DELETE,
       
   286 };
       
   287 
   277 static void TownViewWndProc(Window *w, WindowEvent *e)
   288 static void TownViewWndProc(Window *w, WindowEvent *e)
   278 {
   289 {
   279 	Town *t = GetTown(w->window_number);
   290 	Town *t = GetTown(w->window_number);
   280 
   291 
   281 	switch (e->event) {
   292 	switch (e->event) {
   282 	case WE_CREATE:
   293 		case WE_CREATE:
   283 		if (t->larger_town) w->widget[1].data = STR_CITY;
   294 			if (t->larger_town) w->widget[TVW_CAPTION].data = STR_CITY;
   284 		break;
   295 			break;
   285 
   296 
   286 	case WE_PAINT:
   297 		case WE_PAINT:
   287 		/* disable renaming town in network games if you are not the server */
   298 			/* disable renaming town in network games if you are not the server */
   288 		w->SetWidgetDisabledState(8, _networking && !_network_server);
   299 			w->SetWidgetDisabledState(TVW_CHANGENAME, _networking && !_network_server);
   289 
   300 
   290 		SetDParam(0, t->index);
   301 			SetDParam(0, t->index);
   291 		DrawWindowWidgets(w);
   302 			DrawWindowWidgets(w);
   292 
   303 
   293 		SetDParam(0, t->population);
   304 			SetDParam(0, t->population);
   294 		SetDParam(1, t->num_houses);
   305 			SetDParam(1, t->num_houses);
   295 		DrawString(2, 107, STR_2006_POPULATION, TC_FROMSTRING);
   306 			DrawString(2, 107, STR_2006_POPULATION, TC_FROMSTRING);
   296 
   307 
   297 		SetDParam(0, t->act_pass);
   308 			SetDParam(0, t->act_pass);
   298 		SetDParam(1, t->max_pass);
   309 			SetDParam(1, t->max_pass);
   299 		DrawString(2, 117, STR_200D_PASSENGERS_LAST_MONTH_MAX, TC_FROMSTRING);
   310 			DrawString(2, 117, STR_200D_PASSENGERS_LAST_MONTH_MAX, TC_FROMSTRING);
   300 
   311 
   301 		SetDParam(0, t->act_mail);
   312 			SetDParam(0, t->act_mail);
   302 		SetDParam(1, t->max_mail);
   313 			SetDParam(1, t->max_mail);
   303 		DrawString(2, 127, STR_200E_MAIL_LAST_MONTH_MAX, TC_FROMSTRING);
   314 			DrawString(2, 127, STR_200E_MAIL_LAST_MONTH_MAX, TC_FROMSTRING);
   304 
   315 
   305 		DrawWindowViewport(w);
   316 			DrawWindowViewport(w);
   306 		break;
   317 			break;
   307 
   318 
   308 	case WE_CLICK:
   319 		case WE_CLICK:
   309 		switch (e->we.click.widget) {
   320 			switch (e->we.click.widget) {
   310 			case 6: /* scroll to location */
   321 				case TVW_CENTERVIEW: /* scroll to location */
   311 				ScrollMainWindowToTile(t->xy);
   322 					ScrollMainWindowToTile(t->xy);
   312 				break;
   323 					break;
   313 
   324 
   314 			case 7: /* town authority */
   325 				case TVW_SHOWAUTORITY: /* town authority */
   315 				ShowTownAuthorityWindow(w->window_number);
   326 					ShowTownAuthorityWindow(w->window_number);
   316 				break;
   327 					break;
   317 
   328 
   318 			case 8: /* rename */
   329 				case TVW_CHANGENAME: /* rename */
   319 				SetDParam(0, w->window_number);
   330 					SetDParam(0, w->window_number);
   320 				ShowQueryString(STR_TOWN, STR_2007_RENAME_TOWN, 31, 130, w, CS_ALPHANUMERAL);
   331 					ShowQueryString(STR_TOWN, STR_2007_RENAME_TOWN, 31, 130, w, CS_ALPHANUMERAL);
   321 				break;
   332 					break;
   322 
   333 
   323 			case 9: /* expand town */
   334 				case TVW_EXPAND: /* expand town - only available on Scenario editor */
   324 				ExpandTown(t);
   335 					ExpandTown(t);
   325 				break;
   336 					break;
   326 
   337 
   327 			case 10: /* delete town */
   338 				case TVW_DELETE: /* delete town - only available on Scenario editor */
   328 				delete t;
   339 					delete t;
   329 				break;
   340 					break;
   330 		} break;
   341 			} break;
   331 
   342 
   332 	case WE_ON_EDIT_TEXT:
   343 		case WE_ON_EDIT_TEXT:
   333 		if (e->we.edittext.str[0] != '\0') {
   344 			if (e->we.edittext.str[0] != '\0') {
   334 			_cmd_text = e->we.edittext.str;
   345 				_cmd_text = e->we.edittext.str;
   335 			DoCommandP(0, w->window_number, 0, NULL,
   346 				DoCommandP(0, w->window_number, 0, NULL,
   336 				CMD_RENAME_TOWN | CMD_MSG(STR_2008_CAN_T_RENAME_TOWN));
   347 					CMD_RENAME_TOWN | CMD_MSG(STR_2008_CAN_T_RENAME_TOWN));
   337 		}
   348 			}
   338 		break;
   349 			break;
   339 	}
   350 	}
   340 }
   351 }
   341 
   352 
   342 
   353 
   343 static const Widget _town_view_widgets[] = {
   354 static const Widget _town_view_widgets[] = {
   478 
   489 
   479 
   490 
   480 static void TownDirectoryWndProc(Window *w, WindowEvent *e)
   491 static void TownDirectoryWndProc(Window *w, WindowEvent *e)
   481 {
   492 {
   482 	switch (e->event) {
   493 	switch (e->event) {
   483 	case WE_PAINT: {
   494 		case WE_PAINT: {
   484 		if (_town_sort_dirty) {
   495 			if (_town_sort_dirty) {
   485 			_town_sort_dirty = false;
   496 				_town_sort_dirty = false;
   486 			MakeSortedTownList();
   497 				MakeSortedTownList();
   487 		}
   498 			}
   488 
   499 
   489 		SetVScrollCount(w, _num_town_sort);
   500 			SetVScrollCount(w, _num_town_sort);
   490 
   501 
   491 		DrawWindowWidgets(w);
   502 			DrawWindowWidgets(w);
   492 		DrawSortButtonState(w, (_town_sort_order <= 1) ? TDW_SORTNAME : TDW_SORTPOPULATION, _town_sort_order & 1 ? SBS_DOWN : SBS_UP);
   503 			DrawSortButtonState(w, (_town_sort_order <= 1) ? TDW_SORTNAME : TDW_SORTPOPULATION, _town_sort_order & 1 ? SBS_DOWN : SBS_UP);
   493 
   504 
   494 		{
   505 			{
   495 			int n = 0;
   506 				int n = 0;
   496 			uint16 i = w->vscroll.pos;
   507 				uint16 i = w->vscroll.pos;
   497 			int y = 28;
   508 				int y = 28;
   498 
   509 
   499 			while (i < _num_town_sort) {
   510 				while (i < _num_town_sort) {
   500 				const Town* t = _town_sort[i];
   511 					const Town* t = _town_sort[i];
   501 
   512 
   502 				assert(t->xy);
   513 					assert(t->xy);
   503 
   514 
   504 				SetDParam(0, t->index);
   515 					SetDParam(0, t->index);
   505 				SetDParam(1, t->population);
   516 					SetDParam(1, t->population);
   506 				DrawString(2, y, STR_2057, TC_FROMSTRING);
   517 					DrawString(2, y, STR_2057, TC_FROMSTRING);
   507 
   518 
   508 				y += 10;
   519 					y += 10;
   509 				i++;
   520 					i++;
   510 				if (++n == w->vscroll.cap) break; // max number of towns in 1 window
   521 					if (++n == w->vscroll.cap) break; // max number of towns in 1 window
   511 			}
   522 				}
   512 			SetDParam(0, GetWorldPopulation());
   523 				SetDParam(0, GetWorldPopulation());
   513 			DrawString(3, w->height - 12 + 2, STR_TOWN_POPULATION, TC_FROMSTRING);
   524 				DrawString(3, w->height - 12 + 2, STR_TOWN_POPULATION, TC_FROMSTRING);
   514 		}
   525 			}
   515 	} break;
   526 		} break;
   516 
   527 
   517 	case WE_CLICK:
   528 		case WE_CLICK:
   518 		switch (e->we.click.widget) {
   529 			switch (e->we.click.widget) {
   519 			case TDW_SORTNAME: { /* Sort by Name ascending/descending */
   530 				case TDW_SORTNAME: /* Sort by Name ascending/descending */
   520 				_town_sort_order = (_town_sort_order == 0) ? 1 : 0;
   531 					_town_sort_order = (_town_sort_order == 0) ? 1 : 0;
   521 				_town_sort_dirty = true;
   532 					_town_sort_dirty = true;
   522 				SetWindowDirty(w);
   533 					SetWindowDirty(w);
   523 			} break;
   534 					break;
   524 
   535 
   525 			case TDW_SORTPOPULATION: { /* Sort by Population ascending/descending */
   536 				case TDW_SORTPOPULATION: /* Sort by Population ascending/descending */
   526 				_town_sort_order = (_town_sort_order == 2) ? 3 : 2;
   537 					_town_sort_order = (_town_sort_order == 2) ? 3 : 2;
   527 				_town_sort_dirty = true;
   538 					_town_sort_dirty = true;
   528 				SetWindowDirty(w);
   539 					SetWindowDirty(w);
   529 			} break;
   540 					break;
   530 
   541 
   531 			case TDW_CENTERTOWN: { /* Click on Town Matrix */
   542 				case TDW_CENTERTOWN: { /* Click on Town Matrix */
   532 				const Town* t;
   543 					const Town* t;
   533 
   544 
   534 				uint16 id_v = (e->we.click.pt.y - 28) / 10;
   545 					uint16 id_v = (e->we.click.pt.y - 28) / 10;
   535 
   546 
   536 				if (id_v >= w->vscroll.cap) return; // click out of bounds
   547 					if (id_v >= w->vscroll.cap) return; // click out of bounds
   537 
   548 
   538 				id_v += w->vscroll.pos;
   549 					id_v += w->vscroll.pos;
   539 
   550 
   540 				if (id_v >= _num_town_sort) return; // click out of town bounds
   551 					if (id_v >= _num_town_sort) return; // click out of town bounds
   541 
   552 
   542 				t = _town_sort[id_v];
   553 					t = _town_sort[id_v];
   543 				assert(t->xy);
   554 					assert(t->xy);
   544 				ScrollMainWindowToTile(t->xy);
   555 					ScrollMainWindowToTile(t->xy);
   545 			} break;
   556 				} break;
   546 		}
   557 			}
   547 		break;
   558 			break;
   548 
   559 
   549 	case WE_4:
   560 		case WE_4:
   550 		SetWindowDirty(w);
   561 			SetWindowDirty(w);
   551 		break;
   562 			break;
   552 
   563 
   553 	case WE_RESIZE:
   564 		case WE_RESIZE:
   554 		w->vscroll.cap += e->we.sizing.diff.y / 10;
   565 			w->vscroll.cap += e->we.sizing.diff.y / 10;
   555 		break;
   566 			break;
   556 	}
   567 	}
   557 }
   568 }
   558 
   569 
   559 static const WindowDesc _town_directory_desc = {
   570 static const WindowDesc _town_directory_desc = {
   560 	WDP_AUTO, WDP_AUTO, 208, 202, 208, 202,
   571 	WDP_AUTO, WDP_AUTO, 208, 202, 208, 202,
   588 {
   599 {
   589 	uint32 size = min(_scengen_town_size, (int)TSM_CITY);
   600 	uint32 size = min(_scengen_town_size, (int)TSM_CITY);
   590 	uint32 mode = _scengen_town_size > TSM_CITY ? TSM_CITY : TSM_FIXED;
   601 	uint32 mode = _scengen_town_size > TSM_CITY ? TSM_CITY : TSM_FIXED;
   591 	DoCommandP(tile, size, mode, CcBuildTown, CMD_BUILD_TOWN | CMD_MSG(STR_0236_CAN_T_BUILD_TOWN_HERE));
   602 	DoCommandP(tile, size, mode, CcBuildTown, CMD_BUILD_TOWN | CMD_MSG(STR_0236_CAN_T_BUILD_TOWN_HERE));
   592 }
   603 }
       
   604 
       
   605 enum TownScenarioEditorWidget {
       
   606 	TSEW_NEWTOWN = 4,
       
   607 	TSEW_RANDOMTOWN,
       
   608 	TSEW_MANYRANDOMTOWNS,
       
   609 	TSEW_SMALLTOWN,
       
   610 	TSEW_MEDIUMTOWN,
       
   611 	TSEW_LARGETOWN,
       
   612 	TSEW_CITY,
       
   613 };
   593 
   614 
   594 static const Widget _scen_edit_town_gen_widgets[] = {
   615 static const Widget _scen_edit_town_gen_widgets[] = {
   595 {   WWT_CLOSEBOX,   RESIZE_NONE,     7,     0,    10,     0,    13, STR_00C5,                 STR_018B_CLOSE_WINDOW},
   616 {   WWT_CLOSEBOX,   RESIZE_NONE,     7,     0,    10,     0,    13, STR_00C5,                 STR_018B_CLOSE_WINDOW},
   596 {    WWT_CAPTION,   RESIZE_NONE,     7,    11,   147,     0,    13, STR_0233_TOWN_GENERATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
   617 {    WWT_CAPTION,   RESIZE_NONE,     7,    11,   147,     0,    13, STR_0233_TOWN_GENERATION, STR_018C_WINDOW_TITLE_DRAG_THIS},
   597 {  WWT_STICKYBOX,   RESIZE_NONE,     7,   148,   159,     0,    13, 0x0,                      STR_STICKY_BUTTON},
   618 {  WWT_STICKYBOX,   RESIZE_NONE,     7,   148,   159,     0,    13, 0x0,                      STR_STICKY_BUTTON},
   608 };
   629 };
   609 
   630 
   610 static void ScenEditTownGenWndProc(Window *w, WindowEvent *e)
   631 static void ScenEditTownGenWndProc(Window *w, WindowEvent *e)
   611 {
   632 {
   612 	switch (e->event) {
   633 	switch (e->event) {
   613 	case WE_PAINT:
   634 		case WE_PAINT:
   614 		DrawWindowWidgets(w);
   635 			DrawWindowWidgets(w);
   615 		break;
   636 			break;
   616 
   637 
   617 	case WE_CREATE:
   638 		case WE_CREATE:
   618 		w->LowerWidget(_scengen_town_size + 7);
   639 			w->LowerWidget(_scengen_town_size + TSEW_SMALLTOWN);
   619 		break;
   640 			break;
   620 
   641 
   621 	case WE_CLICK:
   642 		case WE_CLICK:
   622 		switch (e->we.click.widget) {
   643 			switch (e->we.click.widget) {
   623 		case 4: // new town
   644 				case TSEW_NEWTOWN:
   624 			HandlePlacePushButton(w, 4, SPR_CURSOR_TOWN, VHM_RECT, PlaceProc_Town);
   645 					HandlePlacePushButton(w, TSEW_NEWTOWN, SPR_CURSOR_TOWN, VHM_RECT, PlaceProc_Town);
   625 			break;
   646 					break;
   626 		case 5: {// random town
   647 
   627 			Town *t;
   648 				case TSEW_RANDOMTOWN: {
   628 			uint size = min(_scengen_town_size, (int)TSM_CITY);
   649 					Town *t;
   629 			TownSizeMode mode = _scengen_town_size > TSM_CITY ? TSM_CITY : TSM_FIXED;
   650 					uint size = min(_scengen_town_size, (int)TSM_CITY);
   630 
   651 					TownSizeMode mode = _scengen_town_size > TSM_CITY ? TSM_CITY : TSM_FIXED;
   631 			w->HandleButtonClick(5);
   652 
   632 			_generating_world = true;
   653 					w->HandleButtonClick(TSEW_RANDOMTOWN);
   633 			t = CreateRandomTown(20, mode, size);
   654 					_generating_world = true;
   634 			_generating_world = false;
   655 					t = CreateRandomTown(20, mode, size);
   635 
   656 					_generating_world = false;
   636 			if (t == NULL) {
   657 
   637 				ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
   658 					if (t == NULL) {
   638 			} else {
   659 						ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
   639 				ScrollMainWindowToTile(t->xy);
   660 					} else {
   640 			}
   661 						ScrollMainWindowToTile(t->xy);
   641 
   662 					}
   642 			break;
   663 				} break;
   643 		}
   664 
   644 		case 6: {// many random towns
   665 				case TSEW_MANYRANDOMTOWNS:
   645 			w->HandleButtonClick(6);
   666 					w->HandleButtonClick(TSEW_MANYRANDOMTOWNS);
   646 
   667 
   647 			_generating_world = true;
   668 					_generating_world = true;
   648 			if (!GenerateTowns()) ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
   669 					if (!GenerateTowns()) ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
   649 			_generating_world = false;
   670 					_generating_world = false;
   650 			break;
   671 					break;
   651 		}
   672 
   652 
   673 				case TSEW_SMALLTOWN: case TSEW_MEDIUMTOWN: case TSEW_LARGETOWN: case TSEW_CITY:
   653 		case 7: case 8: case 9: case 10:
   674 					w->RaiseWidget(_scengen_town_size + TSEW_SMALLTOWN);
   654 			w->RaiseWidget(_scengen_town_size + 7);
   675 					_scengen_town_size = e->we.click.widget - TSEW_SMALLTOWN;
   655 			_scengen_town_size = e->we.click.widget - 7;
   676 					w->LowerWidget(_scengen_town_size + TSEW_SMALLTOWN);
   656 			w->LowerWidget(_scengen_town_size + 7);
   677 					SetWindowDirty(w);
       
   678 					break;
       
   679 			} break;
       
   680 
       
   681 		case WE_TIMEOUT:
       
   682 			w->RaiseWidget(TSEW_RANDOMTOWN);
       
   683 			w->RaiseWidget(TSEW_MANYRANDOMTOWNS);
   657 			SetWindowDirty(w);
   684 			SetWindowDirty(w);
   658 			break;
   685 			break;
   659 		}
   686 
   660 		break;
   687 		case WE_PLACE_OBJ:
   661 
   688 			_place_proc(e->we.place.tile);
   662 	case WE_TIMEOUT:
   689 			break;
   663 		w->RaiseWidget(5);
   690 
   664 		w->RaiseWidget(6);
   691 		case WE_ABORT_PLACE_OBJ:
   665 		SetWindowDirty(w);
   692 			w->RaiseButtons();
   666 		break;
   693 			w->LowerWidget(_scengen_town_size + TSEW_SMALLTOWN);
   667 	case WE_PLACE_OBJ:
   694 			SetWindowDirty(w);
   668 		_place_proc(e->we.place.tile);
   695 			break;
   669 		break;
       
   670 	case WE_ABORT_PLACE_OBJ:
       
   671 		w->RaiseButtons();
       
   672 		w->LowerWidget(_scengen_town_size + 7);
       
   673 		SetWindowDirty(w);
       
   674 		break;
       
   675 	}
   696 	}
   676 }
   697 }
   677 
   698 
   678 static const WindowDesc _scen_edit_town_gen_desc = {
   699 static const WindowDesc _scen_edit_town_gen_desc = {
   679 	WDP_AUTO, WDP_AUTO, 160, 95, 160, 95,
   700 	WDP_AUTO, WDP_AUTO, 160, 95, 160, 95,