OpenTTD Source 20260311-master-g511d3794ce
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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
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()) {
51 if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile);
52 } else {
54 }
55}
56
57
63static void GenerateDesertArea(TileIndex end, TileIndex start)
64{
65 if (_game_mode != GM_EDITOR) return;
66
67 Backup<bool> old_generating_world(_generating_world, true);
68
69 TileArea ta(start, end);
70 for (TileIndex tile : ta) {
72 Command<Commands::LandscapeClear>::Post(tile);
74 }
75 old_generating_world.Restore();
77}
78
84static void GenerateRockyArea(TileIndex end, TileIndex start)
85{
86 if (_game_mode != GM_EDITOR) return;
87
88 bool success = false;
89 TileArea ta(start, end);
90
91 for (TileIndex tile : ta) {
92 switch (GetTileType(tile)) {
93 case TileType::Trees:
94 if (GetTreeGround(tile) == TreeGround::Shore) continue;
95 [[fallthrough]];
96
97 case TileType::Clear:
99 break;
100
101 default:
102 continue;
103 }
105 success = true;
106 }
107
108 if (success && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, end);
109}
110
121{
122 if (!_settings_game.construction.freeform_edges) {
123 /* When end_tile is TileType::Void, the error tile will not be visible to the
124 * user. This happens when terraforming at the southern border. */
125 if (TileX(end_tile) == Map::MaxX()) end_tile += TileDiffXY(-1, 0);
126 if (TileY(end_tile) == Map::MaxY()) end_tile += TileDiffXY(0, -1);
127 }
128
129 switch (proc) {
131 Command<Commands::ClearArea>::Post(STR_ERROR_CAN_T_CLEAR_THIS_AREA, CcPlaySound_EXPLOSION, end_tile, start_tile, _ctrl_pressed);
132 break;
134 Command<Commands::LevelLand>::Post(STR_ERROR_CAN_T_RAISE_LAND_HERE, CcTerraform, end_tile, start_tile, _ctrl_pressed, LM_RAISE);
135 break;
137 Command<Commands::LevelLand>::Post(STR_ERROR_CAN_T_LOWER_LAND_HERE, CcTerraform, end_tile, start_tile, _ctrl_pressed, LM_LOWER);
138 break;
139 case DDSP_LEVEL_AREA:
140 Command<Commands::LevelLand>::Post(STR_ERROR_CAN_T_LEVEL_LAND_HERE, CcTerraform, end_tile, start_tile, _ctrl_pressed, LM_LEVEL);
141 break;
143 GenerateRockyArea(end_tile, start_tile);
144 break;
146 GenerateDesertArea(end_tile, start_tile);
147 break;
148 default:
149 return false;
150 }
151
152 return true;
153}
154
163
165struct TerraformToolbarWindow : Window {
167
168 TerraformToolbarWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
169 {
170 /* This is needed as we like to have the tree available on OnInit. */
171 this->CreateNestedTree();
172 this->FinishInitNested(window_number);
173 }
174
175 void OnInit() override
176 {
177 /* Don't show the place object button when there are no objects to place. */
180 }
181
182 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
183 {
184 if (widget < WID_TT_BUTTONS_START) return;
185
186 switch (widget) {
187 case WID_TT_LOWER_LAND: // Lower land button
189 this->last_user_action = widget;
190 break;
191
192 case WID_TT_RAISE_LAND: // Raise land button
194 this->last_user_action = widget;
195 break;
196
197 case WID_TT_LEVEL_LAND: // Level land button
198 HandlePlacePushButton(this, WID_TT_LEVEL_LAND, SPR_CURSOR_LEVEL_LAND, HT_POINT | HT_DIAGONAL);
199 this->last_user_action = widget;
200 break;
201
202 case WID_TT_DEMOLISH: // Demolish aka dynamite button
204 this->last_user_action = widget;
205 break;
206
207 case WID_TT_BUY_LAND: // Buy land button
208 HandlePlacePushButton(this, WID_TT_BUY_LAND, SPR_CURSOR_BUY_LAND, HT_RECT | HT_DIAGONAL);
209 this->last_user_action = widget;
210 break;
211
212 case WID_TT_PLANT_TREES: // Plant trees button
213 ShowBuildTreesToolbar();
214 break;
215
216 case WID_TT_PLACE_SIGN: // Place sign button
217 HandlePlacePushButton(this, WID_TT_PLACE_SIGN, SPR_CURSOR_SIGN, HT_RECT);
218 this->last_user_action = widget;
219 break;
220
221 case WID_TT_PLACE_OBJECT: // Place object button
223 break;
224
225 default: NOT_REACHED();
226 }
227 }
228
229 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
230 {
231 switch (this->last_user_action) {
232 case WID_TT_LOWER_LAND: // Lower land button
234 break;
235
236 case WID_TT_RAISE_LAND: // Raise land button
238 break;
239
240 case WID_TT_LEVEL_LAND: // Level land button
242 break;
243
244 case WID_TT_DEMOLISH: // Demolish aka dynamite button
246 break;
247
248 case WID_TT_BUY_LAND: // Buy land button
250 break;
251
252 case WID_TT_PLACE_SIGN: // Place sign button
253 PlaceProc_Sign(tile);
254 break;
255
256 default: NOT_REACHED();
257 }
258 }
259
260 void OnPlaceDrag(ViewportPlaceMethod select_method, [[maybe_unused]] ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt) override
261 {
262 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
263 }
264
265 Point OnInitialPosition([[maybe_unused]] int16_t sm_width, [[maybe_unused]] int16_t sm_height, [[maybe_unused]] int window_number) override
266 {
268 if (FindWindowByClass(WC_BUILD_TOOLBAR) != nullptr && !_settings_client.gui.link_terraform_toolbar) pt.y += sm_height;
269
270 return pt;
271 }
272
273 void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override
274 {
275 if (pt.x != -1) {
276 switch (select_proc) {
277 default: NOT_REACHED();
281 case DDSP_LEVEL_AREA:
282 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
283 break;
285 if (!_settings_game.construction.freeform_edges) {
286 /* When end_tile is TileType::Void, the error tile will not be visible to the
287 * user. This happens when terraforming at the southern border. */
288 if (TileX(end_tile) == Map::MaxX()) end_tile += TileDiffXY(-1, 0);
289 if (TileY(end_tile) == Map::MaxY()) end_tile += TileDiffXY(0, -1);
290 }
291 Command<Commands::BuildObjectArea>::Post(STR_ERROR_CAN_T_PURCHASE_THIS_LAND, CcPlaySound_CONSTRUCTION_RAIL,
292 end_tile, start_tile, OBJECT_OWNED_LAND, 0, _ctrl_pressed);
293 break;
294 }
295 }
296 }
297
298 void OnPlaceObjectAbort() override
299 {
300 this->RaiseButtons();
301 }
302
309 {
310 if (_game_mode != GM_NORMAL) return ES_NOT_HANDLED;
311 Window *w = ShowTerraformToolbar(nullptr);
312 if (w == nullptr) return ES_NOT_HANDLED;
313 return w->OnHotkey(hotkey);
314 }
315
316 static inline HotkeyList hotkeys{"terraform", {
320 Hotkey('D' | WKC_GLOBAL_HOTKEY, "dynamite", WID_TT_DEMOLISH),
321 Hotkey('U', "buyland", WID_TT_BUY_LAND),
322 Hotkey('I', "trees", WID_TT_PLANT_TREES),
323 Hotkey('O', "placesign", WID_TT_PLACE_SIGN),
324 Hotkey('P', "placeobject", WID_TT_PLACE_OBJECT),
326};
327
328static constexpr std::initializer_list<NWidgetPart> _nested_terraform_widgets = {
330 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
331 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_LANDSCAPING_TOOLBAR, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
332 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
333 EndContainer(),
336 SetFill(0, 1), SetSpriteTip(SPR_IMG_TERRAFORM_DOWN, STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND),
338 SetFill(0, 1), SetSpriteTip(SPR_IMG_TERRAFORM_UP, STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND),
340 SetFill(0, 1), SetSpriteTip(SPR_IMG_LEVEL_LAND, STR_LANDSCAPING_LEVEL_LAND_TOOLTIP),
341
343
345 SetFill(0, 1), SetSpriteTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
347 SetFill(0, 1), SetSpriteTip(SPR_IMG_BUY_LAND, STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND),
349 SetFill(0, 1), SetSpriteTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES_TOOLTIP),
351 SetFill(0, 1), SetSpriteTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN_TOOLTIP),
354 SetFill(0, 1), SetSpriteTip(SPR_IMG_TRANSMITTER, STR_SCENEDIT_TOOLBAR_PLACE_OBJECT_TOOLTIP),
355 EndContainer(),
356 EndContainer(),
357};
358
359static WindowDesc _terraform_desc(
360 WDP_MANUAL, "toolbar_landscape", 0, 0,
363 _nested_terraform_widgets,
364 &TerraformToolbarWindow::hotkeys
365);
366
373{
374 if (!Company::IsValidID(_local_company)) return nullptr;
375
376 /* Delete the terraform toolbar to place it again. */
378
379 if (link == nullptr) return AllocateWindowDescFront<TerraformToolbarWindow>(_terraform_desc, 0);
380
382 /* Put the linked toolbar to the left / right of the main toolbar. */
383 link->left = w->left + (_current_text_dir == TD_RTL ? w->width : -link->width);
384 link->top = w->top;
385 link->SetDirty();
386
387 return w;
388}
389
390static uint8_t _terraform_size = 1;
391
401static void CommonRaiseLowerBigLand(TileIndex tile, bool mode)
402{
403 if (_terraform_size == 1) {
404 StringID msg =
405 mode ? STR_ERROR_CAN_T_RAISE_LAND_HERE : STR_ERROR_CAN_T_LOWER_LAND_HERE;
406
407 Command<Commands::TerraformLand>::Post(msg, CcTerraform, tile, SLOPE_N, mode);
408 } else {
409 assert(_terraform_size != 0);
410 TileArea ta(tile, _terraform_size, _terraform_size);
411 ta.ClampToMap();
412
413 if (ta.w == 0 || ta.h == 0) return;
414
415 if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, tile);
416
417 uint h;
418 if (mode != 0) {
419 /* Raise land */
420 h = MAX_TILE_HEIGHT;
421 for (TileIndex tile2 : ta) {
422 h = std::min(h, TileHeight(tile2));
423 }
424 } else {
425 /* Lower land */
426 h = 0;
427 for (TileIndex tile2 : ta) {
428 h = std::max(h, TileHeight(tile2));
429 }
430 }
431
432 for (TileIndex tile2 : ta) {
433 if (TileHeight(tile2) == h) {
434 Command<Commands::TerraformLand>::Post(tile2, SLOPE_N, mode);
435 }
436 }
437 }
438}
439
440static const int8_t _multi_terraform_coords[][2] = {
441 { 0, -2},
442 { 4, 0}, { -4, 0}, { 0, 2},
443 { -8, 2}, { -4, 4}, { 0, 6}, { 4, 4}, { 8, 2},
444 {-12, 0}, { -8, -2}, { -4, -4}, { 0, -6}, { 4, -4}, { 8, -2}, { 12, 0},
445 {-16, 2}, {-12, 4}, { -8, 6}, { -4, 8}, { 0, 10}, { 4, 8}, { 8, 6}, { 12, 4}, { 16, 2},
446 {-20, 0}, {-16, -2}, {-12, -4}, { -8, -6}, { -4, -8}, { 0,-10}, { 4, -8}, { 8, -6}, { 12, -4}, { 16, -2}, { 20, 0},
447 {-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},
448 {-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},
449};
450
451static constexpr std::initializer_list<NWidgetPart> _nested_scen_edit_land_gen_widgets = {
453 NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN),
454 NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetStringTip(STR_TERRAFORM_TOOLBAR_LAND_GENERATION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
455 NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN),
456 NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN),
457 EndContainer(),
458 NWidget(WWT_PANEL, COLOUR_DARK_GREEN),
459 NWidget(NWID_HORIZONTAL), SetPadding(2, 2, 7, 2),
462 SetFill(0, 1), SetSpriteTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC),
464 SetFill(0, 1), SetSpriteTip(SPR_IMG_TERRAFORM_DOWN, STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND),
466 SetFill(0, 1), SetSpriteTip(SPR_IMG_TERRAFORM_UP, STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND),
468 SetFill(0, 1), SetSpriteTip(SPR_IMG_LEVEL_LAND, STR_LANDSCAPING_LEVEL_LAND_TOOLTIP),
470 SetFill(0, 1), SetSpriteTip(SPR_IMG_ROCKS, STR_TERRAFORM_TOOLTIP_PLACE_ROCKY_AREAS_ON_LANDSCAPE),
473 SetFill(0, 1), SetSpriteTip(SPR_IMG_DESERT, STR_TERRAFORM_TOOLTIP_DEFINE_DESERT_AREA),
474 EndContainer(),
476 SetFill(0, 1), SetSpriteTip(SPR_IMG_TRANSMITTER, STR_SCENEDIT_TOOLBAR_PLACE_OBJECT_TOOLTIP),
478 EndContainer(),
481 NWidget(WWT_EMPTY, INVALID_COLOUR, WID_ETT_DOTS), SetMinimalSize(59, 31), SetStringTip(STR_EMPTY),
485 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_ETT_INCREASE_SIZE), SetMinimalSize(12, 12), SetSpriteTip(SPR_ARROW_UP, STR_TERRAFORM_TOOLTIP_INCREASE_SIZE_OF_LAND_AREA),
487 NWidget(WWT_IMGBTN, COLOUR_GREY, WID_ETT_DECREASE_SIZE), SetMinimalSize(12, 12), SetSpriteTip(SPR_ARROW_DOWN, STR_TERRAFORM_TOOLTIP_DECREASE_SIZE_OF_LAND_AREA),
489 EndContainer(),
491 EndContainer(),
494 SetFill(1, 0), SetStringTip(STR_TERRAFORM_SE_NEW_WORLD, STR_TERRAFORM_TOOLTIP_GENERATE_RANDOM_LAND), SetPadding(0, 2, 0, 2),
496 SetFill(1, 0), SetStringTip(STR_TERRAFORM_RESET_LANDSCAPE, STR_TERRAFORM_RESET_LANDSCAPE_TOOLTIP), SetPadding(1, 2, 2, 2),
497 EndContainer(),
498};
499
504static void ResetLandscapeConfirmationCallback(Window *, bool confirmed)
505{
506 if (confirmed) {
507 /* Set generating_world to true to get instant-green grass after removing
508 * company property. */
509 Backup<bool> old_generating_world(_generating_world, true);
510
511 /* Delete all companies */
512 for (Company *c : Company::Iterate()) {
514 delete c;
515 }
516
517 old_generating_world.Restore();
518
519 /* Delete all station signs */
520 for (BaseStation *st : BaseStation::Iterate()) {
521 /* There can be buoys, remove them */
522 if (IsBuoyTile(st->xy)) Command<Commands::LandscapeClear>::Do({DoCommandFlag::Execute, DoCommandFlag::Bankrupt}, st->xy);
523 if (!st->IsInUse()) delete st;
524 }
525
526 /* Now that all vehicles are gone, we can reset the engine pool. Maybe it reduces some NewGRF changing-mess */
528
530 }
531}
532
534struct ScenarioEditorLandscapeGenerationWindow : Window {
536
537 ScenarioEditorLandscapeGenerationWindow(WindowDesc &desc, WindowNumber window_number) : Window(desc)
538 {
539 this->CreateNestedTree();
541 show_desert->SetDisplayedPlane(_settings_game.game_creation.landscape == LandscapeType::Tropic ? 0 : SZSP_NONE);
542 this->FinishInitNested(window_number);
543 }
544
545 void OnPaint() override
546 {
547 this->DrawWidgets();
548
549 if (this->IsWidgetLowered(WID_ETT_LOWER_LAND) || this->IsWidgetLowered(WID_ETT_RAISE_LAND)) { // change area-size if raise/lower corner is selected
550 SetTileSelectSize(_terraform_size, _terraform_size);
551 }
552 }
553
554 void UpdateWidgetSize(WidgetID widget, Dimension &size, [[maybe_unused]] const Dimension &padding, [[maybe_unused]] Dimension &fill, [[maybe_unused]] Dimension &resize) override
555 {
556 if (widget != WID_ETT_DOTS) return;
557
558 size.width = std::max<uint>(size.width, ScaleGUITrad(59));
559 size.height = std::max<uint>(size.height, ScaleGUITrad(31));
560 }
561
562 void DrawWidget(const Rect &r, WidgetID widget) const override
563 {
564 if (widget != WID_ETT_DOTS) return;
565
566 int center_x = RoundDivSU(r.left + r.right, 2);
567 int center_y = RoundDivSU(r.top + r.bottom, 2);
568
569 int n = _terraform_size * _terraform_size;
570 const int8_t *coords = &_multi_terraform_coords[0][0];
571
572 assert(n != 0);
573 do {
574 DrawSprite(SPR_WHITE_POINT, PAL_NONE, center_x + ScaleGUITrad(coords[0]), center_y + ScaleGUITrad(coords[1]));
575 coords += 2;
576 } while (--n);
577 }
578
579 void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
580 {
581 if (widget < WID_ETT_BUTTONS_START) return;
582
583 switch (widget) {
584 case WID_ETT_DEMOLISH: // Demolish aka dynamite button
586 this->last_user_action = widget;
587 break;
588
589 case WID_ETT_LOWER_LAND: // Lower land button
591 this->last_user_action = widget;
592 break;
593
594 case WID_ETT_RAISE_LAND: // Raise land button
596 this->last_user_action = widget;
597 break;
598
599 case WID_ETT_LEVEL_LAND: // Level land button
600 HandlePlacePushButton(this, WID_ETT_LEVEL_LAND, SPR_CURSOR_LEVEL_LAND, HT_POINT | HT_DIAGONAL);
601 this->last_user_action = widget;
602 break;
603
604 case WID_ETT_PLACE_ROCKS: // Place rocks button
605 HandlePlacePushButton(this, WID_ETT_PLACE_ROCKS, SPR_CURSOR_ROCKY_AREA, HT_RECT);
606 this->last_user_action = widget;
607 break;
608
609 case WID_ETT_PLACE_DESERT: // Place desert button (in tropical climate)
610 HandlePlacePushButton(this, WID_ETT_PLACE_DESERT, SPR_CURSOR_DESERT, HT_RECT);
611 this->last_user_action = widget;
612 break;
613
614 case WID_ETT_PLACE_OBJECT: // Place transmitter button
616 break;
617
619 case WID_ETT_DECREASE_SIZE: { // Increase/Decrease terraform size
620 int size = (widget == WID_ETT_INCREASE_SIZE) ? 1 : -1;
621 this->HandleButtonClick(widget);
622 size += _terraform_size;
623
624 if (!IsInsideMM(size, 1, 8 + 1)) return;
625 _terraform_size = size;
626
627 this->SetDirty();
628 break;
629 }
630
631 case WID_ETT_NEW_SCENARIO: // gen random land
632 this->HandleButtonClick(widget);
634 break;
635
636 case WID_ETT_RESET_LANDSCAPE: // Reset landscape
637 ShowQuery(
638 GetEncodedString(STR_QUERY_RESET_LANDSCAPE_CAPTION),
639 GetEncodedString(STR_RESET_LANDSCAPE_CONFIRMATION_TEXT),
641 break;
642
643 default: NOT_REACHED();
644 }
645 }
646
647 void OnTimeout() override
648 {
649 for (const auto &pair : this->widget_lookup) {
650 if (pair.first < WID_ETT_START || (pair.first >= WID_ETT_BUTTONS_START && pair.first < WID_ETT_BUTTONS_END)) continue; // skip the buttons
651 this->RaiseWidgetWhenLowered(pair.first);
652 }
653 }
654
655 void OnPlaceObject([[maybe_unused]] Point pt, TileIndex tile) override
656 {
657 switch (this->last_user_action) {
658 case WID_ETT_DEMOLISH: // Demolish aka dynamite button
660 break;
661
662 case WID_ETT_LOWER_LAND: // Lower land button
663 CommonRaiseLowerBigLand(tile, false);
664 break;
665
666 case WID_ETT_RAISE_LAND: // Raise land button
667 CommonRaiseLowerBigLand(tile, true);
668 break;
669
670 case WID_ETT_LEVEL_LAND: // Level land button
672 break;
673
674 case WID_ETT_PLACE_ROCKS: // Place rocks button
676 break;
677
678 case WID_ETT_PLACE_DESERT: // Place desert button (in tropical climate)
680 break;
681
682 default: NOT_REACHED();
683 }
684 }
685
686 void OnPlaceDrag(ViewportPlaceMethod select_method, [[maybe_unused]] ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt) override
687 {
688 VpSelectTilesWithMethod(pt.x, pt.y, select_method);
689 }
690
691 void OnPlaceMouseUp([[maybe_unused]] ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, [[maybe_unused]] Point pt, TileIndex start_tile, TileIndex end_tile) override
692 {
693 if (pt.x != -1) {
694 switch (select_proc) {
695 default: NOT_REACHED();
700 case DDSP_LEVEL_AREA:
702 GUIPlaceProcDragXY(select_proc, start_tile, end_tile);
703 break;
704 }
705 }
706 }
707
708 void OnPlaceObjectAbort() override
709 {
710 this->RaiseButtons();
711 this->SetDirty();
712 }
713
720 {
721 if (_game_mode != GM_EDITOR) return ES_NOT_HANDLED;
723 if (w == nullptr) return ES_NOT_HANDLED;
724 return w->OnHotkey(hotkey);
725 }
726
727 static inline HotkeyList hotkeys{"terraform_editor", {
728 Hotkey('D' | WKC_GLOBAL_HOTKEY, "dynamite", WID_ETT_DEMOLISH),
732 Hotkey('R', "rocky", WID_ETT_PLACE_ROCKS),
733 Hotkey('T', "desert", WID_ETT_PLACE_DESERT),
734 Hotkey('O', "object", WID_ETT_PLACE_OBJECT),
736};
737
738static WindowDesc _scen_edit_land_gen_desc(
739 WDP_AUTO, "toolbar_landscape_scen", 0, 0,
742 _nested_scen_edit_land_gen_widgets,
743 &ScenarioEditorLandscapeGenerationWindow::hotkeys
744);
745
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:1425
Map accessors for 'clear' tiles.
@ Rocks
Rocks with snow transition (0-3).
Definition clear_map.h:24
void MakeClear(Tile t, ClearGround g, uint density)
Make a clear tile.
Definition clear_map.h:253
Functions related to commands.
@ Execute
execute the given command
@ Bankrupt
company bankrupts, skip money check, skip vehicle on tile check in some cases
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:322
static constexpr Owner INVALID_OWNER
An invalid owner.
Base class for engines.
bool _generating_world
Whether we are generating the map or not.
Definition genworld.cpp:74
Functions related to world/map generation.
void ShowCreateScenario()
Show the window to create a scenario.
bool _ctrl_pressed
Is Ctrl pressed?
Definition gfx.cpp:39
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:1038
@ WKC_GLOBAL_HOTKEY
Fake keycode bit to indicate global hotkeys.
Definition gfx_type.h:35
constexpr NWidgetPart SetFill(uint16_t fill_x, uint16_t fill_y)
Widget part function for setting filling.
constexpr NWidgetPart SetSpriteTip(SpriteID sprite, StringID tip={})
Widget part function for setting the sprite and tooltip.
constexpr NWidgetPart SetToolbarMinimalSize(int width)
Widget part function to setting the minimal size for a toolbar button.
constexpr NWidgetPart SetPadding(uint8_t top, uint8_t right, uint8_t bottom, uint8_t left)
Widget part function for setting additional space around a widget.
constexpr NWidgetPart SetStringTip(StringID string, StringID tip={})
Widget part function for setting the string and tooltip.
constexpr NWidgetPart SetToolbarSpacerMinimalSize()
Widget part function to setting the minimal size for a toolbar spacer.
constexpr NWidgetPart SetMinimalSize(int16_t x, int16_t y)
Widget part function for setting the minimal size.
constexpr NWidgetPart EndContainer()
Widget part function for denoting the end of a container (horizontal, vertical, WWT_FRAME,...
constexpr NWidgetPart NWidget(WidgetType tp, Colours col, WidgetID idx=INVALID_WIDGET)
Widget part function for starting a new 'real' widget.
void SetDirty() const
Mark entire window as dirty (in need of re-paint).
Definition window.cpp:980
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1554
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.
@ Tropic
Landscape with distinct rainforests and deserts,.
#define Point
Macro that prevents name conflicts between included headers.
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:392
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:429
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:419
@ 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 bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
constexpr int RoundDivSU(int a, uint b)
Computes round(a / b) for signed a and unsigned b.
void ShowQuery(EncodedString &&caption, EncodedString &&message, Window *parent, QueryCallbackProc *callback, bool focus)
Show a confirmation window with standard 'yes' and 'no' buttons The window is aligned to the centre o...
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:21
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:61
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
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:52
Functions related to sound.
@ SND_1F_CONSTRUCTION_OTHER
29 == 0x1D Construction: other (non-water, non-rail, non-bridge)
Definition sound_type.h:77
static const CursorID ANIMCURSOR_DEMOLISH
704 - 707 - demolish dynamite
Definition sprites.h:1522
static const CursorID ANIMCURSOR_LOWERLAND
699 - 701 - lower land tool
Definition sprites.h:1523
static const CursorID ANIMCURSOR_RAISELAND
696 - 698 - raise land tool
Definition sprites.h:1524
bool IsBuoyTile(Tile t)
Is tile t a buoy tile?
Definition of base types and functions in a cross-platform compatible way.
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
TextDirection _current_text_dir
Text direction of the currently selected language.
Definition strings.cpp:56
Functions related to OTTD's strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
@ TD_RTL
Text is written right-to-left by default.
Class to backup a specific variable and restore it later.
void Restore()
Restore the variable.
Base class for all station-ish types.
T y
Y coordinate.
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:588
List of hotkeys for a window.
Definition hotkeys.h:46
All data for a single hotkey.
Definition hotkeys.h:22
static uint MaxY()
Gets the maximum Y coordinate within the map, including TileType::Void.
Definition map_func.h:298
static uint MaxX()
Gets the maximum X coordinate within the map, including TileType::Void.
Definition map_func.h:289
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.
static Pool::IterateWrapper< Company > Iterate(size_t from=0)
Specification of a rectangle with absolute coordinates of all edges.
void OnClick(Point pt, WidgetID widget, int click_count) override
A click with the left mouse button has been made on the window.
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.
WidgetID last_user_action
Last started user action.
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.
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.
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.
WidgetID 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.
High level window description.
Definition window_gui.h:168
Number to differentiate different windows of the same class.
Data structure for an opened window.
Definition window_gui.h:274
void FinishInitNested(WindowNumber window_number=0)
Perform the second part of the initialization of a nested widget tree.
Definition window.cpp:1822
void DrawWidgets() const
Paint all widgets of a window.
Definition widget.cpp:768
void RaiseWidgetWhenLowered(WidgetID widget_index)
Marks a widget as raised and dirty (redraw), when it is marked as lowered.
Definition window_gui.h:479
ResizeInfo resize
Resize information.
Definition window_gui.h:315
void CreateNestedTree()
Perform the first part of the initialization of a nested widget tree.
Definition window.cpp:1812
bool IsWidgetLowered(WidgetID widget_index) const
Gets the lowered state of a widget.
Definition window_gui.h:492
void RaiseButtons(bool autoraise=false)
Raise the buttons of the window.
Definition window.cpp:544
int left
x position of left edge of the window
Definition window_gui.h:310
int top
y position of top edge of the window
Definition window_gui.h:311
WidgetLookup widget_lookup
Indexed access to the nested widget tree. Do not access directly, use Window::GetWidget() instead.
Definition window_gui.h:323
Window(WindowDesc &desc)
Empty constructor, initialization has been moved to InitNested() called from the constructor of the d...
Definition window.cpp:1845
const NWID * GetWidget(WidgetID widnum) const
Get the nested widget with number widnum from the nested widget tree.
Definition window_gui.h:990
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:609
virtual EventState OnHotkey(int hotkey)
A hotkey has been pressed.
Definition window.cpp:584
int width
width of the window (number of pixels to the right in x direction)
Definition window_gui.h:312
WindowNumber window_number
Window number within the window class.
Definition window_gui.h:303
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 uint TileHeight(Tile tile)
Returns the height of a tile.
Definition tile_map.h:29
void SetTropicZone(Tile tile, TropicZone type)
Set the tropic zone.
Definition tile_map.h:225
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
static constexpr uint MAX_TILE_HEIGHT
Maximum allowed tile height.
Definition tile_type.h:24
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > > TileIndex
The index/ID of a Tile.
Definition tile_type.h:92
@ TROPICZONE_DESERT
Tile is desert.
Definition tile_type.h:83
@ TROPICZONE_NORMAL
Normal tropiczone.
Definition tile_type.h:82
@ Trees
Tile with one or more trees.
Definition tile_type.h:53
@ Clear
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:49
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
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
@ 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.
ViewportPlaceMethod
Viewport place method (type of highlighted area and placed objects).
@ VPM_X_AND_Y
area of land in X and Y directions
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.
static RectPadding ScaleGUITrad(const RectPadding &r)
Scale a RectPadding to GUI zoom level.
Definition widget.cpp:49
@ WWT_IMGBTN
(Toggle) Button with image
Definition widget_type.h:41
@ WWT_PUSHIMGBTN
Normal push-button (no toggle button) with image caption.
@ NWID_SPACER
Invisible widget that takes some space.
Definition widget_type.h:70
@ NWID_HORIZONTAL
Horizontal container.
Definition widget_type.h:66
@ WWT_TEXTBTN
(Toggle) Button with text
Definition widget_type.h:44
@ WWT_PANEL
Simple depressed panel.
Definition widget_type.h:39
@ WWT_STICKYBOX
Sticky box (at top-right of a window, after WWT_DEFSIZEBOX).
Definition widget_type.h:57
@ WWT_SHADEBOX
Shade box (at top-right of a window, between WWT_DEBUGBOX and WWT_DEFSIZEBOX).
Definition widget_type.h:55
@ WWT_CAPTION
Window caption (window title between closebox and stickybox).
Definition widget_type.h:52
@ NWID_VERTICAL
Vertical container.
Definition widget_type.h:68
@ WWT_CLOSEBOX
Close box (at top-left of a window).
Definition widget_type.h:60
@ WWT_EMPTY
Empty widget, place holder to reserve space in widget tree.
Definition widget_type.h:37
@ NWID_SELECTION
Stacked widgets, only one visible at a time (eg in a panel with tabs).
Definition widget_type.h:71
@ SZSP_NONE
Display plane with zero size in both directions (none filling and resizing).
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:1209
Window * FindWindowByClass(WindowClass cls)
Find any window by its class.
Definition window.cpp:1181
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:1699
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:3339
Window functions not directly related to making/drawing windows.
Functions, definitions and such used only by the GUI.
@ Construction
This window is used for construction; close it whenever changing company.
Definition window_gui.h:153
Twindow * AllocateWindowDescFront(WindowDesc &desc, WindowNumber window_number, Targs... extra_arguments)
Open a new window.
@ WDP_AUTO
Find a place automatically.
Definition window_gui.h:144
@ WDP_MANUAL
Manually align the window (so no automatic location finding).
Definition window_gui.h:143
int WidgetID
Widget ID.
Definition window_type.h:20
EventState
State of handling an event.
@ ES_NOT_HANDLED
The passed event is not handled.
static constexpr WidgetID INVALID_WIDGET
An invalid widget index.
Definition window_type.h:23
@ WC_BUILD_TOOLBAR
Build toolbar; Window numbers:
Definition window_type.h:78
@ WC_NONE
No window, redirects to WC_MAIN_WINDOW.
Definition window_type.h:50
@ WC_SCEN_LAND_GEN
Landscape generation (in Scenario Editor); Window numbers:
@ WC_TOWN_VIEW
Town view; Window numbers:
Functions related to zooming.