(svn r13234) -Fix: Check/affect town rating when removing/bulldozing town-owned road under drivethrough stops.
authorfrosch
Sat, 24 May 2008 22:15:10 +0000
changeset 10690 2a363031721a
parent 10689 46a1a76e734e
child 10692 9532c1cee494
(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
src/road_internal.h
src/station_cmd.cpp
src/station_map.h
src/town_type.h
--- a/src/road_cmd.cpp	Sat May 24 19:36:20 2008 +0000
+++ b/src/road_cmd.cpp	Sat May 24 22:15:10 2008 +0000
@@ -130,10 +130,18 @@
 
 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 @@
 	 * 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 @@
 	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 @@
  */
 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 @@
 			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 @@
 				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 @@
 			 * 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 @@
 
 			case MP_STATION:
 				SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt));
+				if (IsDriveThroughStopTile(tile) && rt == ROADTYPE_ROAD) SetStopBuiltOnTownRoad(tile, false);
 				break;
 
 			default:
--- a/src/road_internal.h	Sat May 24 19:36:20 2008 +0000
+++ b/src/road_internal.h	Sat May 24 22:15:10 2008 +0000
@@ -20,11 +20,12 @@
  * @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
--- a/src/station_cmd.cpp	Sat May 24 19:36:20 2008 +0000
+++ b/src/station_cmd.cpp	Sat May 24 22:15:10 2008 +0000
@@ -2995,16 +2995,15 @@
  * 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 @@
 		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);
--- a/src/station_map.h	Sat May 24 19:36:20 2008 +0000
+++ b/src/station_map.h	Sat May 24 22:15:10 2008 +0000
@@ -134,6 +134,12 @@
 	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.
--- a/src/town_type.h	Sat May 24 19:36:20 2008 +0000
+++ b/src/town_type.h	Sat May 24 22:15:10 2008 +0000
@@ -54,7 +54,8 @@
 	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,