* Finds the town nearest to given airport. Based on minimal manhattan distance to any airport's tile. * If two towns have the same distance, town with lower index is returned. * @param as airport's description * @param rotation airport's rotation * @param tile origin tile (top corner of the airport) * @param it An iterator over all airport tiles (consumed) * @param[out] mindist Minimum dista
| 2552 | * @return nearest town to airport |
| 2553 | */ |
| 2554 | Town *AirportGetNearestTown(const AirportSpec *as, Direction rotation, TileIndex tile, TileIterator &&it, uint &mindist) |
| 2555 | { |
| 2556 | assert(Town::GetNumItems() > 0); |
| 2557 | |
| 2558 | Town *nearest = nullptr; |
| 2559 | |
| 2560 | auto width = as->size_x; |
| 2561 | auto height = as->size_y; |
| 2562 | if (rotation == DIR_E || rotation == DIR_W) std::swap(width, height); |
| 2563 | |
| 2564 | uint perimeter_min_x = TileX(tile); |
| 2565 | uint perimeter_min_y = TileY(tile); |
| 2566 | uint perimeter_max_x = perimeter_min_x + width - 1; |
| 2567 | uint perimeter_max_y = perimeter_min_y + height - 1; |
| 2568 | |
| 2569 | mindist = UINT_MAX - 1; // prevent overflow |
| 2570 | |
| 2571 | for (TileIndex cur_tile = *it; cur_tile != INVALID_TILE; cur_tile = ++it) { |
| 2572 | assert(IsInsideBS(TileX(cur_tile), perimeter_min_x, width)); |
| 2573 | assert(IsInsideBS(TileY(cur_tile), perimeter_min_y, height)); |
| 2574 | if (TileX(cur_tile) == perimeter_min_x || TileX(cur_tile) == perimeter_max_x || TileY(cur_tile) == perimeter_min_y || TileY(cur_tile) == perimeter_max_y) { |
| 2575 | Town *t = CalcClosestTownFromTile(cur_tile, mindist + 1); |
| 2576 | if (t == nullptr) continue; |
| 2577 | |
| 2578 | uint dist = DistanceManhattan(t->xy, cur_tile); |
| 2579 | if (dist == mindist && t->index < nearest->index) nearest = t; |
| 2580 | if (dist < mindist) { |
| 2581 | nearest = t; |
| 2582 | mindist = dist; |
| 2583 | } |
| 2584 | } |
| 2585 | } |
| 2586 | |
| 2587 | return nearest; |
| 2588 | } |
| 2589 | |
| 2590 | /** |
| 2591 | * Finds the town nearest to given existing airport. Based on minimal manhattan distance to any airport's tile. |
no test coverage detected