function Road::_Neighbours(self, path, cur_node) { (...) bla bla (…) local bridges = self._GetTunnelsBridgesEfficient(path.GetParent().GetTile(), cur_node, self._GetDirectionEfficient(path.GetParent().GetTile(), cur_node, true) << 4); foreach (tile in bridges) { tiles.push(tile); } return tiles; } /** * Get a list of all bridges and tunnels that can be built from the * current tile. Tunnels will only be built if no terraforming * is needed on both ends. */ function Road::_GetTunnelsBridgesEfficient(last_node, cur_node, bridge_dir, _AIBridge = AIBridge, _AITile = AITile, _AIMap = AIMap, _AITunnel = AITunnel, _AIVehicle = AIVehicle) { local tiles = []; for (local i = 2; i < this._max_bridge_length;) { local target = cur_node + i * (cur_node - last_node); local bridge_list = AIBridgeList_Length(++i); if (!bridge_list.IsEmpty() && _AIBridge.BuildBridge(_AIVehicle.VT_ROAD, bridge_list.Begin(), cur_node, target)) { tiles.push([target, bridge_dir]); } } local slope = _AITile.GetSlope(cur_node); if (slope != _AITile.SLOPE_SW && slope != _AITile.SLOPE_NW && slope != _AITile.SLOPE_SE && slope != _AITile.SLOPE_NE) return tiles; local other_tunnel_end = _AITunnel.GetOtherTunnelEnd(cur_node); if (!_AIMap.IsValidTile(other_tunnel_end)) return tiles; local tunnel_length = _AIMap.DistanceManhattan(cur_node, other_tunnel_end); if (_AITunnel.GetOtherTunnelEnd(other_tunnel_end) == cur_node && tunnel_length >= 2 && cur_node + (cur_node - other_tunnel_end) / tunnel_length == last_node && tunnel_length < _max_tunnel_length && _AITunnel.BuildTunnel(_AIVehicle.VT_ROAD, cur_node)) { tiles.push([other_tunnel_end, bridge_dir]); } return tiles; }