src/pathfind.cpp
changeset 8894 1e5b2d4380b8
parent 8893 af54cf3065cd
child 8976 1fd3a02c3432
equal deleted inserted replaced
8893:af54cf3065cd 8894:1e5b2d4380b8
    15 #include "tunnel_map.h"
    15 #include "tunnel_map.h"
    16 #include "settings_type.h"
    16 #include "settings_type.h"
    17 #include "depot.h"
    17 #include "depot.h"
    18 #include "tunnelbridge_map.h"
    18 #include "tunnelbridge_map.h"
    19 #include "core/random_func.hpp"
    19 #include "core/random_func.hpp"
       
    20 #include "tunnelbridge.h"
    20 
    21 
    21 /* remember which tiles we have already visited so we don't visit them again. */
    22 /* remember which tiles we have already visited so we don't visit them again. */
    22 static bool TPFSetTileBit(TrackPathFinder *tpf, TileIndex tile, int dir)
    23 static bool TPFSetTileBit(TrackPathFinder *tpf, TileIndex tile, int dir)
    23 {
    24 {
    24 	uint hash, val, offs;
    25 	uint hash, val, offs;
   190 		tpf->rd = rd;
   191 		tpf->rd = rd;
   191 	} while (ClrBit(bits, i) != 0);
   192 	} while (ClrBit(bits, i) != 0);
   192 
   193 
   193 }
   194 }
   194 
   195 
   195 
       
   196 /* Returns the end tile and the length of a tunnel. The length does not
       
   197  * include the starting tile (entry), it does include the end tile (exit).
       
   198  */
       
   199 FindLengthOfTunnelResult FindLengthOfTunnel(TileIndex tile, DiagDirection dir)
       
   200 {
       
   201 	TileIndexDiff delta = TileOffsByDiagDir(dir);
       
   202 	uint z = GetTileZ(tile);
       
   203 	FindLengthOfTunnelResult flotr;
       
   204 
       
   205 	flotr.length = 0;
       
   206 
       
   207 	dir = ReverseDiagDir(dir);
       
   208 	do {
       
   209 		flotr.length++;
       
   210 		tile += delta;
       
   211 	} while(
       
   212 		!IsTunnelTile(tile) ||
       
   213 		GetTunnelBridgeDirection(tile) != dir ||
       
   214 		GetTileZ(tile) != z
       
   215 	);
       
   216 
       
   217 	flotr.tile = tile;
       
   218 	return flotr;
       
   219 }
       
   220 
       
   221 /**
   196 /**
   222  * Checks if any vehicle can enter/leave tile in given diagdir
   197  * Checks if any vehicle can enter/leave tile in given diagdir
   223  * Checks only for rail/road depots and road non-drivethrough stations
   198  * Checks only for rail/road depots and road non-drivethrough stations
   224  * @param tile tile to check
   199  * @param tile tile to check
   225  * @param side side of tile we are trying to leave/enter
   200  * @param side side of tile we are trying to leave/enter
   255 		DiagDirection dir = GetTunnelBridgeDirection(tile);
   230 		DiagDirection dir = GetTunnelBridgeDirection(tile);
   256 		/* entering tunnel / bridge? */
   231 		/* entering tunnel / bridge? */
   257 		if (dir == direction) {
   232 		if (dir == direction) {
   258 			TileIndex endtile = GetOtherTunnelBridgeEnd(tile);
   233 			TileIndex endtile = GetOtherTunnelBridgeEnd(tile);
   259 
   234 
   260 			tpf->rd.cur_length += DistanceManhattan(tile, endtile);
   235 			tpf->rd.cur_length += GetTunnelBridgeLength(tile, endtile) + 1;
   261 
   236 
   262 			TPFSetTileBit(tpf, tile, 14);
   237 			TPFSetTileBit(tpf, tile, 14);
   263 			TPFSetTileBit(tpf, endtile, 14);
   238 			TPFSetTileBit(tpf, endtile, 14);
   264 
   239 
   265 			tile = endtile;
   240 			tile = endtile;
   663 		/* If the tile is the entry tile of a tunnel, and we're not going out of the tunnel,
   638 		/* If the tile is the entry tile of a tunnel, and we're not going out of the tunnel,
   664 		 *   need to find the exit of the tunnel. */
   639 		 *   need to find the exit of the tunnel. */
   665 		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
   640 		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
   666 			if (IsTunnel(tile)) {
   641 			if (IsTunnel(tile)) {
   667 				if (GetTunnelBridgeDirection(tile) != ReverseDiagDir(direction)) {
   642 				if (GetTunnelBridgeDirection(tile) != ReverseDiagDir(direction)) {
   668 					FindLengthOfTunnelResult flotr;
       
   669 
       
   670 					/* We are not just driving out of the tunnel */
   643 					/* We are not just driving out of the tunnel */
   671 					if (GetTunnelBridgeDirection(tile) != direction ||
   644 					if (GetTunnelBridgeDirection(tile) != direction ||
   672 							GetTunnelBridgeTransportType(tile) != tpf->tracktype) {
   645 							GetTunnelBridgeTransportType(tile) != tpf->tracktype) {
   673 						/* We are not driving into the tunnel, or it is an invalid tunnel */
   646 						/* We are not driving into the tunnel, or it is an invalid tunnel */
   674 						continue;
   647 						continue;
   675 					}
   648 					}
   676 					if (!HasBit(tpf->railtypes, GetRailType(tile))) {
   649 					if (!HasBit(tpf->railtypes, GetRailType(tile))) {
   677 						bits = TRACK_BIT_NONE;
   650 						bits = TRACK_BIT_NONE;
   678 						break;
   651 						break;
   679 					}
   652 					}
   680 					flotr = FindLengthOfTunnel(tile, direction);
   653 
   681 					si.cur_length += flotr.length * DIAG_FACTOR;
   654 					TileIndex endtile = GetOtherTunnelEnd(tile);
   682 					tile = flotr.tile;
   655 					si.cur_length += DIAG_FACTOR * (GetTunnelBridgeLength(tile, endtile) + 1);
       
   656 					tile = endtile;
   683 					/* tile now points to the exit tile of the tunnel */
   657 					/* tile now points to the exit tile of the tunnel */
   684 				}
   658 				}
   685 			} else { // IsBridge(tile)
   659 			} else { // IsBridge(tile)
   686 				TileIndex tile_end;
   660 				TileIndex tile_end;
   687 				if (GetTunnelBridgeDirection(tile) != ReverseDiagDir(direction)) {
   661 				if (GetTunnelBridgeDirection(tile) != ReverseDiagDir(direction)) {
   691 						/* Not entering the bridge or not compatible */
   665 						/* Not entering the bridge or not compatible */
   692 						continue;
   666 						continue;
   693 					}
   667 					}
   694 				}
   668 				}
   695 				tile_end = GetOtherBridgeEnd(tile);
   669 				tile_end = GetOtherBridgeEnd(tile);
   696 				si.cur_length += DistanceManhattan(tile, tile_end) * DIAG_FACTOR;
   670 				si.cur_length += DIAG_FACTOR * (GetTunnelBridgeLength(tile, tile_end) + 1);
   697 				tile = tile_end;
   671 				tile = tile_end;
   698 			}
   672 			}
   699 		}
   673 		}
   700 
   674 
   701 		/* This is a special loop used to go through
   675 		/* This is a special loop used to go through