summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/rail_cmd.cpp48
-rw-r--r--src/station_cmd.cpp28
-rw-r--r--src/tunnelbridge_cmd.cpp18
-rw-r--r--src/waypoint.cpp8
4 files changed, 99 insertions, 3 deletions
diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp
index 0494d9ddc..fd3755e5e 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<Vehicle*, 2> 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 4b62d7289..d3e69216b 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<Vehicle*, 4> 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 41af685ac..08588e4ed 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 ad86a6690..ac81cc45d 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);