diff --git a/src/command.cpp b/src/command.cpp index b24745bd40..068f8bf440 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -137,6 +137,7 @@ CommandProc CmdFoundTown; CommandProc CmdRenameTown; CommandProc CmdDoTownAction; CommandProc CmdExpandTown; +CommandProc CmdDeleteTown; CommandProc CmdChangeSetting; CommandProc CmdChangeCompanySetting; @@ -289,6 +290,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdRenameTown, CMD_SERVER), // CMD_RENAME_TOWN DEF_CMD(CmdDoTownAction, 0), // CMD_DO_TOWN_ACTION DEF_CMD(CmdExpandTown, CMD_OFFLINE), // CMD_EXPAND_TOWN + DEF_CMD(CmdDeleteTown, CMD_OFFLINE), // CMD_DELETE_TOWN DEF_CMD(CmdSellShip, 0), // CMD_SELL_SHIP DEF_CMD(CmdBuildShip, 0), // CMD_BUILD_SHIP diff --git a/src/command_type.h b/src/command_type.h index 8f74d6e614..82f5ada911 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -236,6 +236,7 @@ enum Commands { CMD_RENAME_TOWN, ///< rename a town CMD_DO_TOWN_ACTION, ///< do a action from the town detail window (like advertises or bribe) CMD_EXPAND_TOWN, ///< expand a town + CMD_DELETE_TOWN, ///< delete a town CMD_SELL_SHIP, ///< sell a ship CMD_BUILD_SHIP, ///< build a new ship diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 702de3fc6c..db93a7a008 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -45,6 +45,7 @@ #include "townname_type.h" #include "core/random_func.hpp" #include "core/backup_type.hpp" +#include "depot_base.h" #include "table/strings.h" #include "table/town_land.h" @@ -2348,6 +2349,70 @@ CommandCost CmdExpandTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 return CommandCost(); } +/** + * Delete a town (scenario editor only). + * @param tile Unused. + * @param flags Type of operation. + * @param p1 Town ID to delete. + * @param p2 Unused. + * @param text Unused. + * @return Empty cost or an error. + */ +CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + if (_game_mode != GM_EDITOR) return CMD_ERROR; + Town *t = Town::GetIfValid(p1); + if (t == NULL) return CMD_ERROR; + + /* Stations refer to towns. */ + const Station *st; + FOR_ALL_STATIONS(st) { + if (st->town == t) { + /* Non-oil rig stations are always a problem. */ + if (!(st->facilities & FACIL_AIRPORT) || st->airport.type != AT_OILRIG) return CMD_ERROR; + /* We can only automatically delete oil rigs *if* there's no vehicle on them. */ + CommandCost ret = DoCommand(st->airport.tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR); + if (ret.Failed()) return ret; + } + } + + /* Depots refer to towns. */ + const Depot *d; + FOR_ALL_DEPOTS(d) { + if (d->town == t) return CMD_ERROR; + } + + /* Check all tiles for town ownership. */ + for (TileIndex tile = 0; tile < MapSize(); ++tile) { + switch (GetTileType(tile)) { + case MP_ROAD: + if (HasTownOwnedRoad(tile) && GetTownIndex(tile) == t->index) { + /* Can we clear this tile? */ + CommandCost ret = DoCommand(tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR); + if (ret.Failed()) return ret; + } + break; + + case MP_TUNNELBRIDGE: + if (IsTileOwner(tile, OWNER_TOWN) && + ClosestTownFromTile(tile, UINT_MAX) == t) { + /* Can we clear this bridge? */ + CommandCost ret = DoCommand(tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR); + if (ret.Failed()) return ret; + } + break; + + default: + break; + } + } + + /* The town destructor will delete everything related to the town. */ + if (flags & DC_EXEC) delete t; + + return CommandCost(); +} + /** * Factor in the cost of each town action. * @see TownActions diff --git a/src/town_gui.cpp b/src/town_gui.cpp index 4a50b12114..e1581cb700 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -33,8 +33,6 @@ #include "townname_func.h" #include "townname_type.h" #include "core/geometry_func.hpp" -#include "station_base.h" -#include "depot_base.h" #include "genworld.h" #include "table/sprites.h" @@ -466,65 +464,11 @@ public: break; case TVW_DELETE: // delete town - only available on Scenario editor - if (this->CanDeleteTown()) { - delete this->town; - } else { - ShowErrorMessage(STR_ERROR_TOWN_CAN_T_DELETE, INVALID_STRING_ID, WL_INFO); - } + DoCommandP(0, this->window_number, 0, CMD_DELETE_TOWN | CMD_MSG(STR_ERROR_TOWN_CAN_T_DELETE)); break; } } - /** - * Can we delete the town? - * Or in other words, does anything refer to this town? - * @return true if it's possible - */ - bool CanDeleteTown() const - { - /* Stations refer to towns. */ - const Station *st; - FOR_ALL_STATIONS(st) { - if (st->town == this->town) { - /* Non-oil rig stations are always a problem. */ - if (!(st->facilities & FACIL_AIRPORT) || st->airport.type != AT_OILRIG) return false; - /* We can only automatically delete oil rigs *if* there's no vehicle on them. */ - if (DoCommand(st->airport.tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR).Failed()) return false; - } - } - - /* Depots refer to towns. */ - const Depot *d; - FOR_ALL_DEPOTS(d) { - if (d->town == this->town) return false; - } - - /* Check all tiles for town ownership. */ - for (TileIndex tile = 0; tile < MapSize(); ++tile) { - switch (GetTileType(tile)) { - case MP_ROAD: - if (HasTownOwnedRoad(tile) && GetTownIndex(tile) == this->town->index) { - /* Can we clear this tile? */ - if (DoCommand(tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR).Failed()) return false; - } - break; - - case MP_TUNNELBRIDGE: - if (IsTileOwner(tile, OWNER_TOWN) && - ClosestTownFromTile(tile, UINT_MAX) == this->town) { - /* Can we clear this bridge? */ - if (DoCommand(tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR).Failed()) return false; - } - break; - - default: - break; - } - } - - return true; - } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) { switch (widget) {