* Is it allowed to remove the given road bits from the given tile? * @param tile the tile to remove the road from * @param remove the roadbits that are going to be removed * @param owner the actual owner of the roadbits of the tile * @param rt the road type to remove the bits from * @param flags command flags * @param town_check Shall the town rating checked/affected
| 250 | * @return A succeeded command when it is allowed to remove the road bits, a failed command otherwise. |
| 251 | */ |
| 252 | CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, RoadTramType rtt, DoCommandFlags flags, bool town_check) |
| 253 | { |
| 254 | if (_game_mode == GM_EDITOR || remove == ROAD_NONE) return CommandCost(); |
| 255 | |
| 256 | /* Water can always flood and towns can always remove "normal" road pieces. |
| 257 | * Towns are not be allowed to remove non "normal" road pieces, like tram |
| 258 | * tracks as that would result in trams that cannot turn. */ |
| 259 | if (_current_company == OWNER_WATER || |
| 260 | (rtt == RTT_ROAD && !Company::IsValidID(_current_company))) return CommandCost(); |
| 261 | |
| 262 | /* Only do the special processing if the road is owned |
| 263 | * by a town */ |
| 264 | if (owner != OWNER_TOWN) { |
| 265 | if (owner == OWNER_NONE) return CommandCost(); |
| 266 | CommandCost ret = CheckOwnership(owner); |
| 267 | return ret; |
| 268 | } |
| 269 | |
| 270 | if (!town_check) return CommandCost(); |
| 271 | |
| 272 | if (_cheats.magic_bulldozer.value) return CommandCost(); |
| 273 | |
| 274 | Town *t = ClosestTownFromTile(tile, UINT_MAX); |
| 275 | if (t == nullptr) return CommandCost(); |
| 276 | |
| 277 | /* check if you're allowed to remove the street owned by a town |
| 278 | * removal allowance depends on difficulty setting */ |
| 279 | CommandCost ret = CheckforTownRating(flags, t, TownRatingCheckType::RoadRemove); |
| 280 | if (ret.Failed()) return ret; |
| 281 | |
| 282 | /* Get a bitmask of which neighbouring roads has a tile */ |
| 283 | RoadBits n = ROAD_NONE; |
| 284 | RoadBits present = GetAnyRoadBits(tile, rtt); |
| 285 | if ((present & ROAD_NE) && (GetAnyRoadBits(TileAddXY(tile, -1, 0), rtt) & ROAD_SW)) n |= ROAD_NE; |
| 286 | if ((present & ROAD_SE) && (GetAnyRoadBits(TileAddXY(tile, 0, 1), rtt) & ROAD_NW)) n |= ROAD_SE; |
| 287 | if ((present & ROAD_SW) && (GetAnyRoadBits(TileAddXY(tile, 1, 0), rtt) & ROAD_NE)) n |= ROAD_SW; |
| 288 | if ((present & ROAD_NW) && (GetAnyRoadBits(TileAddXY(tile, 0, -1), rtt) & ROAD_SE)) n |= ROAD_NW; |
| 289 | |
| 290 | int rating_decrease = RATING_ROAD_DOWN_STEP_EDGE; |
| 291 | /* If 0 or 1 bits are set in n, or if no bits that match the bits to remove, |
| 292 | * then allow it */ |
| 293 | if (KillFirstBit(n) != ROAD_NONE && (n & remove) != ROAD_NONE) { |
| 294 | /* you can remove all kind of roads with extra dynamite */ |
| 295 | if (!_settings_game.construction.extra_dynamite) { |
| 296 | return CommandCostWithParam(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, t->index); |
| 297 | } |
| 298 | rating_decrease = RATING_ROAD_DOWN_STEP_INNER; |
| 299 | } |
| 300 | ChangeTownRating(t, rating_decrease, RATING_ROAD_MINIMUM, flags); |
| 301 | |
| 302 | return CommandCost(); |
| 303 | } |
| 304 | |
| 305 | |
| 306 | /** |
no test coverage detected