(svn r2625) - Fix: [pbs] Store the end of a train's reserved path explicitly. Prevents trains from unreserving eachothers paths in some cases.
authorhackykid
Sun, 17 Jul 2005 20:09:02 +0000
changeset 2115 71e12444631c
parent 2114 6b2451b1f6b0
child 2116 cdfc27b696b7
(svn r2625) - Fix: [pbs] Store the end of a train's reserved path explicitly. Prevents trains from unreserving eachothers paths in some cases.
- CodeChange: Use the TrackdirToTrack function instead of &7, and remove an unneeded variable.
npf.c
pbs.c
pbs.h
train_cmd.c
vehicle.c
vehicle.h
--- a/npf.c	Sun Jul 17 19:38:40 2005 +0000
+++ b/npf.c	Sun Jul 17 20:09:02 2005 +0000
@@ -180,27 +180,35 @@
 					 * BUT, you have to have a pretty fucked up junction layout for this to happen,
 					 * so we'll just stop this train, the user will eventually notice, so he can fix it.
 					 */
-					PBSClearPath(start, trackdir);
+					PBSClearPath(start, trackdir, curr->node.tile, curr->node.direction);
 					NPFSetFlag(&ftd->node, NPF_FLAG_PBS_BLOCKED, true);
 					DEBUG(pbs, 1) ("PBS: Self-crossing path!!!");
 					return;
 				};
 
-				PBSReserveTrack(curr->node.tile, (curr->node.direction & 7) );
+				PBSReserveTrack(curr->node.tile, TrackdirToTrack(curr->node.direction) );
 
-				/* we want to reserve the last tile (with the signal) on the path too */
-				if (prev != NULL && start == INVALID_TILE) {
-					PBSReserveTrack(prev->node.tile, (prev->node.direction & 7) );
-					start = prev->node.tile;
-					trackdir = ReverseTrackdir(prev->node.direction);
+				/* we want to reserve the last tile (with the signal) on the path too
+				   also remember this tile, cause its the end of the path (where we exit the block) */
+				if (start == INVALID_TILE) {
+					if (prev != NULL) {
+						PBSReserveTrack(prev->node.tile, TrackdirToTrack(prev->node.direction) );
+						start = prev->node.tile;
+						trackdir = ReverseTrackdir(prev->node.direction);
+					} else {
+						start = curr->node.tile;
+						trackdir = curr->node.direction;
+					}
 				}
 			}
 
 			prev = curr;
 			curr = curr->parent;
 		} while (curr != NULL);
+		// we remember the tile/track where this path leaves the pbs junction
+		ftd->node.tile = start;
+		ftd->node.direction = trackdir;
 	}
-
 }
 
 
--- a/pbs.c	Sun Jul 17 19:38:40 2005 +0000
+++ b/pbs.c	Sun Jul 17 20:09:02 2005 +0000
@@ -189,13 +189,17 @@
 		MarkTileDirtyByTile(tile);
 };
 
-void PBSClearPath(TileIndex tile, Trackdir trackdir) {
+void PBSClearPath(TileIndex tile, Trackdir trackdir, TileIndex end_tile, Trackdir end_trackdir) {
 	uint16 res;
 	FindLengthOfTunnelResult flotr;
 	assert(IsValidTile(tile));
-	assert((trackdir & ~8) <= 5);
+	assert(IsValidTrackdir(trackdir));
+
 	do {
-		PBSClearTrack(tile, trackdir & 7);
+		PBSClearTrack(tile, TrackdirToTrack(trackdir));
+
+		if (tile == end_tile && TrackdirToTrack(trackdir) == TrackdirToTrack(end_trackdir))
+			return;
 
 		if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xF0)==0 && (unsigned)(_m[tile].m5 & 3) == TrackdirToExitdir(trackdir)) {
 			// this is a tunnel
@@ -204,11 +208,7 @@
 			tile = flotr.tile;
 		} else {
 			byte exitdir = TrackdirToExitdir(trackdir);
-			if (IsTileDepotType(tile, TRANSPORT_RAIL) && (exitdir != GetDepotDirection(tile, TRANSPORT_RAIL)))
-				return;
 			tile = AddTileIndexDiffCWrap(tile, TileIndexDiffCByDir(exitdir));
-			if (IsTileDepotType(tile, TRANSPORT_RAIL) && (exitdir != ReverseDiagdir(GetDepotDirection(tile, TRANSPORT_RAIL))))
-				return;
 		};
 
 		res = PBSTileReserved(tile);
--- a/pbs.h	Sun Jul 17 19:38:40 2005 +0000
+++ b/pbs.h	Sun Jul 17 20:09:02 2005 +0000
@@ -56,11 +56,13 @@
  * @param track The track to unreserve, valid values 0-5.
  */
 
-void PBSClearPath(TileIndex tile, Trackdir trackdir);
+void PBSClearPath(TileIndex tile, Trackdir trackdir, TileIndex end_tile, Trackdir end_trackdir);
 /**<
  * Follows a planned(reserved) path, and unreserves the tracks.
  * @param tile The tile on which the path starts
  * @param trackdir The trackdirection in which the path starts
+ * @param end_tile The tile on which the path ends
+ * @param end_trackdir The trackdirection in which the path ends
  */
 
 bool PBSIsPbsSignal(TileIndex tile, Trackdir trackdir);
--- a/train_cmd.c	Sun Jul 17 19:38:40 2005 +0000
+++ b/train_cmd.c	Sun Jul 17 20:09:02 2005 +0000
@@ -1321,13 +1321,15 @@
 	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 @@
 				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 @@
 		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 @@
 			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 @@
 		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 @@
 								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 @@
 	// 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 @@
 		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;
 			}
 		};
--- a/vehicle.c	Sun Jul 17 19:38:40 2005 +0000
+++ b/vehicle.c	Sun Jul 17 20:09:02 2005 +0000
@@ -1947,8 +1947,10 @@
 	SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,days_since_order_progr), SLE_UINT16, 2, 255),
 
 	SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,pbs_status), SLE_UINT8, 2, 255),
-	// reserve extra space in savegame here. (currently 12 bytes)
-	SLE_CONDARR(NullStruct,null,SLE_FILE_U8 | SLE_VAR_NULL, 12, 2, 255),
+	SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,pbs_end_tile), SLE_UINT32, 2, 255),
+	SLE_CONDVARX(offsetof(Vehicle,u)+offsetof(VehicleRail,pbs_end_trackdir), SLE_UINT8, 2, 255),
+	// reserve extra space in savegame here. (currently 7 bytes)
+	SLE_CONDARR(NullStruct,null,SLE_FILE_U8 | SLE_VAR_NULL, 7, 2, 255),
 
 	SLE_END()
 };
--- a/vehicle.h	Sun Jul 17 19:38:40 2005 +0000
+++ b/vehicle.h	Sun Jul 17 20:09:02 2005 +0000
@@ -70,6 +70,8 @@
 	byte flags;
 
 	byte pbs_status;
+	TileIndex pbs_end_tile;
+	Trackdir pbs_end_trackdir;
 } VehicleRail;
 
 enum {