diff --git a/train_cmd.c b/train_cmd.c --- a/train_cmd.c +++ b/train_cmd.c @@ -1321,13 +1321,15 @@ static void ReverseTrainDirection(Vehicl int l = 0, r = -1; Vehicle *u; TileIndex tile; - byte trackdir; + Trackdir trackdir; + TileIndex pbs_end_tile = v->u.rail.pbs_end_tile; // these may be changed, and we may need + Trackdir pbs_end_trackdir = v->u.rail.pbs_end_trackdir; // the old values, so cache them u = GetLastVehicleInChain(v); tile = GetVehicleTileOutOfTunnel(u, false); trackdir = ReverseTrackdir(GetVehicleTrackdir(u)); - if (PBSTileReserved(tile) & (1 << (trackdir&7))) { + if (PBSTileReserved(tile) & (1 << TrackdirToTrack(trackdir))) { NPFFindStationOrTileData fstd; NPFFoundTargetData ftd; @@ -1351,13 +1353,15 @@ static void ReverseTrainDirection(Vehicl return; } } + + v->u.rail.pbs_end_tile = ftd.node.tile; + v->u.rail.pbs_end_trackdir = ftd.node.direction; } tile = GetVehicleTileOutOfTunnel(v, false); trackdir = GetVehicleTrackdir(v); if (v->u.rail.pbs_status == PBS_STAT_HAS_PATH) { - byte trackdir = GetVehicleTrackdir(v); TileIndex tile = AddTileIndexDiffCWrap(v->tile, TileIndexDiffCByDir(TrackdirToExitdir(trackdir))); uint32 ts; assert(tile != INVALID_TILE); @@ -1365,10 +1369,10 @@ static void ReverseTrainDirection(Vehicl ts &= TrackdirReachesTrackdirs(trackdir); assert(ts != 0 && KillFirstBit2x64(ts) == 0); trackdir = FindFirstBit2x64(ts); - PBSClearPath(tile, trackdir); + PBSClearPath(tile, trackdir, pbs_end_tile, pbs_end_trackdir); v->u.rail.pbs_status = PBS_STAT_NONE; - } else if (PBSTileReserved(tile) & (1 << (trackdir&7))) { - PBSClearPath(tile, trackdir); + } else if (PBSTileReserved(tile) & (1 << TrackdirToTrack(trackdir))) { + PBSClearPath(tile, trackdir, pbs_end_tile, pbs_end_trackdir); if (v->u.rail.track != 0x40) PBSReserveTrack(tile, trackdir & 7); }; @@ -1838,8 +1842,11 @@ static bool CheckTrainStayInDepot(Vehicl if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_EXIT)) { if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED) || NPFGetFlag(&ftd.node, NPF_FLAG_PBS_RED)) return true; - else + else { + v->u.rail.pbs_end_tile = ftd.node.tile; + v->u.rail.pbs_end_trackdir = ftd.node.direction; goto green; + } } } @@ -2007,11 +2014,14 @@ static byte ChooseTrainTrack(Vehicle *v, if (pbs_tracks || (v->u.rail.pbs_status == PBS_STAT_NEED_PATH)) { DEBUG(pbs, 2) ("pbs: (%i) choosefromblock, tile_org:%x tile_dst:%x trackdir:%i pbs_tracks:%i",v->unitnumber, tile,tile - TileOffsByDir(enterdir), trackdir, pbs_tracks); // clear the currently planned path - if (v->u.rail.pbs_status != PBS_STAT_NEED_PATH) PBSClearPath(tile, FindFirstBit2x64(pbs_tracks)); + if (v->u.rail.pbs_status != PBS_STAT_NEED_PATH) PBSClearPath(tile, FindFirstBit2x64(pbs_tracks), v->u.rail.pbs_end_tile, v->u.rail.pbs_end_trackdir); // try to find a route to a green exit signal ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_ANY); + v->u.rail.pbs_end_tile = ftd.node.tile; + v->u.rail.pbs_end_trackdir = ftd.node.direction; + } else ftd = NPFRouteToStationOrTile(tile - TileOffsByDir(enterdir), trackdir, &fstd, TRANSPORT_RAIL, v->owner, v->u.rail.railtype, PBS_MODE_NONE); @@ -2779,6 +2789,8 @@ static void TrainController(Vehicle *v) if (NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED) || NPFGetFlag(&ftd.node, NPF_FLAG_PBS_RED)) goto red_light; else { + v->u.rail.pbs_end_tile = ftd.node.tile; + v->u.rail.pbs_end_trackdir = ftd.node.direction; goto green_light; } @@ -2955,8 +2967,8 @@ static void DeleteLastWagon(Vehicle *v) // clear up reserved pbs tracks if (PBSTileReserved(v->tile) & v->u.rail.track) { if (v == u) { - PBSClearPath(v->tile, FIND_FIRST_BIT(v->u.rail.track)); - PBSClearPath(v->tile, FIND_FIRST_BIT(v->u.rail.track) + 8); + PBSClearPath(v->tile, FIND_FIRST_BIT(v->u.rail.track), v->u.rail.pbs_end_tile, v->u.rail.pbs_end_trackdir); + PBSClearPath(v->tile, FIND_FIRST_BIT(v->u.rail.track) + 8, v->u.rail.pbs_end_tile, v->u.rail.pbs_end_trackdir); }; if (v->tile != u->tile) { PBSClearTrack(v->tile, FIND_FIRST_BIT(v->u.rail.track)); @@ -3206,6 +3218,8 @@ static bool TrainCheckIfLineEnds(Vehicle if (ftd.best_trackdir != 0xFF && NPFGetFlag(&ftd.node, NPF_FLAG_PBS_EXIT)) { if (!(NPFGetFlag(&ftd.node, NPF_FLAG_PBS_BLOCKED) || NPFGetFlag(&ftd.node, NPF_FLAG_PBS_RED))) { v->u.rail.pbs_status = PBS_STAT_HAS_PATH; + v->u.rail.pbs_end_tile = ftd.node.tile; + v->u.rail.pbs_end_trackdir = ftd.node.direction; return true; } };