@@ -93,36 +93,29 @@ bool CheckAllowRemoveRoad(TileIndex tile
static bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, bool *edge_road, RoadType rt)
{
return CheckAllowRemoveRoad(tile, remove, GetRoadOwner(tile, rt), edge_road, rt);
}
/** Delete a piece of road.
* @param tile tile where to remove road from
* @param flags operation to perform
* @param p1 bit 0..3 road pieces to remove (RoadBits)
* bit 4..5 road type
* bit 6 ignore the fact that the tram track has not been removed
* yet when removing the road bits when not actually doing
* it. Makes it possible to test whether the road bits can
* be removed from a level crossing without physically
* removing the tram bits before the test.
* @param p2 unused
* @param pieces roadbits to remove
* @param rt roadtype to remove
* @param crossing_check should we check if there is a tram track when we are removing road from crossing?
*/
CommandCost CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
static CommandCost RemoveRoad(TileIndex tile, uint32 flags, RoadBits pieces, RoadType rt, bool crossing_check)
/* 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;
RoadType rt = (RoadType)GB(p1, 4, 2);
if (!IsValidRoadType(rt)) return CMD_ERROR;
Town *t = NULL;
switch (GetTileType(tile)) {
case MP_ROAD:
if (_game_mode != GM_EDITOR && GetRoadOwner(tile, rt) == OWNER_TOWN) t = GetTownByTile(tile);
if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
break;
@@ -138,13 +131,12 @@ CommandCost CmdRemoveRoad(TileIndex tile
default:
return CMD_ERROR;
RoadBits pieces = Extract<RoadBits, 0>(p1);
RoadTypes rts = GetRoadTypes(tile);
/* The tile doesn't have the given road type */
if (!HasBit(rts, rt)) return CMD_ERROR;
if (!CheckAllowRemoveRoad(tile, pieces, &edge_road, rt)) return CMD_ERROR;
@@ -230,13 +222,13 @@ CommandCost CmdRemoveRoad(TileIndex tile
if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) {
/* Don't allow road to be removed from the crossing when there is tram;
* we can't draw the crossing without trambits ;) */
if (rt == ROADTYPE_ROAD && HasBit(GetRoadTypes(tile), ROADTYPE_TRAM) && ((flags & DC_EXEC) || !HasBit(p1, 6))) return CMD_ERROR;
if (rt == ROADTYPE_ROAD && HasBit(GetRoadTypes(tile), ROADTYPE_TRAM) && (flags & DC_EXEC || crossing_check)) return CMD_ERROR;
if (rt == ROADTYPE_ROAD) {
ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
if (flags & DC_EXEC) {
@@ -256,12 +248,30 @@ CommandCost CmdRemoveRoad(TileIndex tile
case ROAD_TILE_DEPOT:
return RemoveRoad(tile, flags, pieces, rt, true);
static const RoadBits _valid_tileh_slopes_road[][15] = {
/* set of normal ones */
ROAD_ALL, // SLOPE_FLAT
ROAD_NONE, // SLOPE_W
ROAD_NONE, // SLOPE_S
@@ -731,21 +741,21 @@ CommandCost CmdRemoveLongRoad(TileIndex
if (tile == end_tile && !HasBit(p2, 1)) bits &= ROAD_NW | ROAD_NE;
if (tile == start_tile && HasBit(p2, 0)) bits &= ROAD_SE | ROAD_SW;
/* try to remove the halves. */
if (bits != 0) {
ret = DoCommand(tile, rt << 4 | bits, 0, flags & ~DC_EXEC, CMD_REMOVE_ROAD);
ret = RemoveRoad(tile, flags & ~DC_EXEC, bits, rt, true);
if (CmdSucceeded(ret)) {
money -= ret.GetCost();
if (money < 0) {
_additional_cash_required = DoCommand(end_tile, start_tile, p2, flags & ~DC_EXEC, CMD_REMOVE_LONG_ROAD).GetCost();
return cost;
DoCommand(tile, rt << 4 | bits, 0, flags, CMD_REMOVE_ROAD);
RemoveRoad(tile, flags, bits, rt, true);
cost.AddCost(ret);
if (tile == end_tile) break;
@@ -832,13 +842,13 @@ static CommandCost ClearTile_Road(TileIn
!(flags & DC_AUTO)
) {
CommandCost ret(EXPENSES_CONSTRUCTION);
for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) {
if (HasBit(rts, rt)) {
CommandCost tmp_ret = DoCommand(tile, rt << 4 | GetRoadBits(tile, rt), 0, flags, CMD_REMOVE_ROAD);
CommandCost tmp_ret = RemoveRoad(tile, flags, GetRoadBits(tile, rt), rt, true);
if (CmdFailed(tmp_ret)) return tmp_ret;
ret.AddCost(tmp_ret);
return ret;
@@ -852,13 +862,13 @@ static CommandCost ClearTile_Road(TileIn
if (flags & DC_AUTO) return_cmd_error(STR_1801_MUST_REMOVE_ROAD_FIRST);
/* Must iterate over the roadtypes in a reverse manner because
* tram tracks must be removed before the road bits. */
for (RoadType rt = ROADTYPE_HWAY; rt >= ROADTYPE_ROAD; rt--) {
CommandCost tmp_ret = DoCommand(tile, 1 << 6 | rt << 4 | GetCrossingRoadBits(tile), 0, flags, CMD_REMOVE_ROAD);
CommandCost tmp_ret = RemoveRoad(tile, flags, GetCrossingRoadBits(tile), rt, false);
@@ -1273,13 +1283,13 @@ static void TileLoop_Road(TileIndex tile
if (_patches.mod_road_rebuild) {
/* Generate a nicer town surface */
const RoadBits old_rb = GetAnyRoadBits(tile, ROADTYPE_ROAD);
const RoadBits new_rb = CleanUpRoadBits(tile, old_rb);
if (old_rb != new_rb) {
DoCommand(tile, (old_rb ^ new_rb), t->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_REMOVE_ROAD);
RemoveRoad(tile, DC_EXEC | DC_AUTO | DC_NO_WATER, (old_rb ^ new_rb), ROADTYPE_ROAD, true);
MarkTileDirtyByTile(tile);
Status change: