* Delete a town (scenario editor or worldgen only). * @param flags Type of operation. * @param town_id Town ID to delete. * @return Empty cost or an error. */
| 3293 | * @return Empty cost or an error. |
| 3294 | */ |
| 3295 | CommandCost CmdDeleteTown(DoCommandFlags flags, TownID town_id) |
| 3296 | { |
| 3297 | if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR; |
| 3298 | Town *t = Town::GetIfValid(town_id); |
| 3299 | if (t == nullptr) return CMD_ERROR; |
| 3300 | |
| 3301 | /* Stations refer to towns. */ |
| 3302 | for (const Station *st : Station::Iterate()) { |
| 3303 | if (st->town == t) { |
| 3304 | /* Non-oil rig stations are always a problem. */ |
| 3305 | if (!st->facilities.Test(StationFacility::Airport) || st->airport.type != AT_OILRIG) return CMD_ERROR; |
| 3306 | /* We can only automatically delete oil rigs *if* there's no vehicle on them. */ |
| 3307 | CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, st->airport.tile); |
| 3308 | if (ret.Failed()) return ret; |
| 3309 | } |
| 3310 | } |
| 3311 | |
| 3312 | /* Waypoints refer to towns. */ |
| 3313 | for (const Waypoint *wp : Waypoint::Iterate()) { |
| 3314 | if (wp->town == t) return CMD_ERROR; |
| 3315 | } |
| 3316 | |
| 3317 | /* Depots refer to towns. */ |
| 3318 | for (const Depot *d : Depot::Iterate()) { |
| 3319 | if (d->town == t) return CMD_ERROR; |
| 3320 | } |
| 3321 | |
| 3322 | /* Check all tiles for town ownership. First check for bridge tiles, as |
| 3323 | * these do not directly have an owner so we need to check adjacent |
| 3324 | * tiles. This won't work correctly in the same loop if the adjacent |
| 3325 | * tile was already deleted earlier in the loop. */ |
| 3326 | for (const auto current_tile : Map::Iterate()) { |
| 3327 | if (IsTileType(current_tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(current_tile, t)) { |
| 3328 | CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile); |
| 3329 | if (ret.Failed()) return ret; |
| 3330 | } |
| 3331 | } |
| 3332 | |
| 3333 | /* Check all remaining tiles for town ownership. */ |
| 3334 | for (const auto current_tile : Map::Iterate()) { |
| 3335 | bool try_clear = false; |
| 3336 | switch (GetTileType(current_tile)) { |
| 3337 | case MP_ROAD: |
| 3338 | try_clear = HasTownOwnedRoad(current_tile) && GetTownIndex(current_tile) == t->index; |
| 3339 | break; |
| 3340 | |
| 3341 | case MP_HOUSE: |
| 3342 | try_clear = GetTownIndex(current_tile) == t->index; |
| 3343 | break; |
| 3344 | |
| 3345 | case MP_INDUSTRY: |
| 3346 | try_clear = Industry::GetByTile(current_tile)->town == t; |
| 3347 | break; |
| 3348 | |
| 3349 | case MP_OBJECT: |
| 3350 | if (Town::GetNumItems() == 1) { |
| 3351 | /* No towns will be left, remove it! */ |
| 3352 | try_clear = true; |
nothing calls this directly
no test coverage detected