@@ -197,96 +197,114 @@ continue_here:
* include the starting tile (entry), it does include the end tile (exit).
*/
FindLengthOfTunnelResult FindLengthOfTunnel(TileIndex tile, DiagDirection dir)
{
TileIndexDiff delta = TileOffsByDiagDir(dir);
uint z = GetTileZ(tile);
FindLengthOfTunnelResult flotr;
flotr.length = 0;
dir = ReverseDiagDir(dir);
do {
flotr.length++;
tile += delta;
} while(
!IsTunnelTile(tile) ||
GetTunnelBridgeDirection(tile) != dir ||
GetTileZ(tile) != z
);
flotr.tile = tile;
return flotr;
}
/**
* Checks if any vehicle can enter/leave tile in given diagdir
* Checks only for rail/road depots and road non-drivethrough stations
* @param tile tile to check
* @param side side of tile we are trying to leave/enter
* @param tracktype type of transport
* @pre tile has trackbit at that diagdir
* @return true iff vehicle can enter/leve the tile in given side
static inline bool CanAccessTileInDir(TileIndex tile, DiagDirection side, TransportType tracktype)
if (tracktype == TRANSPORT_RAIL) {
/* depot from wrong side */
if (IsTileDepotType(tile, TRANSPORT_RAIL) && GetRailDepotDirection(tile) != side) return false;
} else if (tracktype == TRANSPORT_ROAD) {
if (IsTileDepotType(tile, TRANSPORT_ROAD) && GetRoadDepotDirection(tile) != side) return false;
/* non-driverthrough road station from wrong side */
if (IsStandardRoadStopTile(tile) && GetRoadStopDir(tile) != side) return false;
return true;
static const uint16 _tpfmode1_and[4] = { 0x1009, 0x16, 0x520, 0x2A00 };
static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
const TileIndex tile_org = tile;
if (IsTileType(tile, MP_TUNNELBRIDGE)) {
/* wrong track type */
if (GetTunnelBridgeTransportType(tile) != tpf->tracktype) return;
DiagDirection dir = GetTunnelBridgeDirection(tile);
/* entering tunnel / bridge? */
if (dir == direction) {
TileIndex endtile = GetOtherTunnelBridgeEnd(tile);
tpf->rd.cur_length += DistanceManhattan(tile, endtile);
TPFSetTileBit(tpf, tile, 14);
TPFSetTileBit(tpf, endtile, 14);
tile = endtile;
} else {
/* leaving tunnel / bridge? */
if (ReverseDiagDir(dir) != direction) return;
/* can we leave tile in this dir? */
if (!CanAccessTileInDir(tile, direction, tpf->tracktype)) return;
tile += TileOffsByDiagDir(direction);
/* can we enter tile in this dir? */
if (!CanAccessTileInDir(tile, ReverseDiagDir(direction), tpf->tracktype)) return;
/* Check in case of rail if the owner is the same */
if (tpf->tracktype == TRANSPORT_RAIL) {
/* don't enter train depot from the back */
if (IsTileDepotType(tile, TRANSPORT_RAIL) && GetRailDepotDirection(tile) == direction) return;
if (IsTileType(tile_org, MP_RAILWAY) || IsTileType(tile_org, MP_STATION) || IsTileType(tile_org, MP_TUNNELBRIDGE))
if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
if (GetTileOwner(tile_org) != GetTileOwner(tile)) return;
/* check if the new tile can be entered from that direction */
if (tpf->tracktype == TRANSPORT_ROAD) {
/* road stops and depots now have a track (r4419)
* don't enter road stop from the back */
if (IsStandardRoadStopTile(tile) && ReverseDiagDir(GetRoadStopDir(tile)) != direction) return;
/* don't enter road depot from the back */
if (IsTileDepotType(tile, TRANSPORT_ROAD) && ReverseDiagDir(GetRoadDepotDirection(tile)) != direction) return;
/* Check if the new tile is a tunnel or bridge head and that the direction
* and transport type match */
if (GetTunnelBridgeDirection(tile) != direction ||
GetTunnelBridgeTransportType(tile) != tpf->tracktype) {
return;
tpf->rd.cur_length++;
uint bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
if ((byte)bits != tpf->var2) {
bits &= _tpfmode1_and[direction];
bits |= bits >> 8;
bits &= 0xBF;
if (bits != 0) {
if (!tpf->disable_tile_hash || (tpf->rd.cur_length <= 64 && (KillFirstBit(bits) == 0 || ++tpf->rd.depth <= 7))) {
int i = FIND_FIRST_BIT(bits);
bits = KillFirstBit(bits);
Status change: