diff --git a/src/lang/english.txt b/src/lang/english.txt index 8c0e8ead06..dfaddd368d 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1470,6 +1470,12 @@ STR_CONFIG_SETTING_STATION_RATING_TOOLTIP_MODE_OFF :Off STR_CONFIG_SETTING_STATION_RATING_TOOLTIP_MODE_SIMPLE :Simple STR_CONFIG_SETTING_STATION_RATING_TOOLTIP_MODE_DETAILED :Detailed +STR_CONFIG_SETTING_DEMOLISH_CONFIRM_MODE :Ask before demolishing structures: {STRING2} +STR_CONFIG_SETTING_DEMOLISH_CONFIRM_MODE_HELPTEXT :Ask for confirmation before irreversibly demolishing structures. +STR_CONFIG_SETTING_DEMOLISH_CONFIRM_MODE_OFF :Off +STR_CONFIG_SETTING_DEMOLISH_CONFIRM_MODE_INDUSTRY :Industries +STR_CONFIG_SETTING_DEMOLISH_CONFIRM_MODE_ALL :Industries and rail stations + STR_CONFIG_SETTING_ADV_SIG_BRIDGE_TUN_MODES :Enable signals on bridges/tunnels advanced modes: {STRING2} STR_CONFIG_SETTING_ADV_SIG_BRIDGE_TUN_MODES_HELPTEXT :Enables use of advanced modes of signal simulation on bridges and tunnels. When disabled, bridges/tunnels which are not already in an advanced mode cannot be changed to an advanced mode, however other players may choose to enable this setting and use an advanced mode. @@ -5571,6 +5577,10 @@ STR_ERROR_NAME_MUST_BE_UNIQUE :{WHITE}Name mus STR_ERROR_GENERIC_OBJECT_IN_THE_WAY :{WHITE}{1:STRING} in the way STR_ERROR_NOT_ALLOWED_WHILE_PAUSED :{WHITE}Not allowed while paused +# Clear area query +STR_QUERY_CLEAR_AREA_CAPTION :{WHITE}Clear area +STR_CLEAR_AREA_CONFIRMATION_TEXT :{YELLOW}You are about to destroy an important structure. Are you sure? + # Local authority errors STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS :{WHITE}{TOWN} local authority refuses to allow this STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT :{WHITE}{TOWN} local authority refuses to allow another airport to be built in this town diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 49d67da2cc..dfdea2f547 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -1757,6 +1757,7 @@ static SettingsContainer &GetSettingsTree() construction->Add(new SettingEntry("gui.quick_goto")); construction->Add(new SettingEntry("gui.default_rail_type")); construction->Add(new SettingEntry("gui.default_road_type")); + construction->Add(new SettingEntry("gui.demolish_confirm_mode")); } SettingsPage *departureboards = interface->Add(new SettingsPage(STR_CONFIG_SETTING_INTERFACE_DEPARTUREBOARDS)); diff --git a/src/settings_type.h b/src/settings_type.h index 68b9001265..c94585476d 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -221,6 +221,7 @@ struct GUISettings : public TimeSettings { uint8 vehicle_names; ///< Vehicle naming scheme bool shade_trees_on_slopes; ///< Shade trees on slopes uint8 station_rating_tooltip_mode; ///< Station rating tooltip mode + uint8 demolish_confirm_mode; ///< Demolition confirmation mode uint16 console_backlog_timeout; ///< the minimum amount of time items should be in the console backlog before they will be removed in ~3 seconds granularity. uint16 console_backlog_length; ///< the minimum amount of items in the console backlog before items will be removed. diff --git a/src/table/settings.ini b/src/table/settings.ini index 75259fed95..ae61f4d6a1 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -5479,6 +5479,18 @@ max = 2 str = STR_CONFIG_SETTING_STATION_RATING_TOOLTIP_MODE strhelp = STR_CONFIG_SETTING_STATION_RATING_TOOLTIP_MODE_HELPTEXT strval = STR_CONFIG_SETTING_STATION_RATING_TOOLTIP_MODE_OFF + +[SDTC_VAR] +var = gui.demolish_confirm_mode +type = SLE_UINT8 +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +guiflags = SGF_MULTISTRING +def = 2 +min = 0 +max = 2 +str = STR_CONFIG_SETTING_DEMOLISH_CONFIRM_MODE +strhelp = STR_CONFIG_SETTING_DEMOLISH_CONFIRM_MODE_HELPTEXT +strval = STR_CONFIG_SETTING_DEMOLISH_CONFIRM_MODE_OFF cat = SC_BASIC ; For the dedicated build we'll enable dates in logs by default. diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 2db07278b4..253b55c1d4 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -30,6 +30,7 @@ #include "hotkeys.h" #include "engine_base.h" #include "terraform_gui.h" +#include "cheat_func.h" #include "town_gui.h" #include "zoom_func.h" @@ -39,6 +40,12 @@ #include "safeguards.h" +enum DemolishConfirmMode { + DCM_OFF, + DCM_INDUSTRY, + DCM_INDUSTRY_RAIL_STATION, +}; + void CcTerraform(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint64 p3, uint32 cmd) { if (result.Succeeded()) { @@ -95,6 +102,40 @@ static void GenerateRockyArea(TileIndex end, TileIndex start) if (success && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_CONSTRUCTION_OTHER, end); } +/** Checks if the area contains any structures that are important enough to query about first */ +static bool IsQueryConfirmIndustryOrRailStationInArea(TileIndex start_tile, TileIndex end_tile, bool diagonal) +{ + if (_settings_client.gui.demolish_confirm_mode == DCM_OFF) return false; + + std::unique_ptr tile_iterator; + + if (diagonal) { + tile_iterator = std::make_unique(end_tile, start_tile); + } else { + tile_iterator = std::make_unique(end_tile, start_tile); + } + + bool destroying_industry_or_station = false; + + for (; *tile_iterator != INVALID_TILE; ++(*tile_iterator)) { + if ((_cheats.magic_bulldozer.value && IsTileType(*tile_iterator, MP_INDUSTRY)) || + (_settings_client.gui.demolish_confirm_mode == DCM_INDUSTRY_RAIL_STATION && IsRailStationTile(*tile_iterator))) { + destroying_industry_or_station = true; + break; + } + } + + return destroying_industry_or_station; +} + +static CommandContainer _demolish_area_command; + +static void DemolishAreaConfirmationCallback(Window*, bool confirmed) { + if (confirmed) { + DoCommandP(&_demolish_area_command); + } +} + /** * A central place to handle all X_AND_Y dragged GUI functions. * @param proc Procedure related to the dragging @@ -114,9 +155,16 @@ bool GUIPlaceProcDragXY(ViewportDragDropSelectionProcess proc, TileIndex start_t } switch (proc) { - case DDSP_DEMOLISH_AREA: - DoCommandP(end_tile, start_tile, _ctrl_pressed ? 1 : 0, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION); + case DDSP_DEMOLISH_AREA: { + _demolish_area_command = NewCommandContainerBasic(end_tile, start_tile, _ctrl_pressed ? 1 : 0, CMD_CLEAR_AREA | CMD_MSG(STR_ERROR_CAN_T_CLEAR_THIS_AREA), CcPlaySound_EXPLOSION); + + if (IsQueryConfirmIndustryOrRailStationInArea(start_tile, end_tile, _ctrl_pressed)) { + ShowQuery(STR_QUERY_CLEAR_AREA_CAPTION, STR_CLEAR_AREA_CONFIRMATION_TEXT, nullptr, DemolishAreaConfirmationCallback); + } else { + DemolishAreaConfirmationCallback(nullptr, true); + } break; + } case DDSP_RAISE_AND_LEVEL_AREA: DoCommandP(end_tile, start_tile, LM_RAISE << 1 | (_ctrl_pressed ? 1 : 0), CMD_LEVEL_LAND | CMD_MSG(STR_ERROR_CAN_T_RAISE_LAND_HERE), CcTerraform); break;