(svn r6791) -Fix: [YAPF] YapfFindNearestRailDepotTwoWay() did not work for train inside tunnel.
authorKUDr
Mon, 16 Oct 2006 19:17:30 +0000
changeset 4865 cad5fa7ec427
parent 4864 b2d39953a590
child 4866 d8c5cb502c0d
(svn r6791) -Fix: [YAPF] YapfFindNearestRailDepotTwoWay() did not work for train inside tunnel.
yapf/yapf_rail.cpp
--- a/yapf/yapf_rail.cpp	Mon Oct 16 11:46:47 2006 +0000
+++ b/yapf/yapf_rail.cpp	Mon Oct 16 19:17:30 2006 +0000
@@ -239,6 +239,8 @@
 	return reverse;
 }
 
+static TileIndex YapfGetVehicleOutOfTunnelTile(const Vehicle *v, bool bReverse);
+
 bool YapfFindNearestRailDepotTwoWay(Vehicle *v, int max_distance, int reverse_penalty, TileIndex* depot_tile, bool* reversed)
 {
 	*depot_tile = INVALID_TILE;
@@ -250,12 +252,12 @@
 	bool last_in_tunnel = last_veh->u.rail.track == 0x40;
 
 	// tile where the engine and last wagon are
-	TileIndex tile = first_in_tunnel ? INVALID_TILE : v->tile;
-	TileIndex last_tile = last_in_tunnel ? INVALID_TILE : last_veh->tile;
+	TileIndex tile = first_in_tunnel ? YapfGetVehicleOutOfTunnelTile(v, false) : v->tile;
+	TileIndex last_tile = last_in_tunnel ? YapfGetVehicleOutOfTunnelTile(last_veh, true) : last_veh->tile;
 
 	// their trackdirs
-	Trackdir td = first_in_tunnel ? INVALID_TRACKDIR : GetVehicleTrackdir(v);
-	Trackdir td_rev = last_in_tunnel ? INVALID_TRACKDIR : ReverseTrackdir(GetVehicleTrackdir(last_veh));
+	Trackdir td = GetVehicleTrackdir(v);
+	Trackdir td_rev = ReverseTrackdir(GetVehicleTrackdir(last_veh));
 
 	typedef bool (*PfnFindNearestDepotTwoWay)(Vehicle*, TileIndex, Trackdir, TileIndex, Trackdir, int, int, TileIndex*, bool*);
 	PfnFindNearestDepotTwoWay pfnFindNearestDepotTwoWay = &CYapfAnyDepotRail2::stFindNearestDepotTwoWay;
@@ -270,6 +272,38 @@
 	return ret;
 }
 
+/** Retrieve the exit-tile of the vehicle from inside a tunnel
+* Very similar to GetOtherTunnelEnd(), but we use the vehicle's
+* direction for determining which end of the tunnel to find
+* @param v the vehicle which is inside the tunnel and needs an exit
+* @param bReverse should we search for the tunnel exit in the opposite direction?
+* @return the exit-tile of the tunnel based on the vehicle's direction
+* taken from tunnelbridge_cmd.c where the function body was disabled by
+* #if 1 #else #endif (at r5951). Added bReverse argument to allow two-way
+* operation (YapfFindNearestRailDepotTwoWay).                              */
+static TileIndex YapfGetVehicleOutOfTunnelTile(const Vehicle *v, bool bReverse)
+{
+	TileIndex tile = v->tile;
+	DiagDirection dir = DirToDiagDir((Direction)v->direction);
+	TileIndexDiff delta = TileOffsByDiagDir(dir);
+	byte z = v->z_pos;
+
+	if (bReverse) {
+		delta = -delta;
+	} else {
+		dir = ReverseDiagDir(dir);
+	}
+	while (
+		!IsTunnelTile(tile) ||
+		GetTunnelDirection(tile) != dir ||
+		GetTileZ(tile) != z
+		) {
+			tile += delta;
+	}
+	return tile;
+}
+
+
 /** if any track changes, this counter is incremented - that will invalidate segment cost cache */
 int CSegmentCostCacheBase::s_rail_change_counter = 0;