From f0fdbf9644502541531112c6b10f63d9f68313d4 Mon Sep 17 00:00:00 2001 From: rubidium Date: Sat, 2 Aug 2008 22:55:08 +0000 Subject: [PATCH] (svn r13957) -Codechange [YAPP]: Free the old path reservation on removing some tracks and reroute trains afterwards. (michi_cc) --- src/rail_cmd.cpp | 48 ++++++++++++++++++++++++++++++++++++++-- src/station_cmd.cpp | 28 +++++++++++++++++++++++ src/tunnelbridge_cmd.cpp | 18 ++++++++++++++- src/waypoint.cpp | 8 +++++++ 4 files changed, 99 insertions(+), 3 deletions(-) diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 0494d9ddc1..fd3755e5e5 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -46,6 +46,8 @@ #include "functions.h" #include "elrail_func.h" #include "oldpool_func.h" +#include "pbs.h" +#include "core/smallvec_type.hpp" #include "table/sprites.h" #include "table/strings.h" @@ -458,6 +460,8 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 * so do not call GetTileOwner(tile) in any case here */ Owner owner = INVALID_OWNER; + Vehicle *v = NULL; + switch (GetTileType(tile)) { case MP_ROAD: { if (!IsLevelCrossing(tile) || @@ -468,6 +472,10 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 } if (flags & DC_EXEC) { + if (HasReservedTracks(tile, trackbit)) { + v = GetTrainForReservation(tile, track); + if (v != NULL) FreeTrainTrackReservation(v); + } owner = GetTileOwner(tile); MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM), GetRoadOwner(tile, ROADTYPE_HWAY)); } @@ -492,6 +500,10 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 cost.AddCost(DoCommand(tile, track, 0, flags, CMD_REMOVE_SIGNALS)); if (flags & DC_EXEC) { + if (HasReservedTracks(tile, trackbit)) { + v = GetTrainForReservation(tile, track); + if (v != NULL) FreeTrainTrackReservation(v); + } owner = GetTileOwner(tile); present ^= trackbit; if (present == 0) { @@ -531,6 +543,8 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 AddTrackToSignalBuffer(tile, track, owner); YapfNotifyTrackLayoutChange(tile, track); } + + if (v != NULL) TryPathReserve(v, true); } return cost; @@ -1259,11 +1273,24 @@ CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) /* Trying to convert other's rail */ if (!CheckTileOwnership(tile)) continue; + SmallVector vehicles_affected; + /* Vehicle on the tile when not converting Rail <-> ElRail * Tunnels and bridges have special check later */ if (tt != MP_TUNNELBRIDGE) { if (!IsCompatibleRail(type, totype) && !EnsureNoVehicleOnGround(tile)) continue; if (flags & DC_EXEC) { // we can safely convert, too + TrackBits reserved = GetReservedTrackbits(tile); + Track track; + while ((track = RemoveFirstTrack(&reserved)) != INVALID_TRACK) { + Vehicle *v = GetTrainForReservation(tile, track); + if (v != NULL && !HasPowerOnRail(v->u.rail.railtype, totype)) { + /* No power on new rail type, reroute. */ + FreeTrainTrackReservation(v); + *vehicles_affected.Append() = v; + } + } + SetRailType(tile, totype); MarkTileDirtyByTile(tile); /* update power of train engines on this tile */ @@ -1320,14 +1347,20 @@ CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) GetVehicleTunnelBridge(tile, endtile) != NULL) continue; if (flags & DC_EXEC) { + Track track = DiagDirToDiagTrack(GetTunnelBridgeDirection(tile)); + if (GetTunnelBridgeReservation(tile)) { + Vehicle *v = GetTrainForReservation(tile, track); + if (v != NULL) { + FreeTrainTrackReservation(v); + *vehicles_affected.Append() = v; + } + } SetRailType(tile, totype); SetRailType(endtile, totype); VehicleFromPos(tile, NULL, &UpdateTrainPowerProc); VehicleFromPos(endtile, NULL, &UpdateTrainPowerProc); - Track track = DiagDirToDiagTrack(GetTunnelBridgeDirection(tile)); - YapfNotifyTrackLayoutChange(tile, track); YapfNotifyTrackLayoutChange(endtile, track); @@ -1353,6 +1386,10 @@ CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) cost.AddCost(RailConvertCost(type, totype)); break; } + + for (uint i = 0; i < vehicles_affected.Length(); ++i) { + TryPathReserve(vehicles_affected[i], true); + } } } @@ -1371,11 +1408,18 @@ static CommandCost RemoveTrainDepot(TileIndex tile, uint32 flags) /* read variables before the depot is removed */ DiagDirection dir = GetRailDepotDirection(tile); Owner owner = GetTileOwner(tile); + Vehicle *v = NULL; + + if (GetDepotWaypointReservation(tile)) { + v = GetTrainForReservation(tile, DiagDirToDiagTrack(dir)); + if (v != NULL) FreeTrainTrackReservation(v); + } DoClearSquare(tile); delete GetDepotByTile(tile); AddSideToSignalBuffer(tile, dir, owner); YapfNotifyTrackLayoutChange(tile, DiagDirToDiagTrack(dir)); + if (v != NULL) TryPathReserve(v, true); } return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_train_depot); diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 4b62d72891..d3e69216b6 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -44,6 +44,7 @@ #include "animated_tile_func.h" #include "elrail_func.h" #include "newgrf.h" +#include "core/smallvec_type.hpp" #include "table/sprites.h" #include "table/strings.h" @@ -1019,11 +1020,20 @@ CommandCost CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1, numtracks_orig = numtracks; + SmallVector affected_vehicles; do { TileIndex tile = tile_org; int w = plat_len; do { byte layout = *layout_ptr++; + if (IsRailwayStationTile(tile) && GetRailwayStationReservation(tile)) { + Vehicle *v = GetTrainForReservation(tile, AxisToTrack(GetRailStationAxis(tile))); + if (v != NULL) { + FreeTrainTrackReservation(v); + *affected_vehicles.Append() = v; + } + } + MakeRailStation(tile, st->owner, st->index, axis, layout & ~1, (RailType)GB(p2, 0, 4)); SetCustomStationSpecIndex(tile, specindex); SetStationTileRandomBits(tile, GB(Random(), 0, 4)); @@ -1048,6 +1058,10 @@ CommandCost CmdBuildRailroadStation(TileIndex tile_org, uint32 flags, uint32 p1, tile_org += tile_delta ^ TileDiffXY(1, 1); // perpendicular to tile_delta } while (--numtracks); + for (uint i = 0; i < affected_vehicles.Length(); ++i) { + TryPathReserve(affected_vehicles[i], true); + } + st->MarkTilesDirty(false); UpdateStationVirtCoordDirty(st); UpdateStationAcceptance(st, false); @@ -1173,6 +1187,12 @@ CommandCost CmdRemoveFromRailroadStation(TileIndex tile, uint32 flags, uint32 p1 uint specindex = GetCustomStationSpecIndex(tile2); Track track = GetRailStationTrack(tile2); Owner owner = GetTileOwner(tile2); + Vehicle *v = NULL; + + if (GetRailwayStationReservation(tile2)) { + v = GetTrainForReservation(tile2, track); + if (v != NULL) FreeTrainTrackReservation(v); + } DoClearSquare(tile2); st->rect.AfterRemoveTile(st, tile2); @@ -1188,6 +1208,8 @@ CommandCost CmdRemoveFromRailroadStation(TileIndex tile, uint32 flags, uint32 p1 st->MarkTilesDirty(false); UpdateStationSignCoord(st); + if (v != NULL) TryPathReserve(v, true); + /* if we deleted the whole station, delete the train facility. */ if (st->train_tile == 0) { st->facilities &= ~FACIL_TRAIN; @@ -1236,9 +1258,15 @@ static CommandCost RemoveRailroadStation(Station *st, TileIndex tile, uint32 fla /* read variables before the station tile is removed */ Track track = GetRailStationTrack(tile); Owner owner = GetTileOwner(tile); // _current_player can be OWNER_WATER + Vehicle *v = NULL; + if (GetRailwayStationReservation(tile)) { + v = GetTrainForReservation(tile, track); + if (v != NULL) FreeTrainTrackReservation(v); + } DoClearSquare(tile); AddTrackToSignalBuffer(tile, track, owner); YapfNotifyTrackLayoutChange(tile, track); + if (v != NULL) TryPathReserve(v, true); } } tile += TileDiffXY(1, 0); diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 41af685acf..08588e4ede 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -630,8 +630,15 @@ static CommandCost DoClearTunnel(TileIndex tile, uint32 flags) if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) { /* We first need to request values before calling DoClearSquare */ DiagDirection dir = GetTunnelBridgeDirection(tile); + Track track = DiagDirToDiagTrack(dir); Owner owner = GetTileOwner(tile); + Vehicle *v = NULL; + if (GetTunnelBridgeReservation(tile)) { + v = GetTrainForReservation(tile, track); + if (v != NULL) FreeTrainTrackReservation(v); + } + DoClearSquare(tile); DoClearSquare(endtile); @@ -639,9 +646,10 @@ static CommandCost DoClearTunnel(TileIndex tile, uint32 flags) AddSideToSignalBuffer(tile, ReverseDiagDir(dir), owner); AddSideToSignalBuffer(endtile, dir, owner); - Track track = DiagDirToDiagTrack(dir); YapfNotifyTrackLayoutChange(tile, track); YapfNotifyTrackLayoutChange(endtile, track); + + if (v != NULL) TryPathReserve(v); } else { DoClearSquare(tile); DoClearSquare(endtile); @@ -689,6 +697,12 @@ static CommandCost DoClearBridge(TileIndex tile, uint32 flags) bool rail = GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL; Owner owner = GetTileOwner(tile); uint height = GetBridgeHeight(tile); + Vehicle *v = NULL; + + if (rail && GetTunnelBridgeReservation(tile)) { + v = GetTrainForReservation(tile, DiagDirToDiagTrack(direction)); + if (v != NULL) FreeTrainTrackReservation(v); + } DoClearSquare(tile); DoClearSquare(endtile); @@ -710,6 +724,8 @@ static CommandCost DoClearBridge(TileIndex tile, uint32 flags) Track track = DiagDirToDiagTrack(direction); YapfNotifyTrackLayoutChange(tile, track); YapfNotifyTrackLayoutChange(endtile, track); + + if (v != NULL) TryPathReserve(v, true); } } diff --git a/src/waypoint.cpp b/src/waypoint.cpp index ad86a66901..ac81cc45d5 100644 --- a/src/waypoint.cpp +++ b/src/waypoint.cpp @@ -33,6 +33,8 @@ #include "newgrf_station.h" #include "oldpool_func.h" #include "viewport_func.h" +#include "pbs.h" +#include "train.h" #include "table/strings.h" @@ -320,6 +322,7 @@ CommandCost RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove) wp->deleted = 30; // let it live for this many days before we do the actual deletion. RedrawWaypointSign(wp); + Vehicle *v = NULL; if (justremove) { TrackBits tracks = GetRailWaypointBits(tile); bool reserved = GetDepotWaypointReservation(tile); @@ -327,10 +330,15 @@ CommandCost RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove) if (reserved) SetTrackReservation(tile, tracks); MarkTileDirtyByTile(tile); } else { + if (GetDepotWaypointReservation(tile)) { + v = GetTrainForReservation(tile, track); + if (v != NULL) FreeTrainTrackReservation(v); + } DoClearSquare(tile); AddTrackToSignalBuffer(tile, track, owner); } YapfNotifyTrackLayoutChange(tile, track); + if (v != NULL) TryPathReserve(v, true); } return CommandCost(EXPENSES_CONSTRUCTION, _price.remove_train_depot);