function Road::_Cost(self, path, new_tile, new_direction) { /* path == null means this is the first node of a path, so the cost is 0. */ if (path == null) return 0; local prev_tile = path.GetTile(); /* If the new tile is a bridge / tunnel tile, check whether we came from the other * end of the bridge / tunnel or if we just entered the bridge / tunnel. */ if (AIBridge.IsBridgeTile(new_tile)) { if (AIBridge.GetOtherBridgeEnd(new_tile) != prev_tile) { /* Check for a turn. We do this by substracting the TileID of the current node from * the TileID of the previous node and comparing that to the difference between the * previous node and the node before that. */ local cost = self._cost_tile; if (path.GetParent() != null && (prev_tile - path.GetParent().GetTile()) != (new_tile - prev_tile) && AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1) { cost += self._cost_turn; } /* Check if the last tile was sloped. */ if (path.GetParent() != null && !AIBridge.IsBridgeTile(prev_tile) && !AITunnel.IsTunnelTile(prev_tile) && AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1 && self._IsSlopedRoad(path.GetParent().GetTile(), prev_tile, new_tile)) { cost += self._cost_slope; } if (!AIRoad.AreRoadTilesConnected(prev_tile, new_tile)) { cost += self._cost_no_existing_road; } return path.GetCost() + cost; } return path.GetCost() + (AIMap.DistanceManhattan(new_tile, prev_tile) + 1) * (self._cost_tile + self._cost_bridge_per_tile) - self._cost_tile + self._GetBridgeNumSlopes(new_tile, prev_tile) * self._cost_slope; } if (AITunnel.IsTunnelTile(new_tile)) { if (AITunnel.GetOtherTunnelEnd(new_tile) != prev_tile) { /* Check for a turn. We do this by substracting the TileID of the current node from * the TileID of the previous node and comparing that to the difference between the * previous node and the node before that. */ local cost = self._cost_tile; if (path.GetParent() != null && (prev_tile - path.GetParent().GetTile()) != (new_tile - prev_tile) && AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1) { cost += self._cost_turn; } /* Check if the last tile was sloped. */ if (path.GetParent() != null && !AIBridge.IsBridgeTile(prev_tile) && !AITunnel.IsTunnelTile(prev_tile) && AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1 && self._IsSlopedRoad(path.GetParent().GetTile(), prev_tile, new_tile)) { cost += self._cost_slope; } if (!AIRoad.AreRoadTilesConnected(prev_tile, new_tile)) { cost += self._cost_no_existing_road; } return path.GetCost() + cost; } return path.GetCost() + (AIMap.DistanceManhattan(new_tile, prev_tile) + 1) * (self._cost_tile + self._cost_tunnel_per_tile) - self._cost_tile; } /* If the two tiles are more than 1 tile apart, the pathfinder wants a bridge or tunnel * to be built. It isn't an existing bridge / tunnel, as that case is already handled. */ if (AIMap.DistanceManhattan(new_tile, prev_tile) > 1) { /* Check if we should build a bridge or a tunnel. */ if (AITunnel.GetOtherTunnelEnd(new_tile) == prev_tile) { return path.GetCost() + (AIMap.DistanceManhattan(new_tile, prev_tile) + 1) * (self._cost_tile + self._cost_tunnel_per_tile + self._cost_no_existing_road) - self._cost_tile; } else { local cost = (AIMap.DistanceManhattan(new_tile, prev_tile) + 1) * (self._cost_tile + self._cost_bridge_per_tile + self._cost_no_existing_road) - self._cost_tile + self._GetBridgeNumSlopes(new_tile, prev_tile) * self._cost_slope; /* Check if the new tile is a coast tile. */ if (AITile.IsCoastTile(new_tile) && AITile.HasTransportType(new_tile, AITile.TRANSPORT_WATER)) { cost += self._cost_coast; } return path.GetCost() + cost; } } /* Check for a turn. We do this by substracting the TileID of the current node from * the TileID of the previous node and comparing that to the difference between the * previous node and the node before that. */ local cost = self._cost_tile; if (path.GetParent() != null && (prev_tile - path.GetParent().GetTile()) != (new_tile - prev_tile) && AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1) { cost += self._cost_turn; } /* Check if the new tile is a coast tile. */ if (AITile.IsCoastTile(new_tile) && AITile.HasTransportType(new_tile, AITile.TRANSPORT_WATER)) { cost += self._cost_coast; } /* Check if the last tile was sloped. */ if (path.GetParent() != null && !AIBridge.IsBridgeTile(prev_tile) && !AITunnel.IsTunnelTile(prev_tile) && AIMap.DistanceManhattan(path.GetParent().GetTile(), prev_tile) == 1 && self._IsSlopedRoad(path.GetParent().GetTile(), prev_tile, new_tile)) { cost += self._cost_slope; } if (!AIRoad.AreRoadTilesConnected(prev_tile, new_tile)) { cost += self._cost_no_existing_road; } return path.GetCost() + cost; }