OpenTTD Source 20241224-master-gee860a5c8e
terraform_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 <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "core/backup_type.hpp"
12#include "clear_map.h"
13#include "company_func.h"
14#include "company_base.h"
15#include "house.h"
16#include "gui.h"
17#include "window_gui.h"
18#include "window_func.h"
19#include "viewport_func.h"
20#include "command_func.h"
21#include "signs_func.h"
22#include "sound_func.h"
23#include "base_station_base.h"
24#include "textbuf_gui.h"
25#include "genworld.h"
26#include "tree_map.h"
27#include "landscape_type.h"
28#include "tilehighlight_func.h"
29#include "strings_func.h"
30#include "newgrf_object.h"
31#include "object.h"
32#include "hotkeys.h"
33#include "engine_base.h"
34#include "terraform_gui.h"
35#include "terraform_cmd.h"
36#include "zoom_func.h"
37#include "rail_cmd.h"
38#include "landscape_cmd.h"
39#include "terraform_cmd.h"
40#include "object_cmd.h"
41
43
44#include "table/strings.h"
45
46#include "safeguards.h"
47
48void CcTerraform(Commands, const CommandCost &result, Money, TileIndex tile)
49{
50 if (result.Succeeded()) {
52 } else {
54 }
55}
56
57
59static void GenerateDesertArea(TileIndex end, TileIndex start)
60{
61 if (_game_mode != GM_EDITOR) return;
62
63 Backup<bool> old_generating_world(_generating_world, true);
64
65 TileArea ta(start, end);
66 for (TileIndex tile : ta) {
70 }
71 old_generating_world.Restore();
73}
74
76static void GenerateRockyArea(TileIndex end, TileIndex start)
77{
78 if (_game_mode != GM_EDITOR) return;
79
80 bool success = false;
81 TileArea ta(start, end);
82
83 for (TileIndex tile : ta) {
84 switch (GetTileType(tile)) {
85 case MP_TREES:
86 if (GetTreeGround(tile) == TREE_GROUND_SHORE) continue;
87 [[fallthrough]];
88
89 case MP_CLEAR:
90 MakeClear(tile, CLEAR_ROCKS, 3);
91 break;
92
93 default:
94 continue;
95 }
97 success = true;
98 }
99
100 if (success && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, end);
101}
102
113{
115 /* When end_tile is MP_VOID, the error tile will not be visible to the
116 * user. This happens when terraforming at the southern border. */
117 if (TileX(end_tile) == Map::MaxX()) end_tile += TileDiffXY(-1, 0);
118 if (TileY(end_tile) == Map::MaxY()) end_tile += TileDiffXY(0, -1);
119 }
120
121 switch (proc) {
123 Command<CMD_CLEAR_AREA>::Post(STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, end_tile, start_tile, _ctrl_pressed);
124 break;
126 Command<CMD_LEVEL_LAND>::Post(STR_ERROR_CAN_T_RAISE_LAND_HERE, CcTerraform, end_tile, start_tile, _ctrl_pressed, LM_RAISE);
127 break;
129 Command<CMD_LEVEL_LAND>::Post(STR_ERROR_CAN_T_LOWER_LAND_HERE, CcTerraform, end_tile, start_tile, _ctrl_pressed, LM_LOWER);
130 break;
131 case DDSP_LEVEL_AREA:
132 Command<CMD_LEVEL_LAND>::Post(STR_ERROR_CAN_T_LEVEL_LAND_HERE, CcTerraform, end_tile, start_tile, _ctrl_pressed, LM_LEVEL);
133 break;
135 GenerateRockyArea(end_tile, start_tile);
136 break;
138 GenerateDesertArea(end_tile, start_tile);
139 break;
140 default:
141 return false;
142 }
143
144 return true;
145}
146
155
159
161 {
162 /* This is needed as we like to have the tree available on OnInit. */
163 this->CreateNestedTree();
164 this->FinishInitNested(window_number);
165 this->last_user_action = INVALID_WID_TT;
166 }
167
169 {
170 }
171
172 void OnInit() override
173 {
174 /* Don't show the place object button when there are no objects to place. */
177 }
178
179 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
180 {
181 if (widget < WID_TT_BUTTONS_START) return;
182
183 switch (widget) {
184 case WID_TT_LOWER_LAND: // Lower land button
186 this->last_user_action = widget;
187 break;
188
189 case WID_TT_RAISE_LAND: // Raise land button
191 this->last_user_action = widget;
192 break;
193
194 case WID_TT_LEVEL_LAND: // Level land button
195 HandlePlacePushButton(this, WID_TT_LEVEL_LAND, SPR_CURSOR_LEVEL_LAND, HT_POINT | HT_DIAGONAL);
196 this->last_user_action = widget;
197 break;
198
199 case WID_TT_DEMOLISH: // Demolish aka dynamite button
201 this->last_user_action = widget;
202 break;
203
204 case WID_TT_BUY_LAND: // Buy land button
205 HandlePlacePushButton(this, WID_TT_BUY_LAND, SPR_CURSOR_BUY_LAND, HT_RECT | HT_DIAGONAL);
206 this->last_user_action = widget;
207 break;
208
209 case WID_TT_PLANT_TREES: // Plant trees button
210 ShowBuildTreesToolbar();
211 break;
212
213 case WID_TT_PLACE_SIGN: // Place sign button
214 HandlePlacePushButton(this, WID_TT_PLACE_SIGN, SPR_CURSOR_SIGN, HT_RECT);
215 this->last_user_action = widget;
216 break;
217
218 case WID_TT_PLACE_OBJECT: // Place object button
220 break;
221
222 default: NOT_REACHED();
223 }
224 }
225
226 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
227 {
228 switch (this->last_user_action) {
229 case WID_TT_LOWER_LAND: // Lower land button
231 break;
232
233 case WID_TT_RAISE_LAND: // Raise land button
235 break;
236
237 case WID_TT_LEVEL_LAND: // Level land button
239 break;
240
241 case WID_TT_DEMOLISH: // Demolish aka dynamite button
243 break;
244
245 case WID_TT_BUY_LAND: // Buy land button
247 break;
248
249 case WID_TT_PLACE_SIGN: // Place sign button
250 PlaceProc_Sign(tile);
251 break;
252
253 default: NOT_REACHED();
254 }
255 }
256
258 {
259 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
260 }
261
268
269 void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override
270 {
271 if (pt.x != -1) {
272 switch (select_proc) {
273 default: NOT_REACHED();
277 case DDSP_LEVEL_AREA:
278 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
279 break;
282 /* When end_tile is MP_VOID, the error tile will not be visible to the
283 * user. This happens when terraforming at the southern border. */
284 if (TileX(end_tile) == Map::MaxX()) end_tile += TileDiffXY(-1, 0);
285 if (TileY(end_tile) == Map::MaxY()) end_tile += TileDiffXY(0, -1);
286 }
288 end_tile, start_tile, OBJECT_OWNED_LAND, 0, (_ctrl_pressed ? true : false));
289 break;
290 }
291 }
292 }
293
294 void OnPlaceObjectAbort() override
295 {
296 this->RaiseButtons();
297 }
298
305 {
306 if (_game_mode != GM_NORMAL) return ES_NOT_HANDLED;
307 Window *w = ShowTerraformToolbar(nullptr);
308 if (w == nullptr) return ES_NOT_HANDLED;
309 return w->OnHotkey(hotkey);
310 }
311
312 static inline HotkeyList hotkeys{"terraform", {
316 Hotkey('D' | WKC_GLOBAL_HOTKEY, "dynamite", WID_TT_DEMOLISH),
317 Hotkey('U', "buyland", WID_TT_BUY_LAND),
318 Hotkey('I', "trees", WID_TT_PLANT_TREES),
319 Hotkey('O', "placesign", WID_TT_PLACE_SIGN),
320 Hotkey('P', "placeobject", WID_TT_PLACE_OBJECT),
322};
323
324static constexpr NWidgetPart _nested_terraform_widgets[] = {
326 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
327 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_LANDSCAPING_TOOLBAR, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
328 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
329 EndContainer(),
331 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_LOWER_LAND), SetMinimalSize(22, 22),
332 SetFill(0, 1), SetDataTip(SPR_IMG_TERRAFORM_DOWN, STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND),
333 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_RAISE_LAND), SetMinimalSize(22, 22),
334 SetFill(0, 1), SetDataTip(SPR_IMG_TERRAFORM_UP, STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND),
335 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_LEVEL_LAND), SetMinimalSize(22, 22),
336 SetFill(0, 1), SetDataTip(SPR_IMG_LEVEL_LAND, STR_LANDSCAPING_LEVEL_LAND_TOOLTIP),
337
338 NWidget(WWT_PANEL, COLOUR_DARK_GREEN), SetMinimalSize(4, 22), EndContainer(),
339
340 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_DEMOLISH), SetMinimalSize(22, 22),
341 SetFill(0, 1), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
342 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_BUY_LAND), SetMinimalSize(22, 22),
343 SetFill(0, 1), SetDataTip(SPR_IMG_BUY_LAND, STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND),
344 NWidget(WWT_PUSHIMGBTN, COLOUR_DARK_GREEN, WID_TT_PLANT_TREES), SetMinimalSize(22, 22),
345 SetFill(0, 1), SetDataTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES),
346 NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_TT_PLACE_SIGN), SetMinimalSize(22, 22),
347 SetFill(0, 1), SetDataTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN),
349 NWidget(WWT_PUSHIMGBTN, COLOUR_DARK_GREEN, WID_TT_PLACE_OBJECT), SetMinimalSize(22, 22),
350 SetFill(0, 1), SetDataTip(SPR_IMG_TRANSMITTER, STR_SCENEDIT_TOOLBAR_PLACE_OBJECT),
351 EndContainer(),
352 EndContainer(),
353};
354
355static WindowDesc _terraform_desc(
356 WDP_MANUAL, "toolbar_landscape", 0, 0,
359 _nested_terraform_widgets,
360 &TerraformToolbarWindow::hotkeys
361);
362
369{
370 if (!Company::IsValidID(_local_company)) return nullptr;
371
372 Window *w;
373 if (link == nullptr) {
374 w = AllocateWindowDescFront<TerraformToolbarWindow>(_terraform_desc, 0);
375 return w;
376 }
377
378 /* Delete the terraform toolbar to place it again. */
380 w = AllocateWindowDescFront<TerraformToolbarWindow>(_terraform_desc, 0);
381 /* Align the terraform toolbar under the main toolbar. */
382 w->top -= w->height;
383 w->SetDirty();
384 /* Put the linked toolbar to the left / right of it. */
385 link->left = w->left + (_current_text_dir == TD_RTL ? w->width : -link->width);
386 link->top = w->top;
387 link->SetDirty();
388
389 return w;
390}
391
392static uint8_t _terraform_size = 1;
393
403static void CommonRaiseLowerBigLand(TileIndex tile, bool mode)
404{
405 if (_terraform_size == 1) {
406 StringID msg =
407 mode ? STR_ERROR_CAN_T_RAISE_LAND_HERE : STR_ERROR_CAN_T_LOWER_LAND_HERE;
408
409 Command<CMD_TERRAFORM_LAND>::Post(msg, CcTerraform, tile, SLOPE_N, mode);
410 } else {
411 assert(_terraform_size != 0);
412 TileArea ta(tile, _terraform_size, _terraform_size);
413 ta.ClampToMap();
414
415 if (ta.w == 0 || ta.h == 0) return;
416
418
419 uint h;
420 if (mode != 0) {
421 /* Raise land */
422 h = MAX_TILE_HEIGHT;
423 for (TileIndex tile2 : ta) {
424 h = std::min(h, TileHeight(tile2));
425 }
426 } else {
427 /* Lower land */
428 h = 0;
429 for (TileIndex tile2 : ta) {
430 h = std::max(h, TileHeight(tile2));
431 }
432 }
433
434 for (TileIndex tile2 : ta) {
435 if (TileHeight(tile2) == h) {
437 }
438 }
439 }
440}
441
442static const int8_t _multi_terraform_coords[][2] = {
443 { 0, -2},
444 { 4, 0}, { -4, 0}, { 0, 2},
445 { -8, 2}, { -4, 4}, { 0, 6}, { 4, 4}, { 8, 2},
446 {-12, 0}, { -8, -2}, { -4, -4}, { 0, -6}, { 4, -4}, { 8, -2}, { 12, 0},
447 {-16, 2}, {-12, 4}, { -8, 6}, { -4, 8}, { 0, 10}, { 4, 8}, { 8, 6}, { 12, 4}, { 16, 2},
448 {-20, 0}, {-16, -2}, {-12, -4}, { -8, -6}, { -4, -8}, { 0,-10}, { 4, -8}, { 8, -6}, { 12, -4}, { 16, -2}, { 20, 0},
449 {-24, 2}, {-20, 4}, {-16, 6}, {-12, 8}, { -8, 10}, { -4, 12}, { 0, 14}, { 4, 12}, { 8, 10}, { 12, 8}, { 16, 6}, { 20, 4}, { 24, 2},
450 {-28, 0}, {-24, -2}, {-20, -4}, {-16, -6}, {-12, -8}, { -8,-10}, { -4,-12}, { 0,-14}, { 4,-12}, { 8,-10}, { 12, -8}, { 16, -6}, { 20, -4}, { 24, -2}, { 28, 0},
451};
452
453static constexpr NWidgetPart _nested_scen_edit_land_gen_widgets[] = {
455 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
456 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_TERRAFORM_TOOLBAR_LAND_GENERATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
457 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
458 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
459 EndContainer(),
460 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
461 NWidget(NWID_HORIZONTAL), SetPadding(2, 2, 7, 2),
463 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_ETT_DEMOLISH), SetMinimalSize(22, 22),
464 SetFill(0, 1), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
465 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_ETT_LOWER_LAND), SetMinimalSize(22, 22),
466 SetFill(0, 1), SetDataTip(SPR_IMG_TERRAFORM_DOWN, STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND),
467 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_ETT_RAISE_LAND), SetMinimalSize(22, 22),
468 SetFill(0, 1), SetDataTip(SPR_IMG_TERRAFORM_UP, STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND),
469 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_ETT_LEVEL_LAND), SetMinimalSize(22, 22),
470 SetFill(0, 1), SetDataTip(SPR_IMG_LEVEL_LAND, STR_LANDSCAPING_LEVEL_LAND_TOOLTIP),
472 SetFill(0, 1), SetDataTip(SPR_IMG_ROCKS, STR_TERRAFORM_TOOLTIP_PLACE_ROCKY_AREAS_ON_LANDSCAPE),
475 SetFill(0, 1), SetDataTip(SPR_IMG_DESERT, STR_TERRAFORM_TOOLTIP_DEFINE_DESERT_AREA),
476 EndContainer(),
478 SetFill(0, 1), SetDataTip(SPR_IMG_TRANSMITTER, STR_SCENEDIT_TOOLBAR_PLACE_OBJECT),
480 EndContainer(),
483 NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_ETT_DOTS), SetMinimalSize(59, 31), SetDataTip(STR_EMPTY, STR_NULL),
487 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_ETT_INCREASE_SIZE), SetMinimalSize(12, 12), SetDataTip(SPR_ARROW_UP, STR_TERRAFORM_TOOLTIP_INCREASE_SIZE_OF_LAND_AREA),
489 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_ETT_DECREASE_SIZE), SetMinimalSize(12, 12), SetDataTip(SPR_ARROW_DOWN, STR_TERRAFORM_TOOLTIP_DECREASE_SIZE_OF_LAND_AREA),
491 EndContainer(),
493 EndContainer(),
496 SetFill(1, 0), SetDataTip(STR_TERRAFORM_SE_NEW_WORLD, STR_TERRAFORM_TOOLTIP_GENERATE_RANDOM_LAND), SetPadding(0, 2, 0, 2),
498 SetFill(1, 0), SetDataTip(STR_TERRAFORM_RESET_LANDSCAPE, STR_TERRAFORM_RESET_LANDSCAPE_TOOLTIP), SetPadding(1, 2, 2, 2),
499 EndContainer(),
500};
501
506static void ResetLandscapeConfirmationCallback(Window *, bool confirmed)
507{
508 if (confirmed) {
509 /* Set generating_world to true to get instant-green grass after removing
510 * company property. */
511 Backup<bool> old_generating_world(_generating_world, true);
512
513 /* Delete all companies */
514 for (Company *c : Company::Iterate()) {
516 delete c;
517 }
518
519 old_generating_world.Restore();
520
521 /* Delete all station signs */
522 for (BaseStation *st : BaseStation::Iterate()) {
523 /* There can be buoys, remove them */
525 if (!st->IsInUse()) delete st;
526 }
527
528 /* Now that all vehicles are gone, we can reset the engine pool. Maybe it reduces some NewGRF changing-mess */
530
532 }
533}
534
538
540 {
541 this->CreateNestedTree();
543 show_desert->SetDisplayedPlane(_settings_game.game_creation.landscape == LT_TROPIC ? 0 : SZSP_NONE);
544 this->FinishInitNested(window_number);
545 this->last_user_action = INVALID_WID_ETT;
546 }
547
548 void OnPaint() override
549 {
550 this->DrawWidgets();
551
552 if (this->IsWidgetLowered(WID_ETT_LOWER_LAND) || this->IsWidgetLowered(WID_ETT_RAISE_LAND)) { // change area-size if raise/lower corner is selected
553 SetTileSelectSize(_terraform_size, _terraform_size);
554 }
555 }
556
558 {
559 if (widget != WID_ETT_DOTS) return;
560
561 size.width = std::max<uint>(size.width, ScaleGUITrad(59));
562 size.height = std::max<uint>(size.height, ScaleGUITrad(31));
563 }
564
565 void DrawWidget(const Rect &r, WidgetID widget) const override
566 {
567 if (widget != WID_ETT_DOTS) return;
568
569 int center_x = RoundDivSU(r.left + r.right, 2);
570 int center_y = RoundDivSU(r.top + r.bottom, 2);
571
572 int n = _terraform_size * _terraform_size;
573 const int8_t *coords = &_multi_terraform_coords[0][0];
574
575 assert(n != 0);
576 do {
577 DrawSprite(SPR_WHITE_POINT, PAL_NONE, center_x + ScaleGUITrad(coords[0]), center_y + ScaleGUITrad(coords[1]));
578 coords += 2;
579 } while (--n);
580 }
581
582 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
583 {
584 if (widget < WID_ETT_BUTTONS_START) return;
585
586 switch (widget) {
587 case WID_ETT_DEMOLISH: // Demolish aka dynamite button
589 this->last_user_action = widget;
590 break;
591
592 case WID_ETT_LOWER_LAND: // Lower land button
594 this->last_user_action = widget;
595 break;
596
597 case WID_ETT_RAISE_LAND: // Raise land button
599 this->last_user_action = widget;
600 break;
601
602 case WID_ETT_LEVEL_LAND: // Level land button
603 HandlePlacePushButton(this, WID_ETT_LEVEL_LAND, SPR_CURSOR_LEVEL_LAND, HT_POINT | HT_DIAGONAL);
604 this->last_user_action = widget;
605 break;
606
607 case WID_ETT_PLACE_ROCKS: // Place rocks button
608 HandlePlacePushButton(this, WID_ETT_PLACE_ROCKS, SPR_CURSOR_ROCKY_AREA, HT_RECT);
609 this->last_user_action = widget;
610 break;
611
612 case WID_ETT_PLACE_DESERT: // Place desert button (in tropical climate)
613 HandlePlacePushButton(this, WID_ETT_PLACE_DESERT, SPR_CURSOR_DESERT, HT_RECT);
614 this->last_user_action = widget;
615 break;
616
617 case WID_ETT_PLACE_OBJECT: // Place transmitter button
619 break;
620
622 case WID_ETT_DECREASE_SIZE: { // Increase/Decrease terraform size
623 int size = (widget == WID_ETT_INCREASE_SIZE) ? 1 : -1;
624 this->HandleButtonClick(widget);
625 size += _terraform_size;
626
627 if (!IsInsideMM(size, 1, 8 + 1)) return;
628 _terraform_size = size;
629
631 this->SetDirty();
632 break;
633 }
634
635 case WID_ETT_NEW_SCENARIO: // gen random land
636 this->HandleButtonClick(widget);
638 break;
639
640 case WID_ETT_RESET_LANDSCAPE: // Reset landscape
642 break;
643
644 default: NOT_REACHED();
645 }
646 }
647
648 void OnTimeout() override
649 {
650 for (const auto &pair : this->widget_lookup) {
651 if (pair.first < WID_ETT_START || (pair.first >= WID_ETT_BUTTONS_START && pair.first < WID_ETT_BUTTONS_END)) continue; // skip the buttons
652 this->RaiseWidgetWhenLowered(pair.first);
653 }
654 }
655
656 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
657 {
658 switch (this->last_user_action) {
659 case WID_ETT_DEMOLISH: // Demolish aka dynamite button
661 break;
662
663 case WID_ETT_LOWER_LAND: // Lower land button
664 CommonRaiseLowerBigLand(tile, false);
665 break;
666
667 case WID_ETT_RAISE_LAND: // Raise land button
668 CommonRaiseLowerBigLand(tile, true);
669 break;
670
671 case WID_ETT_LEVEL_LAND: // Level land button
673 break;
674
675 case WID_ETT_PLACE_ROCKS: // Place rocks button
677 break;
678
679 case WID_ETT_PLACE_DESERT: // Place desert button (in tropical climate)
681 break;
682
683 default: NOT_REACHED();
684 }
685 }
686
688 {
689 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
690 }
691
692 void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override
693 {
694 if (pt.x != -1) {
695 switch (select_proc) {
696 default: NOT_REACHED();
701 case DDSP_LEVEL_AREA:
703 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
704 break;
705 }
706 }
707 }
708
709 void OnPlaceObjectAbort() override
710 {
711 this->RaiseButtons();
712 this->SetDirty();
713 }
714
721 {
722 if (_game_mode != GM_EDITOR) return ES_NOT_HANDLED;
724 if (w == nullptr) return ES_NOT_HANDLED;
725 return w->OnHotkey(hotkey);
726 }
727
728 static inline HotkeyList hotkeys{"terraform_editor", {
729 Hotkey('D' | WKC_GLOBAL_HOTKEY, "dynamite", WID_ETT_DEMOLISH),
733 Hotkey('R', "rocky", WID_ETT_PLACE_ROCKS),
734 Hotkey('T', "desert", WID_ETT_PLACE_DESERT),
735 Hotkey('O', "object", WID_ETT_PLACE_OBJECT),
737};
738
739static WindowDesc _scen_edit_land_gen_desc(
740 WDP_AUTO, "toolbar_landscape_scen", 0, 0,
743 _nested_scen_edit_land_gen_widgets,
744 &ScenarioEditorLandscapeGenerationWindow::hotkeys
745);
746
752{
753 return AllocateWindowDescFront<ScenarioEditorLandscapeGenerationWindow>(_scen_edit_land_gen_desc, 0);
754}
Class for backupping variables and making sure they are restored later.
Base classes/functions for base stations.
Common return value for all commands.
bool Succeeded() const
Did this command succeed?
Stacked widgets, widgets all occupying the same space in the window.
bool SetDisplayedPlane(int plane)
Select which plane to show (for NWID_SELECTION only).
Definition widget.cpp:1335
static uint GetUIClassCount()
Get the number of classes available to the user.
Map accessors for 'clear' tiles.
@ CLEAR_ROCKS
3
Definition clear_map.h:22
void MakeClear(Tile t, ClearGround g, uint density)
Make a clear tile.
Definition clear_map.h:259
Functions related to commands.
@ DC_BANKRUPT
company bankrupts, skip money check, skip vehicle on tile check in some cases
@ DC_EXEC
execute the given command
Commands
List of commands.
Definition of stuff that is very close to a company, like the company struct itself.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Functions related to companies.
void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
Change the ownership of all the items of a company.
Definition economy.cpp:334
@ INVALID_OWNER
An invalid owner.
Base class for engines.
bool _generating_world
Whether we are generating the map or not.
Definition genworld.cpp:67
Functions related to world/map generation.
void ShowCreateScenario()
Show the window to create a scenario.
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:38
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition gfx.cpp:988
@ WKC_GLOBAL_HOTKEY
Fake keycode bit to indicate global hotkeys.
Definition gfx_type.h:34
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
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 SetDataTip(uint32_t data, StringID tip)
Widget part function for setting the data and tooltip.
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=-1)
Widget part function for starting a new 'real' widget.
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
void SetDirty() const
Mark entire window as dirty (in need of re-paint)
Definition window.cpp:940
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1529
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
GUI functions that shouldn't be here.
Hotkey related functions.
definition of HouseSpec and accessors
Command definitions related to landscape (slopes etc.).
Types related to the landscape.
bool HandlePlacePushButton(Window *w, WidgetID widget, CursorID cursor, HighLightStyle mode)
This code is shared for the majority of the pushbuttons.
Definition main_gui.cpp:63
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition map_func.h:389
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:425
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:415
@ LM_LEVEL
Level the land.
Definition map_type.h:44
@ LM_LOWER
Lower the land.
Definition map_type.h:45
@ LM_RAISE
Raise the land.
Definition map_type.h:46
constexpr int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
void ShowQuery(StringID caption, StringID 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...
Functions related to NewGRF objects.
Functions related to objects.
Window * ShowBuildObjectPicker()
Show our object picker.
Command definitions related to objects.
static const ObjectType OBJECT_OWNED_LAND
Owned land 'flag'.
Definition object_type.h:19
Command definitions for rail.
A number of safeguards to prevent using unsafe methods.
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:57
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:56
void PlaceProc_Sign(TileIndex tile)
PlaceProc function, called when someone pressed the button if the sign-tool is selected.
Functions related to signs.
@ SLOPE_N
the north corner of the tile is raised
Definition slope_type.h:53
Functions related to sound.
@ SND_15_BEEP
19 == 0x13 GUI button click
Definition sound_type.h:66
@ SND_1F_CONSTRUCTION_OTHER
29 == 0x1D Construction: other (non-water, non-rail, non-bridge)
Definition sound_type.h:76
static const CursorID ANIMCURSOR_DEMOLISH
704 - 707 - demolish dynamite
Definition sprites.h:1508
static const CursorID ANIMCURSOR_LOWERLAND
699 - 701 - lower land tool
Definition sprites.h:1509
static const CursorID ANIMCURSOR_RAISELAND
696 - 698 - raise land tool
Definition sprites.h:1510
bool IsBuoyTile(Tile t)
Is tile t a buoy tile?
Definition of base types and functions in a cross-platform compatible way.
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
Functions related to OTTD's strings.
@ TD_RTL
Text is written right-to-left by default.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Class to backup a specific variable and restore it later.
void Restore()
Restore the variable.
Base class for all station-ish types.
SoundSettings sound
sound effect settings
bool freeform_edges
allow terraforming the tiles at the map edges
Dimensions (a width and height) of a rectangle in 2D.
static bool ResetToCurrentNewGRFConfig()
Tries to reset the engine mapping to match the current NewGRF configuration.
Definition engine.cpp:585
uint8_t landscape
the landscape we're currently in
ConstructionSettings construction
construction of things in-game
GameCreationSettings game_creation
settings used during the creation of a game (map)
List of hotkeys for a window.
Definition hotkeys.h:37
All data for a single hotkey.
Definition hotkeys.h:21
static uint MaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
Definition map_func.h:306
static debug_inline uint MaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition map_func.h:297
Partial widget specification to allow NWidgets to be written nested.
Represents the covered area of e.g.
void ClampToMap()
Clamp the tile area to map borders.
Definition tilearea.cpp:142
uint16_t w
The width of the area.
uint16_t h
The height of the area.
Coordinates of a point in 2D.
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Specification of a rectangle with absolute coordinates of all edges.
Landscape generation window handler in the scenario editor.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
int last_user_action
Last started user action.
void OnPlaceObject(Point pt, TileIndex tile) override
The user clicked some place on the map when a tile highlight mode has been set.
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
void OnPaint() override
The window must be repainted.
void DrawWidget(const Rect &r, WidgetID widget) const override
Draw the contents of a nested widget.
void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override
The user has dragged over the map when the tile highlight mode has been set.
void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override
The user is dragging over the map when the tile highlight mode has been set.
void OnTimeout() override
Called when this window's timeout has been reached.
static EventState TerraformToolbarEditorGlobalHotkeys(int hotkey)
Handler for global hotkeys of the ScenarioEditorLandscapeGenerationWindow.
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.
bool click_beep
Beep on a random selection of buttons.
bool confirm
Play sound effect on successful constructions or other actions.
Terra form toolbar managing class.
void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override
The user has dragged over the map when the tile highlight mode has been set.
void OnPlaceObjectAbort() override
The user cancelled a tile highlight mode that has been set.
void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override
The user is dragging over the map when the tile highlight mode has been set.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
int last_user_action
Last started user action.
void OnInit() override
Notification that the nested widget tree gets initialized.
Point OnInitialPosition(int16_t sm_width, int16_t sm_height, int window_number) override
Compute the initial position of the window.
static EventState TerraformToolbarGlobalHotkeys(int hotkey)
Handler for global hotkeys of the TerraformToolbarWindow.
void OnPlaceObject(Point pt, TileIndex tile) override
The user clicked some place on the map when a tile highlight mode has been set.
High level window description.
Definition window_gui.h:159
Data structure for an opened window.
Definition window_gui.h:273
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1733
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:732
void RaiseWidgetWhenLowered(WidgetID widget_index)
Marks a widget as raised and dirty (redraw), when it is marked as lowered.
Definition window_gui.h:484
ResizeInfo resize
Resize information.
Definition window_gui.h:314
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1723
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
Definition window_gui.h:497
void RaiseButtons(bool autoraise=false)
Raise the buttons of the window.
Definition window.cpp:525
int left
x position of left edge of the window
Definition window_gui.h:309
int top
y position of top edge of the window
Definition window_gui.h:310
WidgetLookup widget_lookup
Indexed access to the nested widget tree. Do not access directly, use Window::GetWidget() instead.
Definition window_gui.h:322
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:977
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:590
virtual EventState OnHotkey(int hotkey)
A hotkey has been pressed.
Definition window.cpp:565
int height
Height of the window (number of pixels down in y direction)
Definition window_gui.h:312
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:311
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:302
Command definitions related to terraforming.
bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_tile, TileIndex end_tile)
A central place to handle all X_AND_Y dragged GUI functions.
static void ResetLandscapeConfirmationCallback(Window *, bool confirmed)
Callback function for the scenario editor 'reset landscape' confirmation window.
void PlaceProc_DemolishArea(TileIndex tile)
Start a drag for demolishing an area.
Window * ShowEditorTerraformToolbar()
Show the toolbar for terraforming in the scenario editor.
static void GenerateRockyArea(TileIndex end, TileIndex start)
Scenario editor command that generates rocky areas.
static void CommonRaiseLowerBigLand(TileIndex tile, bool mode)
Raise/Lower a bigger chunk of land at the same time in the editor.
Window * ShowTerraformToolbar(Window *link)
Show the toolbar for terraforming in the game.
static void GenerateDesertArea(TileIndex end, TileIndex start)
Scenario editor command that generates desert areas.
GUI stuff related to terraforming.
Types related to the terraform widgets.
@ WID_ETT_INCREASE_SIZE
Upwards arrow button to increase terraforming size.
@ WID_ETT_PLACE_ROCKS
Place rocks button.
@ WID_ETT_DOTS
Invisible widget for rendering the terraform size on.
@ WID_ETT_DECREASE_SIZE
Downwards arrow button to decrease terraforming size.
@ WID_ETT_SHOW_PLACE_DESERT
Should the place desert button be shown?
@ WID_ETT_PLACE_OBJECT
Place transmitter button.
@ WID_ETT_PLACE_DESERT
Place desert button (in tropical climate).
@ WID_ETT_NEW_SCENARIO
Button for generating a new scenario.
@ WID_ETT_RESET_LANDSCAPE
Button for removing all company-owned property.
@ WID_ETT_BUTTONS_START
Start of pushable buttons.
@ WID_ETT_LEVEL_LAND
Level land button.
@ WID_ETT_LOWER_LAND
Lower land button.
@ WID_ETT_START
Used for iterations.
@ WID_ETT_RAISE_LAND
Raise land button.
@ WID_ETT_BUTTONS_END
End of pushable buttons.
@ WID_ETT_DEMOLISH
Demolish aka dynamite button.
@ WID_TT_LEVEL_LAND
Level land button.
@ WID_TT_DEMOLISH
Demolish aka dynamite button.
@ WID_TT_SHOW_PLACE_OBJECT
Should the place object button be shown?
@ WID_TT_RAISE_LAND
Raise land button.
@ WID_TT_PLACE_OBJECT
Place object button.
@ WID_TT_PLANT_TREES
Plant trees button (note: opens separate window, no place-push-button).
@ WID_TT_PLACE_SIGN
Place sign button.
@ WID_TT_BUY_LAND
Buy land button.
@ WID_TT_BUTTONS_START
Start of pushable buttons.
@ WID_TT_LOWER_LAND
Lower land button.
Stuff related to the text buffer GUI.
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
void SetTropicZone(Tile tile, TropicZone type)
Set the tropic zone.
Definition tile_map.h:225
static debug_inline uint TileHeight(Tile tile)
Returns the height of a tile.
Definition tile_map.h:29
@ TROPICZONE_DESERT
Tile is desert.
Definition tile_type.h:78
@ TROPICZONE_NORMAL
Normal tropiczone.
Definition tile_type.h:77
static const uint MAX_TILE_HEIGHT
Maximum allowed tile height.
Definition tile_type.h:24
@ MP_TREES
Tile got trees.
Definition tile_type.h:52
@ MP_CLEAR
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:48
Functions related to tile highlights.
void VpSelectTilesWithMethod(int x, int y, ViewportPlaceMethod method)
Selects tiles while dragging.
void VpStartPlaceSizing(TileIndex tile, ViewportPlaceMethod method, ViewportDragDropSelectionProcess process)
highlighting tiles while only going over them with the mouse
@ HT_DIAGONAL
Also allow 'diagonal rectangles'. Only usable in combination with HT_RECT or HT_POINT.
@ HT_POINT
point (lower land, raise land, level land, ...)
@ HT_RECT
rectangle (stations, depots, ...)
Map accessors for tree tiles.
TreeGround GetTreeGround(Tile t)
Returns the groundtype for tree tiles.
Definition tree_map.h:102
@ TREE_GROUND_SHORE
shore
Definition tree_map.h:56
void SetTileSelectSize(int w, int h)
Highlight w by h tiles at the cursor.
void SetRedErrorSquare(TileIndex tile)
Set a tile to display a red error square.
Functions related to (drawing on) viewports.
ViewportDragDropSelectionProcess
Drag and drop selection process, or, what to do with an area of land when you've selected it.
@ DDSP_CREATE_DESERT
Fill area with desert.
@ DDSP_LOWER_AND_LEVEL_AREA
Lower / level area.
@ DDSP_DEMOLISH_AREA
Clear area.
@ DDSP_CREATE_ROCKS
Fill area with rocks.
@ DDSP_RAISE_AND_LEVEL_AREA
Raise / level area.
@ DDSP_LEVEL_AREA
Level area.
@ DDSP_BUILD_OBJECT
Build an object.
ViewportPlaceMethod
Viewport place method (type of highlighted area and placed objects)
@ VPM_X_AND_Y
area of land in X and Y directions
static RectPadding ScaleGUITrad(const RectPadding &r)
Scale a RectPadding to GUI zoom level.
Definition widget.cpp:35
@ SZSP_NONE
Display plane with zero size in both directions (none filling and resizing).
@ WWT_IMGBTN
(Toggle) Button with image
Definition widget_type.h:52
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
@ NWID_SPACER
Invisible widget that takes some space.
Definition widget_type.h:79
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:75
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:55
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:50
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX)
Definition widget_type.h:66
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX)
Definition widget_type.h:64
@ WWT_CAPTION
Window caption (window title between closebox and stickybox)
Definition widget_type.h:61
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:77
@ WWT_CLOSEBOX
Close box (at top-left of a window)
Definition widget_type.h:69
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition widget_type.h:48
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:80
void CloseWindowById(WindowClass cls, WindowNumber number, bool force, int data)
Close a window by its class and window number (if it is open).
Definition window.cpp:1140
Point GetToolbarAlignedWindowPosition(int window_width)
Computer the position of the top-left corner of a window to be opened right under the toolbar.
Definition window.cpp:1627
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:3236
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
@ WDF_CONSTRUCTION
This window is used for construction; close it whenever changing company.
Definition window_gui.h:203
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:147
@ WDP_MANUAL
Manually align the window (so no automatic location finding)
Definition window_gui.h:146
int WidgetID
Widget ID.
Definition window_type.h:18
int32_t WindowNumber
Number to differentiate different windows of the same class.
EventState
State of handling an event.
@ ES_NOT_HANDLED
The passed event is not handled.
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:45
@ WC_SCEN_LAND_GEN
Landscape generation (in Scenario Editor); Window numbers:
@ WC_TOWN_VIEW
Town view; Window numbers:
Functions related to zooming.