mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 14:27:16 +00:00
(svn r23441) -Fix [FS#4764]: some airport functions didn't take the layout into account resulting in wrong noise levels or nearests towns (patch by Zuu)
This commit is contained in:
parent
c0a6ce3025
commit
de46e9647b
@ -127,16 +127,16 @@
|
|||||||
|
|
||||||
/* static */ int ScriptAirport::GetNoiseLevelIncrease(TileIndex tile, AirportType type)
|
/* static */ int ScriptAirport::GetNoiseLevelIncrease(TileIndex tile, AirportType type)
|
||||||
{
|
{
|
||||||
extern Town *AirportGetNearestTown(const AirportSpec *as, TileIndex airport_tile);
|
extern Town *AirportGetNearestTown(const AirportSpec *as, byte layout, TileIndex airport_tile);
|
||||||
extern uint8 GetAirportNoiseLevelForTown(const AirportSpec *as, TileIndex town_tile, TileIndex tile);
|
extern uint8 GetAirportNoiseLevelForTown(const AirportSpec *as, byte layout, TileIndex town_tile, TileIndex tile);
|
||||||
|
|
||||||
if (!::IsValidTile(tile)) return -1;
|
if (!::IsValidTile(tile)) return -1;
|
||||||
if (!IsAirportInformationAvailable(type)) return -1;
|
if (!IsAirportInformationAvailable(type)) return -1;
|
||||||
|
|
||||||
if (_settings_game.economy.station_noise_level) {
|
if (_settings_game.economy.station_noise_level) {
|
||||||
const AirportSpec *as = ::AirportSpec::Get(type);
|
const AirportSpec *as = ::AirportSpec::Get(type);
|
||||||
const Town *t = AirportGetNearestTown(as, tile);
|
const Town *t = AirportGetNearestTown(as, 0, tile);
|
||||||
return GetAirportNoiseLevelForTown(as, t->xy, tile);
|
return GetAirportNoiseLevelForTown(as, 0, t->xy, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -144,12 +144,12 @@
|
|||||||
|
|
||||||
/* static */ TownID ScriptAirport::GetNearestTown(TileIndex tile, AirportType type)
|
/* static */ TownID ScriptAirport::GetNearestTown(TileIndex tile, AirportType type)
|
||||||
{
|
{
|
||||||
extern Town *AirportGetNearestTown(const AirportSpec *as, TileIndex airport_tile);
|
extern Town *AirportGetNearestTown(const AirportSpec *as, byte layout, TileIndex airport_tile);
|
||||||
|
|
||||||
if (!::IsValidTile(tile)) return INVALID_TOWN;
|
if (!::IsValidTile(tile)) return INVALID_TOWN;
|
||||||
if (!IsAirportInformationAvailable(type)) return INVALID_TOWN;
|
if (!IsAirportInformationAvailable(type)) return INVALID_TOWN;
|
||||||
|
|
||||||
return AirportGetNearestTown(AirportSpec::Get(type), tile)->index;
|
return AirportGetNearestTown(AirportSpec::Get(type), 0, tile)->index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ uint16 ScriptAirport::GetMaintenanceCostFactor(AirportType type)
|
/* static */ uint16 ScriptAirport::GetMaintenanceCostFactor(AirportType type)
|
||||||
|
@ -2024,24 +2024,21 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui
|
|||||||
* @param airport_tile st->airport.tile
|
* @param airport_tile st->airport.tile
|
||||||
* @return minimal manhattan distance from town_tile to any airport's tile
|
* @return minimal manhattan distance from town_tile to any airport's tile
|
||||||
*/
|
*/
|
||||||
static uint GetMinimalAirportDistanceToTile(const AirportSpec *as, TileIndex town_tile, TileIndex airport_tile)
|
static uint GetMinimalAirportDistanceToTile(const AirportSpec *as, byte layout, TileIndex town_tile, TileIndex airport_tile)
|
||||||
{
|
{
|
||||||
uint ttx = TileX(town_tile); // X, Y of town
|
uint mindist = UINT_MAX;
|
||||||
uint tty = TileY(town_tile);
|
|
||||||
|
|
||||||
uint atx = TileX(airport_tile); // X, Y of northern airport corner
|
const AirportTileTable *it = as->table[layout];
|
||||||
uint aty = TileY(airport_tile);
|
do {
|
||||||
|
TileIndex cur_tile = airport_tile + ToTileIndexDiff(it->ti);
|
||||||
|
|
||||||
uint btx = TileX(airport_tile) + as->size_x - 1; // X, Y of southern corner
|
uint dist = DistanceManhattan(town_tile, cur_tile);
|
||||||
uint bty = TileY(airport_tile) + as->size_y - 1;
|
if (dist < mindist) {
|
||||||
|
mindist = dist;
|
||||||
|
}
|
||||||
|
} while ((++it)->ti.x != -0x80);
|
||||||
|
|
||||||
/* if ttx < atx, dx = atx - ttx
|
return mindist;
|
||||||
* if atx <= ttx <= btx, dx = 0
|
|
||||||
* else, dx = ttx - btx (similiar for dy) */
|
|
||||||
uint dx = ttx < atx ? atx - ttx : (ttx <= btx ? 0 : ttx - btx);
|
|
||||||
uint dy = tty < aty ? aty - tty : (tty <= bty ? 0 : tty - bty);
|
|
||||||
|
|
||||||
return dx + dy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2053,13 +2050,14 @@ static uint GetMinimalAirportDistanceToTile(const AirportSpec *as, TileIndex tow
|
|||||||
* @param tile TileIndex of northern tile of an airport (present or to-be-built), NOT the station tile
|
* @param tile TileIndex of northern tile of an airport (present or to-be-built), NOT the station tile
|
||||||
* @return the noise that will be generated, according to distance
|
* @return the noise that will be generated, according to distance
|
||||||
*/
|
*/
|
||||||
uint8 GetAirportNoiseLevelForTown(const AirportSpec *as, TileIndex town_tile, TileIndex tile)
|
uint8 GetAirportNoiseLevelForTown(const AirportSpec *as, byte layout, TileIndex town_tile, TileIndex tile)
|
||||||
{
|
{
|
||||||
/* 0 cannot be accounted, and 1 is the lowest that can be reduced from town.
|
/* 0 cannot be accounted, and 1 is the lowest that can be reduced from town.
|
||||||
* So no need to go any further*/
|
* So no need to go any further*/
|
||||||
if (as->noise_level < 2) return as->noise_level;
|
if (as->noise_level < 2) return as->noise_level;
|
||||||
|
|
||||||
uint distance = GetMinimalAirportDistanceToTile(as, town_tile, tile);
|
assert(layout < as->num_table);
|
||||||
|
uint distance = GetMinimalAirportDistanceToTile(as, layout, town_tile, tile);
|
||||||
|
|
||||||
/* The steps for measuring noise reduction are based on the "magical" (and arbitrary) 8 base distance
|
/* The steps for measuring noise reduction are based on the "magical" (and arbitrary) 8 base distance
|
||||||
* adding the town_council_tolerance 4 times, as a way to graduate, depending of the tolerance.
|
* adding the town_council_tolerance 4 times, as a way to graduate, depending of the tolerance.
|
||||||
@ -2083,14 +2081,16 @@ uint8 GetAirportNoiseLevelForTown(const AirportSpec *as, TileIndex town_tile, Ti
|
|||||||
* @param airport_tile st->airport.tile
|
* @param airport_tile st->airport.tile
|
||||||
* @return nearest town to airport
|
* @return nearest town to airport
|
||||||
*/
|
*/
|
||||||
Town *AirportGetNearestTown(const AirportSpec *as, TileIndex airport_tile)
|
Town *AirportGetNearestTown(const AirportSpec *as, byte layout, TileIndex airport_tile)
|
||||||
{
|
{
|
||||||
|
assert(layout < as->num_table);
|
||||||
|
|
||||||
Town *t, *nearest = NULL;
|
Town *t, *nearest = NULL;
|
||||||
uint add = as->size_x + as->size_y - 2; // GetMinimalAirportDistanceToTile can differ from DistanceManhattan by this much
|
uint add = as->size_x + as->size_y - 2; // GetMinimalAirportDistanceToTile can differ from DistanceManhattan by this much
|
||||||
uint mindist = UINT_MAX - add; // prevent overflow
|
uint mindist = UINT_MAX - add; // prevent overflow
|
||||||
FOR_ALL_TOWNS(t) {
|
FOR_ALL_TOWNS(t) {
|
||||||
if (DistanceManhattan(t->xy, airport_tile) < mindist + add) { // avoid calling GetMinimalAirportDistanceToTile too often
|
if (DistanceManhattan(t->xy, airport_tile) < mindist + add) { // avoid calling GetMinimalAirportDistanceToTile too often
|
||||||
uint dist = GetMinimalAirportDistanceToTile(as, t->xy, airport_tile);
|
uint dist = GetMinimalAirportDistanceToTile(as, layout, t->xy, airport_tile);
|
||||||
if (dist < mindist) {
|
if (dist < mindist) {
|
||||||
nearest = t;
|
nearest = t;
|
||||||
mindist = dist;
|
mindist = dist;
|
||||||
@ -2113,8 +2113,8 @@ void UpdateAirportsNoise()
|
|||||||
FOR_ALL_STATIONS(st) {
|
FOR_ALL_STATIONS(st) {
|
||||||
if (st->airport.tile != INVALID_TILE) {
|
if (st->airport.tile != INVALID_TILE) {
|
||||||
const AirportSpec *as = st->airport.GetSpec();
|
const AirportSpec *as = st->airport.GetSpec();
|
||||||
Town *nearest = AirportGetNearestTown(as, st->airport.tile);
|
Town *nearest = AirportGetNearestTown(as, st->airport.layout, st->airport.tile);
|
||||||
nearest->noise_reached += GetAirportNoiseLevelForTown(as, nearest->xy, st->airport.tile);
|
nearest->noise_reached += GetAirportNoiseLevelForTown(as, st->airport.layout, nearest->xy, st->airport.tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2166,8 +2166,8 @@ CommandCost CmdBuildAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
|
|||||||
if (cost.Failed()) return cost;
|
if (cost.Failed()) return cost;
|
||||||
|
|
||||||
/* 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. */
|
||||||
Town *nearest = AirportGetNearestTown(as, tile);
|
Town *nearest = AirportGetNearestTown(as, layout, tile);
|
||||||
uint newnoise_level = GetAirportNoiseLevelForTown(as, nearest->xy, tile);
|
uint newnoise_level = GetAirportNoiseLevelForTown(as, layout, nearest->xy, tile);
|
||||||
|
|
||||||
/* Check if local auth would allow a new airport */
|
/* Check if local auth would allow a new airport */
|
||||||
StringID authority_refuse_message = STR_NULL;
|
StringID authority_refuse_message = STR_NULL;
|
||||||
@ -2339,8 +2339,8 @@ static CommandCost RemoveAirport(TileIndex tile, DoCommandFlag flags)
|
|||||||
/* 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.
|
||||||
* And as for construction, always remove it, even if the setting is not set, in order to avoid the
|
* And as for construction, always remove it, even if the setting is not set, in order to avoid the
|
||||||
* need of recalculation */
|
* need of recalculation */
|
||||||
Town *nearest = AirportGetNearestTown(as, tile);
|
Town *nearest = AirportGetNearestTown(as, st->airport.layout, tile);
|
||||||
nearest->noise_reached -= GetAirportNoiseLevelForTown(as, nearest->xy, tile);
|
nearest->noise_reached -= GetAirportNoiseLevelForTown(as, st->airport.layout, nearest->xy, tile);
|
||||||
|
|
||||||
st->rect.AfterRemoveRect(st, st->airport);
|
st->rect.AfterRemoveRect(st, st->airport);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user