summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/road_cmd.cpp63
-rw-r--r--src/road_internal.h5
-rw-r--r--src/station_cmd.cpp11
-rw-r--r--src/station_map.h6
-rw-r--r--src/town_type.h3
5 files changed, 49 insertions, 39 deletions
diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp
index 5b75b15c8..26a36544f 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 7a56a4824..9e3f3c510 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 302d36c19..7dd69c99d 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 ad7e05078..0ec6797dc 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 f1ffeea53..8a555a7c0 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,