mirror of https://github.com/OpenTTD/OpenTTD
Fix: AirportGetNearestTown incorrectly assumed first TileIterator result was origin. (#11565)
Not all TileIterators are equal, and some do not start at the top-corner, so the perimeter check was wrong. As the caller already has thie origin tile, use that instead.pull/11545/head
parent
10f94fb0dd
commit
c0ea0589b4
|
@ -139,7 +139,7 @@
|
||||||
if (_settings_game.economy.station_noise_level) {
|
if (_settings_game.economy.station_noise_level) {
|
||||||
AirportTileTableIterator it(as->table[0], tile);
|
AirportTileTableIterator it(as->table[0], tile);
|
||||||
uint dist;
|
uint dist;
|
||||||
AirportGetNearestTown(as, it, dist);
|
AirportGetNearestTown(as, tile, it, dist);
|
||||||
return GetAirportNoiseLevelForDistance(as, dist);
|
return GetAirportNoiseLevelForDistance(as, dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@
|
||||||
if (!as->IsWithinMapBounds(0, tile)) return INVALID_TOWN;
|
if (!as->IsWithinMapBounds(0, tile)) return INVALID_TOWN;
|
||||||
|
|
||||||
uint dist;
|
uint dist;
|
||||||
return AirportGetNearestTown(as, AirportTileTableIterator(as->table[0], tile), dist)->index;
|
return AirportGetNearestTown(as, tile, AirportTileTableIterator(as->table[0], tile), dist)->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ SQInteger ScriptAirport::GetMaintenanceCostFactor(AirportType type)
|
/* static */ SQInteger ScriptAirport::GetMaintenanceCostFactor(AirportType type)
|
||||||
|
|
|
@ -2303,18 +2303,19 @@ uint8_t GetAirportNoiseLevelForDistance(const AirportSpec *as, uint distance)
|
||||||
* Finds the town nearest to given airport. Based on minimal manhattan distance to any airport's tile.
|
* 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.
|
* If two towns have the same distance, town with lower index is returned.
|
||||||
* @param as airport's description
|
* @param as airport's description
|
||||||
|
* @param tile origin tile (top corner of the airport)
|
||||||
* @param it An iterator over all airport tiles
|
* @param it An iterator over all airport tiles
|
||||||
* @param[out] mindist Minimum distance to town
|
* @param[out] mindist Minimum distance to town
|
||||||
* @return nearest town to airport
|
* @return nearest town to airport
|
||||||
*/
|
*/
|
||||||
Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it, uint &mindist)
|
Town *AirportGetNearestTown(const AirportSpec *as, TileIndex tile, const TileIterator &it, uint &mindist)
|
||||||
{
|
{
|
||||||
assert(Town::GetNumItems() > 0);
|
assert(Town::GetNumItems() > 0);
|
||||||
|
|
||||||
Town *nearest = nullptr;
|
Town *nearest = nullptr;
|
||||||
|
|
||||||
uint perimeter_min_x = TileX(it);
|
uint perimeter_min_x = TileX(tile);
|
||||||
uint perimeter_min_y = TileY(it);
|
uint perimeter_min_y = TileY(tile);
|
||||||
uint perimeter_max_x = perimeter_min_x + as->size_x - 1;
|
uint perimeter_max_x = perimeter_min_x + as->size_x - 1;
|
||||||
uint perimeter_max_y = perimeter_min_y + as->size_y - 1;
|
uint perimeter_max_y = perimeter_min_y + as->size_y - 1;
|
||||||
|
|
||||||
|
@ -2322,6 +2323,8 @@ Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it, uint
|
||||||
|
|
||||||
std::unique_ptr<TileIterator> copy(it.Clone());
|
std::unique_ptr<TileIterator> copy(it.Clone());
|
||||||
for (TileIndex cur_tile = *copy; cur_tile != INVALID_TILE; cur_tile = ++*copy) {
|
for (TileIndex cur_tile = *copy; cur_tile != INVALID_TILE; cur_tile = ++*copy) {
|
||||||
|
assert(IsInsideBS(TileX(cur_tile), perimeter_min_x, as->size_x));
|
||||||
|
assert(IsInsideBS(TileY(cur_tile), perimeter_min_y, as->size_y));
|
||||||
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) {
|
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) {
|
||||||
Town *t = CalcClosestTownFromTile(cur_tile, mindist + 1);
|
Town *t = CalcClosestTownFromTile(cur_tile, mindist + 1);
|
||||||
if (t == nullptr) continue;
|
if (t == nullptr) continue;
|
||||||
|
@ -2349,7 +2352,7 @@ void UpdateAirportsNoise()
|
||||||
const AirportSpec *as = st->airport.GetSpec();
|
const AirportSpec *as = st->airport.GetSpec();
|
||||||
AirportTileIterator it(st);
|
AirportTileIterator it(st);
|
||||||
uint dist;
|
uint dist;
|
||||||
Town *nearest = AirportGetNearestTown(as, it, dist);
|
Town *nearest = AirportGetNearestTown(as, st->airport.tile, it, dist);
|
||||||
nearest->noise_reached += GetAirportNoiseLevelForDistance(as, dist);
|
nearest->noise_reached += GetAirportNoiseLevelForDistance(as, dist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2399,7 +2402,7 @@ CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_ty
|
||||||
|
|
||||||
/* The noise level is the noise from the airport and reduce it to account for the distance to the town center. */
|
/* The noise level is the noise from the airport and reduce it to account for the distance to the town center. */
|
||||||
uint dist;
|
uint dist;
|
||||||
Town *nearest = AirportGetNearestTown(as, tile_iter, dist);
|
Town *nearest = AirportGetNearestTown(as, tile, tile_iter, dist);
|
||||||
uint newnoise_level = GetAirportNoiseLevelForDistance(as, dist);
|
uint newnoise_level = GetAirportNoiseLevelForDistance(as, dist);
|
||||||
|
|
||||||
/* Check if local auth would allow a new airport */
|
/* Check if local auth would allow a new airport */
|
||||||
|
@ -2527,7 +2530,7 @@ static CommandCost RemoveAirport(TileIndex tile, DoCommandFlag flags)
|
||||||
* need of recalculation */
|
* need of recalculation */
|
||||||
AirportTileIterator it(st);
|
AirportTileIterator it(st);
|
||||||
uint dist;
|
uint dist;
|
||||||
Town *nearest = AirportGetNearestTown(as, it, dist);
|
Town *nearest = AirportGetNearestTown(as, st->airport.tile, it, dist);
|
||||||
nearest->noise_reached -= GetAirportNoiseLevelForDistance(as, dist);
|
nearest->noise_reached -= GetAirportNoiseLevelForDistance(as, dist);
|
||||||
|
|
||||||
if (_settings_game.economy.station_noise_level) {
|
if (_settings_game.economy.station_noise_level) {
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
enum StationClassID : byte;
|
enum StationClassID : byte;
|
||||||
enum RoadStopClassID : byte;
|
enum RoadStopClassID : byte;
|
||||||
|
|
||||||
extern Town *AirportGetNearestTown(const struct AirportSpec *as, const TileIterator &it, uint &mindist);
|
extern Town *AirportGetNearestTown(const struct AirportSpec *as, TileIndex tile, const TileIterator &it, uint &mindist);
|
||||||
extern uint8_t GetAirportNoiseLevelForDistance(const struct AirportSpec *as, uint distance);
|
extern uint8_t GetAirportNoiseLevelForDistance(const struct AirportSpec *as, uint distance);
|
||||||
|
|
||||||
CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_type, byte layout, StationID station_to_join, bool allow_adjacent);
|
CommandCost CmdBuildAirport(DoCommandFlag flags, TileIndex tile, byte airport_type, byte layout, StationID station_to_join, bool allow_adjacent);
|
||||||
|
|
Loading…
Reference in New Issue