From ca30288c9d0057c62712973ae2c126195c8c9df5 Mon Sep 17 00:00:00 2001 From: frosch Date: Sat, 24 May 2008 22:15:10 +0000 Subject: [PATCH] (svn r13234) -Fix: Check/affect town rating when removing/bulldozing town-owned road under drivethrough stops. -Fix: Reset the 'town-owned-road'-flag when removing and rebuilding road under drivethrough stops. --- src/road_cmd.cpp | 63 ++++++++++++++++++++++++--------------------- src/road_internal.h | 5 ++-- src/station_cmd.cpp | 11 ++++---- src/station_map.h | 6 +++++ src/town_type.h | 3 ++- 5 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 5b75b15c8b..26a36544fc 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -130,10 +130,18 @@ static const RoadBits _invalid_tileh_slopes_road[2][15] = { Foundation GetRoadFoundation(Slope tileh, RoadBits bits); -bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road, RoadType rt) +/** + * 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 + * @return true when it is allowed to remove the road bits + */ +bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, RoadType rt, uint32 flags, bool town_check) { - *edge_road = true; - if (_game_mode == GM_EDITOR || remove == ROAD_NONE) return true; /* Water can always flood and towns can always remove "normal" road pieces. @@ -146,8 +154,17 @@ bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *ed * by a town */ if (owner != OWNER_TOWN) return (owner == OWNER_NONE) || CheckOwnership(owner); + if (!town_check) return true; + if (_cheats.magic_bulldozer.value) return true; + Town *t = ClosestTownFromTile(tile, UINT_MAX); + if (t == NULL) return true; + + /* check if you're allowed to remove the street owned by a town + * removal allowance depends on difficulty setting */ + if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return false; + /* Get a bitmask of which neighbouring roads has a tile */ RoadBits n = ROAD_NONE; RoadBits present = GetAnyRoadBits(tile, rt); @@ -156,19 +173,19 @@ bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *ed if (present & ROAD_SW && GetAnyRoadBits(TILE_ADDXY(tile, 1, 0), rt) & ROAD_NE) n |= ROAD_SW; if (present & ROAD_NW && GetAnyRoadBits(TILE_ADDXY(tile, 0, -1), rt) & ROAD_SE) n |= ROAD_NW; + int rating_decrease = RATING_ROAD_DOWN_STEP_EDGE; /* If 0 or 1 bits are set in n, or if no bits that match the bits to remove, * then allow it */ if (KillFirstBit(n) != ROAD_NONE && (n & remove) != ROAD_NONE) { - *edge_road = false; /* you can remove all kind of roads with extra dynamite */ - if (_patches.extra_dynamite) return true; - - const Town *t = ClosestTownFromTile(tile, (uint)-1); - - SetDParam(0, t->index); - _error_message = STR_2009_LOCAL_AUTHORITY_REFUSES; - return false; + if (!_patches.extra_dynamite) { + SetDParam(0, t->index); + _error_message = STR_2009_LOCAL_AUTHORITY_REFUSES; + return false; + } + rating_decrease = RATING_ROAD_DOWN_STEP_INNER; } + ChangeTownRating(t, rating_decrease, RATING_ROAD_MINIMUM); return true; } @@ -183,26 +200,20 @@ bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *ed */ static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, RoadType rt, bool crossing_check, bool town_check = true) { - /* cost for removing inner/edge -roads */ - static const uint16 road_remove_cost[2] = {50, 18}; - - /* true if the roadpiece was always removeable, - * false if it was a center piece. Affects town ratings drop */ - bool edge_road; - RoadTypes rts = GetRoadTypes(tile); /* The tile doesn't have the given road type */ if (!HasBit(rts, rt)) return CMD_ERROR; - Town *t = NULL; + bool town_road_under_stop = false; + switch (GetTileType(tile)) { case MP_ROAD: - if (_game_mode != GM_EDITOR && IsRoadOwner(tile, rt, OWNER_TOWN)) t = GetTownByTile(tile); if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; break; case MP_STATION: if (!IsDriveThroughStopTile(tile)) return CMD_ERROR; + if (rt == ROADTYPE_ROAD) town_road_under_stop = GetStopBuiltOnTownRoad(tile); if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR; break; @@ -215,11 +226,7 @@ static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, Roa return CMD_ERROR; } - if (!CheckAllowRemoveRoad(tile, pieces, GetRoadOwner(tile, rt), &edge_road, rt)) return CMD_ERROR; - - /* check if you're allowed to remove the street owned by a town - * removal allowance depends on difficulty setting */ - if (town_check && !CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR; + if (!CheckAllowRemoveRoad(tile, pieces, town_road_under_stop ? OWNER_TOWN : GetRoadOwner(tile, rt), rt, flags, town_check)) return CMD_ERROR; if (!IsTileType(tile, MP_ROAD)) { /* If it's the last roadtype, just clear the whole tile */ @@ -285,7 +292,6 @@ static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, Roa return CMD_ERROR; } - if (town_check) ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); if (flags & DC_EXEC) { if (HasRoadWorks(tile)) { /* flooding tile with road works, don't forget to remove the effect vehicle too */ @@ -331,10 +337,6 @@ static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, Roa * we can't draw the crossing without trambits ;) */ if (rt == ROADTYPE_ROAD && HasTileRoadType(tile, ROADTYPE_TRAM) && (flags & DC_EXEC || crossing_check)) return CMD_ERROR; - if (rt == ROADTYPE_ROAD) { - if (town_check) ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM); - } - if (flags & DC_EXEC) { RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt)); if (rts == ROADTYPES_NONE) { @@ -654,6 +656,7 @@ do_clear:; case MP_STATION: SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt)); + if (IsDriveThroughStopTile(tile) && rt == ROADTYPE_ROAD) SetStopBuiltOnTownRoad(tile, false); break; default: diff --git a/src/road_internal.h b/src/road_internal.h index 7a56a48249..9e3f3c5106 100644 --- a/src/road_internal.h +++ b/src/road_internal.h @@ -20,11 +20,12 @@ RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb); * @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 edge_road are the removed bits from a town? * @param rt the road type to remove the bits from + * @param flags command flags + * @param town_check Shall the town rating checked/affected * @return true when it is allowed to remove the road bits */ -bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road, RoadType rt); +bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, RoadType rt, uint32 flags, bool town_check = true); /** * Draw the catenary for tram road bits diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 302d36c192..7dd69c99d7 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2995,16 +2995,15 @@ static void ChangeTileOwner_Station(TileIndex tile, PlayerID old_player, PlayerI * Road stops built on town-owned roads check the conditions * that would allow clearing of the original road. * @param tile road stop tile to check + * @param flags command flags * @return true if the road can be cleared */ -static bool CanRemoveRoadWithStop(TileIndex tile) +static bool CanRemoveRoadWithStop(TileIndex tile, uint32 flags) { /* The road can always be cleared if it was not a town-owned road */ if (!GetStopBuiltOnTownRoad(tile)) return true; - bool edge_road; - return CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, ROADTYPE_ROAD), OWNER_TOWN, &edge_road, ROADTYPE_ROAD) && - CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, ROADTYPE_TRAM), OWNER_TOWN, &edge_road, ROADTYPE_TRAM); + return CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, ROADTYPE_ROAD), OWNER_TOWN, ROADTYPE_ROAD, flags); } static CommandCost ClearTile_Station(TileIndex tile, byte flags) @@ -3029,11 +3028,11 @@ static CommandCost ClearTile_Station(TileIndex tile, byte flags) case STATION_RAIL: return RemoveRailroadStation(st, tile, flags); case STATION_AIRPORT: return RemoveAirport(st, flags); case STATION_TRUCK: - if (IsDriveThroughStopTile(tile) && !CanRemoveRoadWithStop(tile)) + if (IsDriveThroughStopTile(tile) && !CanRemoveRoadWithStop(tile, flags)) return_cmd_error(STR_3047_MUST_DEMOLISH_TRUCK_STATION); return RemoveRoadStop(st, flags, tile); case STATION_BUS: - if (IsDriveThroughStopTile(tile) && !CanRemoveRoadWithStop(tile)) + if (IsDriveThroughStopTile(tile) && !CanRemoveRoadWithStop(tile, flags)) return_cmd_error(STR_3046_MUST_DEMOLISH_BUS_STATION); return RemoveRoadStop(st, flags, tile); case STATION_BUOY: return RemoveBuoy(st, flags); diff --git a/src/station_map.h b/src/station_map.h index ad7e050787..0ec6797dcc 100644 --- a/src/station_map.h +++ b/src/station_map.h @@ -134,6 +134,12 @@ static inline bool GetStopBuiltOnTownRoad(TileIndex t) return HasBit(_m[t].m6, 2); } +static inline void SetStopBuiltOnTownRoad(TileIndex t, bool on_town_road) +{ + assert(IsDriveThroughStopTile(t)); + SB(_m[t].m6, 2, 1, on_town_road); +} + /** * Gets the direction the road stop entrance points towards. diff --git a/src/town_type.h b/src/town_type.h index f1ffeea532..8a555a7c08 100644 --- a/src/town_type.h +++ b/src/town_type.h @@ -54,7 +54,8 @@ enum { RATING_INDUSTRY_DOWN_STEP = -1500, RATING_INDUSTRY_MINIMUM = RATING_MINIMUM, - RATING_ROAD_DOWN_STEP = -50, + RATING_ROAD_DOWN_STEP_INNER = -50, ///< removing a roadpiece in the middle + RATING_ROAD_DOWN_STEP_EDGE = -18, ///< removing a roadpiece at the edge RATING_ROAD_MINIMUM = -100, RATING_HOUSE_MINIMUM = RATING_MINIMUM,