diff --git a/src/road.cpp b/src/road.cpp index 4e0b99a384..5af3dea7c8 100644 --- a/src/road.cpp +++ b/src/road.cpp @@ -538,34 +538,34 @@ static bool IsValidNeighbourOfPreviousTile(const TileIndex tile, const TileIndex { if (!IsValidTile(tile) || (tile == previous_tile)) return false; + const auto forward_direction = DiagdirBetweenTiles(previous_tile, tile); + if (IsTileType(tile, MP_TUNNELBRIDGE)) { if (GetOtherTunnelBridgeEnd(tile) == previous_tile) return true; const auto tunnel_direction = GetTunnelBridgeDirection(tile); - if (previous_tile + TileOffsByDiagDir(tunnel_direction) != tile) return false; - } else { + return (tunnel_direction == forward_direction); + } - if (!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES) && !IsTileType(tile, MP_ROAD)) return false; + if (!IsTileType(tile, MP_CLEAR) && !IsTileType(tile, MP_TREES) && !IsTileType(tile, MP_ROAD)) return false; - const auto slope = GetTileSlope(tile); + const auto slope = GetTileSlope(tile); - // Do not allow foundations. We'll mess things up later. - const bool has_foundation = GetFoundationSlope(tile) != slope; + // Do not allow foundations. We'll mess things up later. + const bool has_foundation = GetFoundationSlope(tile) != slope; - if (has_foundation) return false; + if (has_foundation) return false; - if (IsInclinedSlope(slope)) { - const auto slope_direction = GetInclinedSlopeDirection(slope); - const auto road_direction = DiagdirBetweenTiles(previous_tile, tile); + if (IsInclinedSlope(slope)) { + const auto slope_direction = GetInclinedSlopeDirection(slope); - if (slope_direction != road_direction && ReverseDiagDir(slope_direction) != road_direction) { - return false; - } - } else if (slope != SLOPE_FLAT) { + if (slope_direction != forward_direction && ReverseDiagDir(slope_direction) != forward_direction) { return false; } + } else if (slope != SLOPE_FLAT) { + return false; } return true; @@ -654,58 +654,22 @@ static void PublicRoad_GetNeighbours(AyStar *aystar, OpenListNode *current) aystar->num_neighbours = 0; // Check if we just went through a tunnel or a bridge. - if (previous_tile != INVALID_TILE && !AreTilesAdjacent(current_tile, previous_tile)) { + if (IsValidTile(previous_tile) && !AreTilesAdjacent(current_tile, previous_tile)) { // We went through a tunnel or bridge, this limits our options to proceed to only forward. - const TileIndex tunnel_bridge_end = current_tile + TileOffsByDiagDir(forward_direction); + const TileIndex next_tile = current_tile + TileOffsByDiagDir(forward_direction); - if (IsValidNeighbourOfPreviousTile(tunnel_bridge_end, current_tile)) { - aystar->neighbours[aystar->num_neighbours].tile = tunnel_bridge_end; + if (IsValidNeighbourOfPreviousTile(next_tile, current_tile)) { + aystar->neighbours[aystar->num_neighbours].tile = next_tile; aystar->neighbours[aystar->num_neighbours].direction = INVALID_TRACKDIR; aystar->num_neighbours++; } } else if (IsTileType(current_tile, MP_TUNNELBRIDGE)) { // Handle existing tunnels and bridges const auto tunnel_bridge_end = GetOtherTunnelBridgeEnd(current_tile); - const auto tunnel_bridge_direction = DiagdirBetweenTiles(current_tile, tunnel_bridge_end); - - // Thanks to custom bridge heads we can come towards a bridge from anywhere but the reverse direction. - if (forward_direction == ReverseDiagDir(tunnel_bridge_direction)) { - return; - } - - // For tunnels we need to come directly towards the tunnel though. - if (IsTunnel(current_tile) && forward_direction != tunnel_bridge_direction) { - return; - } - aystar->neighbours[aystar->num_neighbours].tile = tunnel_bridge_end; aystar->neighbours[aystar->num_neighbours].direction = INVALID_TRACKDIR; aystar->num_neighbours++; - - // Handle regular neighbors for bridges thanks to custom bridge heads. - if (IsBridge(current_tile)) { - for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) { - if (d == tunnel_bridge_direction) { - // We already added this direction. - // The direct neighbor in that direction makes no sense for a bridge. - continue; - } - - const auto neighbour = current_tile + TileOffsByDiagDir(d); - - if (neighbour == previous_tile) { - // That's where we came from. - continue; - } - - if (IsValidNeighbourOfPreviousTile(neighbour, current_tile)) { - aystar->neighbours[aystar->num_neighbours].tile = neighbour; - aystar->neighbours[aystar->num_neighbours].direction = INVALID_TRACKDIR; - aystar->num_neighbours++; - } - } - } } else { // Handle regular neighbors. for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) { @@ -723,11 +687,11 @@ static void PublicRoad_GetNeighbours(AyStar *aystar, OpenListNode *current) } // Check if we can turn this into a tunnel or a bridge. - if (current->path.parent != nullptr) { + if (IsValidTile(previous_tile)) { if (IsUpwardsSlope(current_tile, forward_direction)) { const auto tunnel_end = BuildTunnel(¤t->path); - if (tunnel_end != INVALID_TILE && + if (IsValidTile(tunnel_end) && !IsBlockedByPreviousBridgeOrTunnel(current, current_tile, tunnel_end) && !IsSteepSlope(GetTileSlope(tunnel_end)) && !IsHalftileSlope(GetTileSlope(tunnel_end)) && @@ -741,7 +705,7 @@ static void PublicRoad_GetNeighbours(AyStar *aystar, OpenListNode *current) else if (IsDownwardsSlope(current_tile, forward_direction)) { const auto bridge_end = BuildBridge(¤t->path, forward_direction); - if (bridge_end != INVALID_TILE && + if (IsValidTile(bridge_end) && !IsBlockedByPreviousBridgeOrTunnel(current, current_tile, bridge_end) && !IsSteepSlope(GetTileSlope(bridge_end)) && !IsHalftileSlope(GetTileSlope(bridge_end)) && @@ -756,9 +720,9 @@ static void PublicRoad_GetNeighbours(AyStar *aystar, OpenListNode *current) { // Check if we could bridge a river from a flat tile. Not looking pretty on the map but you gotta do what you gotta do. const auto bridge_end = BuildRiverBridge(¤t->path, forward_direction); - assert(bridge_end == INVALID_TILE || GetTileSlope(bridge_end) == SLOPE_FLAT); + assert(IsValidTile(bridge_end) || GetTileSlope(bridge_end) == SLOPE_FLAT); - if (bridge_end != INVALID_TILE && + if (IsValidTile(bridge_end) && !IsBlockedByPreviousBridgeOrTunnel(current, current_tile, bridge_end)) { assert(IsValidDiagDirection(DiagdirBetweenTiles(current_tile, bridge_end))); aystar->neighbours[aystar->num_neighbours].tile = bridge_end;