From 4d23dccaca51c547db27a685cb92eb04214dce85 Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Fri, 3 Jan 2025 15:35:14 -0500 Subject: [PATCH 1/3] Feature: Setting to allow bulldozing unserved industries --- src/industry_cmd.cpp | 22 +++++++++++++++++++++- src/lang/english.txt | 3 +++ src/settings_gui.cpp | 1 + src/settings_type.h | 1 + src/table/settings/world_settings.ini | 7 +++++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 9d5d761639..7cf54ea46b 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -493,13 +493,33 @@ static CommandCost ClearTile_Industry(TileIndex tile, DoCommandFlag flags) Industry *i = Industry::GetByTile(tile); const IndustrySpec *indspec = GetIndustrySpec(i->type); + /* Check if the player can bulldoze the industry. */ + bool bulldoze_allowed = _settings_game.construction.bulldoze_industries; + if (bulldoze_allowed) { + /* Don't bulldoze industries that have recently had any cargo transported...*/ + for (const auto &p : i->produced) { + if (p.history[LAST_MONTH].PctTransported() > 0) { + bulldoze_allowed = false; + break; + } + } + + /* ...or received. */ + for (const auto &a : i->accepted) { + if (a.last_accepted + EconomyTime::DAYS_IN_ECONOMY_YEAR > TimerGameEconomy::date) { + bulldoze_allowed = false; + break; + } + } + } + /* water can destroy industries * in editor you can bulldoze industries * with magic_bulldozer cheat you can destroy industries * (area around OILRIG is water, so water shouldn't flood it */ if ((_current_company != OWNER_WATER && _game_mode != GM_EDITOR && - !_cheats.magic_bulldozer.value) || + !bulldoze_allowed) || ((flags & DC_AUTO) != 0) || (_current_company == OWNER_WATER && ((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) || diff --git a/src/lang/english.txt b/src/lang/english.txt index 4244c77792..b8e4f3e3d5 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1395,6 +1395,9 @@ STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT :Amount of flat STR_CONFIG_SETTING_MULTIPINDTOWN :Allow multiple similar industries per town: {STRING2} STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :Normally, a town does not want more than one industry of each type. With this setting, it will allow several industries of the same type in the same town +STR_CONFIG_SETTING_BULLDOZE_INDUSTRIES :Allow bulldozing unserved industries +STR_CONFIG_SETTING_BULLDOZE_INDUSTRIES_HELPTEXT :Allow industries to be demolished if 0% of their output is currently being transported + STR_CONFIG_SETTING_SIGNALSIDE :Show signals: {STRING2} STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :Select on which side of the track to place signals ###length 3 diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 708a78f623..9ff5aa7970 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2149,6 +2149,7 @@ static SettingsContainer &GetSettingsTree() limitations->Add(new SettingEntry("construction.command_pause_level")); limitations->Add(new SettingEntry("construction.autoslope")); limitations->Add(new SettingEntry("construction.extra_dynamite")); + limitations->Add(new SettingEntry("construction.bulldoze_industries")); limitations->Add(new SettingEntry("construction.map_height_limit")); limitations->Add(new SettingEntry("construction.max_bridge_length")); limitations->Add(new SettingEntry("construction.max_bridge_height")); diff --git a/src/settings_type.h b/src/settings_type.h index 157bdf6058..6a06c4f7dc 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -392,6 +392,7 @@ struct ConstructionSettings { bool crossing_with_competitor; ///< allow building of level crossings with competitor roads or rails uint8_t raw_industry_construction; ///< type of (raw) industry construction (none, "normal", prospecting) uint8_t industry_platform; ///< the amount of flat land around an industry + bool bulldoze_industries; ///< whether players can bulldozed unserved industries bool freeform_edges; ///< allow terraforming the tiles at the map edges uint8_t extra_tree_placement; ///< (dis)allow building extra trees in-game uint8_t command_pause_level; ///< level/amount of commands that can't be executed while paused diff --git a/src/table/settings/world_settings.ini b/src/table/settings/world_settings.ini index 6b5d1466e0..5331dfcd94 100644 --- a/src/table/settings/world_settings.ini +++ b/src/table/settings/world_settings.ini @@ -560,6 +560,13 @@ strhelp = STR_CONFIG_SETTING_INDUSTRY_PLATFORM_HELPTEXT strval = STR_CONFIG_SETTING_TILE_LENGTH cat = SC_EXPERT +[SDT_BOOL] +var = construction.bulldoze_industries +def = false +str = STR_CONFIG_SETTING_BULLDOZE_INDUSTRIES +strhelp = STR_CONFIG_SETTING_BULLDOZE_INDUSTRIES_HELPTEXT +cat = SC_BASIC + [SDT_BOOL] var = construction.freeform_edges from = SLV_111 From b564013ca116a88c5dcf3f192ac083289bfacb39 Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Fri, 3 Jan 2025 15:35:35 -0500 Subject: [PATCH 2/3] Feature: Setting to allow bulldozing immovable objects --- src/lang/english.txt | 3 +++ src/object_cmd.cpp | 6 +++--- src/settings_gui.cpp | 1 + src/settings_type.h | 1 + src/table/settings/world_settings.ini | 7 +++++++ 5 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index b8e4f3e3d5..b17a06089c 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1398,6 +1398,9 @@ STR_CONFIG_SETTING_MULTIPINDTOWN_HELPTEXT :Normally, a tow STR_CONFIG_SETTING_BULLDOZE_INDUSTRIES :Allow bulldozing unserved industries STR_CONFIG_SETTING_BULLDOZE_INDUSTRIES_HELPTEXT :Allow industries to be demolished if 0% of their output is currently being transported +STR_CONFIG_SETTING_BULLDOZE_OBJECTS :Allow bulldozing immovable objects +STR_CONFIG_SETTING_BULLDOZE_OBJECTS_HELPTEXT :Allow lighthouses, transmitters, and NewGRF objects to be demolished + STR_CONFIG_SETTING_SIGNALSIDE :Show signals: {STRING2} STR_CONFIG_SETTING_SIGNALSIDE_HELPTEXT :Select on which side of the track to place signals ###length 3 diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index d4f28477b9..59b8fed6c9 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -566,13 +566,13 @@ static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlag flags) /* No further limitations for the editor. */ } else if (GetTileOwner(tile) == OWNER_NONE) { /* Owned by nobody and unremovable, so we can only remove it with brute force! */ - if (!_cheats.magic_bulldozer.value && (spec->flags & OBJECT_FLAG_CANNOT_REMOVE) != 0) return CMD_ERROR; + if (!_settings_game.construction.bulldoze_objects && (spec->flags & OBJECT_FLAG_CANNOT_REMOVE) != 0) return CMD_ERROR; } else if (CheckTileOwnership(tile).Failed()) { /* We don't own it!. */ return CommandCost(STR_ERROR_OWNED_BY); } else if ((spec->flags & OBJECT_FLAG_CANNOT_REMOVE) != 0 && (spec->flags & OBJECT_FLAG_AUTOREMOVE) == 0) { - /* In the game editor or with cheats we can remove, otherwise we can't. */ - if (!_cheats.magic_bulldozer.value) { + /* We might be allowed to remove immovable objects. */ + if (!_settings_game.construction.bulldoze_objects) { if (type == OBJECT_HQ) return CommandCost(STR_ERROR_COMPANY_HEADQUARTERS_IN); return CMD_ERROR; } diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 9ff5aa7970..0576fab441 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -2150,6 +2150,7 @@ static SettingsContainer &GetSettingsTree() limitations->Add(new SettingEntry("construction.autoslope")); limitations->Add(new SettingEntry("construction.extra_dynamite")); limitations->Add(new SettingEntry("construction.bulldoze_industries")); + limitations->Add(new SettingEntry("construction.bulldoze_objects")); limitations->Add(new SettingEntry("construction.map_height_limit")); limitations->Add(new SettingEntry("construction.max_bridge_length")); limitations->Add(new SettingEntry("construction.max_bridge_height")); diff --git a/src/settings_type.h b/src/settings_type.h index 6a06c4f7dc..481e064fb3 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -393,6 +393,7 @@ struct ConstructionSettings { uint8_t raw_industry_construction; ///< type of (raw) industry construction (none, "normal", prospecting) uint8_t industry_platform; ///< the amount of flat land around an industry bool bulldoze_industries; ///< whether players can bulldozed unserved industries + bool bulldoze_objects; ///< whether objects can be bulldozed, even if immovable bool freeform_edges; ///< allow terraforming the tiles at the map edges uint8_t extra_tree_placement; ///< (dis)allow building extra trees in-game uint8_t command_pause_level; ///< level/amount of commands that can't be executed while paused diff --git a/src/table/settings/world_settings.ini b/src/table/settings/world_settings.ini index 5331dfcd94..15fc7e6122 100644 --- a/src/table/settings/world_settings.ini +++ b/src/table/settings/world_settings.ini @@ -567,6 +567,13 @@ str = STR_CONFIG_SETTING_BULLDOZE_INDUSTRIES strhelp = STR_CONFIG_SETTING_BULLDOZE_INDUSTRIES_HELPTEXT cat = SC_BASIC +[SDT_BOOL] +var = construction.bulldoze_objects +def = false +str = STR_CONFIG_SETTING_BULLDOZE_OBJECTS +strhelp = STR_CONFIG_SETTING_BULLDOZE_OBJECTS_HELPTEXT +cat = SC_BASIC + [SDT_BOOL] var = construction.freeform_edges from = SLV_111 From b574cd260c07fa3cc18d00d64caa8b568ea410f1 Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Fri, 3 Jan 2025 15:47:42 -0500 Subject: [PATCH 3/3] Remove: Magic Bulldozer cheat --- src/cheat_gui.cpp | 5 ++--- src/cheat_type.h | 2 +- src/road_cmd.cpp | 2 -- src/saveload/cheat_sl.cpp | 4 ++-- src/saveload/saveload.h | 1 + src/town_cmd.cpp | 17 +++++------------ src/tunnelbridge_cmd.cpp | 2 +- 7 files changed, 12 insertions(+), 21 deletions(-) diff --git a/src/cheat_gui.cpp b/src/cheat_gui.cpp index 4b3c9c5db6..032ae45b52 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.cpp @@ -168,7 +168,7 @@ static int32_t ClickChangeMaxHlCheat(int32_t new_value, int32_t) enum CheatNumbers { CHT_MONEY, ///< Change amount of money. CHT_CHANGE_COMPANY, ///< Switch company. - CHT_EXTRA_DYNAMITE, ///< Dynamite anything. + CHT_EXTRA_DYNAMITE, ///< UNUSED: Dynamite anything. CHT_CROSSINGTUNNELS, ///< Allow tunnels to cross each other. CHT_NO_JETCRASH, ///< Disable jet-airplane crashes. CHT_SETUP_PROD, ///< Allow manually editing of industry production. @@ -202,7 +202,6 @@ struct CheatEntry { static const CheatEntry _cheats_ui[] = { {SLE_INT32, STR_CHEAT_MONEY, &_money_cheat_amount, &_cheats.money.been_used, &ClickMoneyCheat }, {SLE_UINT8, STR_CHEAT_CHANGE_COMPANY, &_local_company, &_cheats.switch_company.been_used, &ClickChangeCompanyCheat }, - {SLE_BOOL, STR_CHEAT_EXTRA_DYNAMITE, &_cheats.magic_bulldozer.value, &_cheats.magic_bulldozer.been_used, nullptr }, {SLE_BOOL, STR_CHEAT_CROSSINGTUNNELS, &_cheats.crossing_tunnels.value, &_cheats.crossing_tunnels.been_used, nullptr }, {SLE_BOOL, STR_CHEAT_NO_JETCRASH, &_cheats.no_jetcrash.value, &_cheats.no_jetcrash.been_used, nullptr }, {SLE_BOOL, STR_CHEAT_SETUP_PROD, &_cheats.setup_prod.value, &_cheats.setup_prod.been_used, &ClickSetProdCheat }, @@ -211,7 +210,7 @@ static const CheatEntry _cheats_ui[] = { {SLE_INT32, STR_CHEAT_CHANGE_DATE, &TimerGameCalendar::year, &_cheats.change_date.been_used, &ClickChangeDateCheat }, }; -static_assert(CHT_NUM_CHEATS == lengthof(_cheats_ui)); +static_assert(CHT_NUM_CHEATS == lengthof(_cheats_ui) + 1); // Removed from the UI: Magic Bulldozer. /** Widget definitions of the cheat GUI. */ static constexpr NWidgetPart _nested_cheat_widgets[] = { diff --git a/src/cheat_type.h b/src/cheat_type.h index 8c5dc981b1..2679ee67c4 100644 --- a/src/cheat_type.h +++ b/src/cheat_type.h @@ -24,7 +24,7 @@ struct Cheat { * Only add new entries at the end of the struct! */ struct Cheats { - Cheat magic_bulldozer; ///< dynamite industries, objects + Cheat magic_bulldozer; ///< REMOVED: dynamite industries, objects Cheat switch_company; ///< change to another company Cheat money; ///< get rich or poor Cheat crossing_tunnels; ///< allow tunnels that cross each other diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 8bbfc28bdc..5c5f0240f3 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -279,8 +279,6 @@ CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, R if (!town_check) return CommandCost(); - if (_cheats.magic_bulldozer.value) return CommandCost(); - Town *t = ClosestTownFromTile(tile, UINT_MAX); if (t == nullptr) return CommandCost(); diff --git a/src/saveload/cheat_sl.cpp b/src/saveload/cheat_sl.cpp index ef1d43c9cd..765aaf0262 100644 --- a/src/saveload/cheat_sl.cpp +++ b/src/saveload/cheat_sl.cpp @@ -17,8 +17,8 @@ #include "../safeguards.h" static const SaveLoad _cheats_desc[] = { - SLE_VAR(Cheats, magic_bulldozer.been_used, SLE_BOOL), - SLE_VAR(Cheats, magic_bulldozer.value, SLE_BOOL), + SLE_CONDVAR(Cheats, magic_bulldozer.been_used, SLE_BOOL, SL_MIN_VERSION, SLV_REMOVE_MAGIC_BULLDOZER), + SLE_CONDVAR(Cheats, magic_bulldozer.value, SLE_BOOL, SL_MIN_VERSION, SLV_REMOVE_MAGIC_BULLDOZER), SLE_VAR(Cheats, switch_company.been_used, SLE_BOOL), SLE_VAR(Cheats, switch_company.value, SLE_BOOL), SLE_VAR(Cheats, money.been_used, SLE_BOOL), diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 8caa133ef8..6d510d6b51 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -395,6 +395,7 @@ enum SaveLoadVersion : uint16_t { SLV_PATH_CACHE_FORMAT, ///< 346 PR#12345 Vehicle path cache format changed. SLV_ANIMATED_TILE_STATE_IN_MAP, ///< 347 PR#13082 Animated tile state saved for improved performance. SLV_INCREASE_HOUSE_LIMIT, ///< 348 PR#12288 Increase house limit to 4096. + SLV_REMOVE_MAGIC_BULLDOZER, ///< 349 PR#13265 Remove Magic Bulldozer cheat. SL_MAX_VERSION, ///< Highest possible saveload version }; diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 28259aed75..7fa45899bd 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -729,7 +729,7 @@ static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlag flags) if (Company::IsValidID(_current_company)) { if (rating > t->ratings[_current_company] && !(flags & DC_NO_TEST_TOWN_RATING) && - !_cheats.magic_bulldozer.value && _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) { + _settings_game.difficulty.town_council_tolerance != TOWN_COUNCIL_PERMISSIVE) { SetDParam(0, t->index); return CommandCost(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS); } @@ -3974,12 +3974,8 @@ static int GetRating(const Town *t) */ void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags) { - /* if magic_bulldozer cheat is active, town doesn't penalize for removing stuff */ - if (t == nullptr || (flags & DC_NO_MODIFY_TOWN_RATING) || - !Company::IsValidID(_current_company) || - (_cheats.magic_bulldozer.value && add < 0)) { - return; - } + if (t == nullptr || !Company::IsValidID(_current_company)) return; + if (flags & DC_NO_MODIFY_TOWN_RATING) return; int rating = GetRating(t); if (add < 0) { @@ -4011,11 +4007,8 @@ void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags) */ CommandCost CheckforTownRating(DoCommandFlag flags, Town *t, TownRatingCheckType type) { - /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */ - if (t == nullptr || !Company::IsValidID(_current_company) || - _cheats.magic_bulldozer.value || (flags & DC_NO_TEST_TOWN_RATING)) { - return CommandCost(); - } + if (t == nullptr || !Company::IsValidID(_current_company)) return CommandCost(); + if (flags & DC_NO_MODIFY_TOWN_RATING) return CommandCost(); /* minimum rating needed to be allowed to remove stuff */ static const int needed_rating[][TOWN_RATING_CHECK_TYPE_COUNT] = { diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 9ccf76e95c..a6bcc54784 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -811,7 +811,7 @@ static inline CommandCost CheckAllowRemoveTunnelBridge(TileIndex tile) if (tram_rt != INVALID_ROADTYPE) tram_owner = GetRoadOwner(tile, RTT_TRAM); /* We can remove unowned road and if the town allows it */ - if (road_owner == OWNER_TOWN && _current_company != OWNER_TOWN && !(_settings_game.construction.extra_dynamite || _cheats.magic_bulldozer.value)) { + if (road_owner == OWNER_TOWN && _current_company != OWNER_TOWN && !(_settings_game.construction.extra_dynamite)) { /* Town does not allow */ return CheckTileOwnership(tile); }