(svn r7755) [cbh] - Fix: [NTP] now works with cbh (needs testing) custombridgeheads
authorKUDr
Tue, 02 Jan 2007 18:40:37 +0000
branchcustombridgeheads
changeset 5641 d4d00a16ef26
parent 5640 ccd487181ed5
child 5642 bfa6074e2833
(svn r7755) [cbh] - Fix: [NTP] now works with cbh (needs testing)
pathfind.c
--- a/pathfind.c	Tue Jan 02 16:43:05 2007 +0000
+++ b/pathfind.c	Tue Jan 02 18:40:37 2007 +0000
@@ -725,50 +725,59 @@
 		direction = _tpf_new_direction[si.track];
 
 start_at:
-		// If the tile is the entry tile of a tunnel, and we're not going out of the tunnel,
-		//   need to find the exit of the tunnel.
-		if (IsTileType(tile, MP_TUNNEL)) {
-			if (GetTunnelDirection(tile) != ReverseDiagDir(direction)) {
-				FindLengthOfTunnelResult flotr;
-
-				/* We are not just driving out of the tunnel */
-				if (GetTunnelDirection(tile) != direction ||
-						GetTunnelTransportType(tile) != tpf->tracktype) {
-					// We are not driving into the tunnel, or it is an invalid tunnel
-					continue;
-				}
-				if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
-					bits = 0;
-					break;
-				}
-				flotr = FindLengthOfTunnel(tile, direction);
-				si.cur_length += flotr.length * DIAG_FACTOR;
-				tile = flotr.tile;
-				// tile now points to the exit tile of the tunnel
-			}
-		}
-
-		if (IsTileType(tile, MP_STREET_BRIDGE) || IsTileType(tile, MP_RAILWAY_BRIDGE)) {
-			TileIndex tile_end;
-			if (GetBridgeRampDirection(tile) != ReverseDiagDir(direction)) {
-				// We are not just leaving the bridge
-				if (GetBridgeRampDirection(tile) != direction ||
-						GetBridgeTransportType(tile) != tpf->tracktype) {
-					// Not entering the bridge or not compatible
-					continue;
-				}
-			}
-			tile_end = GetOtherBridgeEnd(tile);
-			si.cur_length += DistanceManhattan(tile, tile_end) * DIAG_FACTOR;
-			tile = tile_end;
-		}
-
 		// This is a special loop used to go through
 		// a rail net and find the first intersection
 		tile_org = tile;
 		for (;;) {
+			uint16 warp_length;
 			assert(direction <= 3);
-			tile += TileOffsByDiagDir(direction);
+			// move 'tile' forward in our 'direction'
+			// tunnel/bridge can move us more than by just one tile forward if it is in our direction
+			if (IsTileType(tile, MP_RAILWAY_BRIDGE) && GetBridgeRampDirection(tile) == direction) {
+				// entering bridge ramp
+				TileIndex end_tile;
+				if (GetBridgeTransportType(tile) != tpf->tracktype) {
+					// wrong track type
+					bits = 0;
+					break;
+				}
+				// pass the bridge wormhole
+				end_tile = GetOtherBridgeEnd(tile);
+				warp_length = DistanceManhattan(tile, end_tile) * DIAG_FACTOR;
+				tile = end_tile;
+			} else if (IsTileType(tile, MP_TUNNEL) && GetTunnelDirection(tile) == direction) {
+				// entering tunnel
+				FindLengthOfTunnelResult flotr;
+				if (GetTunnelTransportType(tile) != tpf->tracktype) {
+					// wrong track type
+					bits = 0;
+					break;
+				}
+				// pass the tunnel wormhole
+				flotr = FindLengthOfTunnel(tile, direction);
+				warp_length = flotr.length * DIAG_FACTOR;
+				tile = flotr.tile;
+			} else {
+				// not a tunnel/bridge, move just one tile forward
+				tile += TileOffsByDiagDir(direction);
+				warp_length = 0;
+				// disable entering bridge from under-bridge track
+				if (IsTileType(tile, MP_RAILWAY_BRIDGE)) {
+					// it is allowed only when we are just at the start of pathfinding (si.first_track == 0xFF)
+					if (GetBridgeRampDirection(tile) == ReverseDiagDir(direction) && si.first_track != 0xFF) {
+						// entered bridge ramp from its back
+						bits = 0;
+						break;
+					}
+				} else if (IsTileType(tile, MP_TUNNEL)) {
+					// disable entering tunnel from regular track in the opposite direction
+					if (GetTunnelDirection(tile) == ReverseDiagDir(direction)) {
+						// entered tunnel from its back
+						bits = 0;
+						break;
+					}
+				}
+			}
 
 			// too long search length? bail out.
 			if (si.cur_length >= tpf->maxlength) {
@@ -779,8 +788,8 @@
 
 			// Not a regular rail tile?
 			// Then we can't use the code below, but revert to more general code.
-			if (!IsTileType(tile, MP_RAILWAY) || !IsPlainRailTile(tile)) {
-				// We found a tile which is not a normal railway tile.
+			if (!(IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_RAILWAY_BRIDGE)) || !IsPlainRailTile(tile)) {
+				// We found a tile which is not a normal railway tile or bridge ramp (cbh behaves as normal railway).
 				// Determine which tracks that exist on this tile.
 				bits = GetTileTrackStatus(tile, TRANSPORT_RAIL) & _tpfmode1_and[direction];
 				bits = (bits | (bits >> 8)) & 0x3F;
@@ -825,7 +834,7 @@
 			track = _new_track[FIND_FIRST_BIT(bits)][direction];
 			assert(track != 0xff);
 
-			si.cur_length += _length_of_track[track];
+			si.cur_length += _length_of_track[track] + warp_length;
 
 			// Check if this rail is an upwards slope. If it is, then add a penalty.
 			// Small optimization here.. if (track&7)>1 then it can't be a slope so we avoid calling GetTileSlope