From 1637f6f6b0797d8dd8f4a1f52bc837a12820784f Mon Sep 17 00:00:00 2001 From: Michael Lutz Date: Sun, 10 Sep 2023 17:28:53 +0200 Subject: [PATCH] Feature: [NewGRF] Related Act2 objects for airports and airport tiles. Airports are similar two stations and industries, both of which have the town as related object. Airport tiles are similar to industry tiles, which have the industry as related object. This seems a sensible structure, so let's make it Airport Tile -> Airport -> Town. (cherry picked from commit 1c620b349f3c15aff20eb4d3372cbba16589213e) --- src/newgrf_airport.cpp | 21 +++++++++++++++++++++ src/newgrf_airport.h | 10 ++++++++++ src/newgrf_airporttiles.cpp | 4 +++- src/newgrf_airporttiles.h | 2 ++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/newgrf_airport.cpp b/src/newgrf_airport.cpp index dd39b4fed0..b94d6e11a4 100644 --- a/src/newgrf_airport.cpp +++ b/src/newgrf_airport.cpp @@ -14,6 +14,7 @@ #include "newgrf_text.h" #include "station_base.h" #include "newgrf_class_func.h" +#include "town.h" #include "safeguards.h" @@ -210,6 +211,26 @@ uint32 AirportResolverObject::GetDebugID() const this->st->airport.psa->StoreValue(pos, value); } +/** + * Get the town scope associated with a station, if it exists. + * On the first call, the town scope is created (if possible). + * @return Town scope, if available. + */ +TownScopeResolver *AirportResolverObject::GetTown() +{ + if (!this->town_scope) { + Town *t = nullptr; + if (this->airport_scope.st != nullptr) { + t = this->airport_scope.st->town; + } else if (this->airport_scope.tile != INVALID_TILE) { + t = ClosestTownFromTile(this->airport_scope.tile, UINT_MAX); + } + if (t == nullptr) return nullptr; + this->town_scope.reset(new TownScopeResolver(*this, t, this->airport_scope.st == nullptr)); + } + return this->town_scope.get(); +} + /** * Constructor of the airport resolver. * @param tile %Tile for the callback, only valid for airporttile callbacks. diff --git a/src/newgrf_airport.h b/src/newgrf_airport.h index f90536b4d0..58c606a91a 100644 --- a/src/newgrf_airport.h +++ b/src/newgrf_airport.h @@ -15,6 +15,7 @@ #include "newgrf_class.h" #include "newgrf_commons.h" #include "newgrf_spritegroup.h" +#include "newgrf_town.h" #include "tilearea_type.h" /** Copy from station_map.h */ @@ -173,14 +174,23 @@ struct AirportScopeResolver : public ScopeResolver { /** Resolver object for airports. */ struct AirportResolverObject : public ResolverObject { AirportScopeResolver airport_scope; + std::unique_ptr town_scope; ///< The town scope resolver (created on the first call). AirportResolverObject(TileIndex tile, Station *st, byte airport_id, byte layout, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0); + TownScopeResolver *GetTown(); + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, VarSpriteGroupScopeOffset relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: return &this->airport_scope; + case VSG_SCOPE_PARENT: + { + TownScopeResolver *tsr = this->GetTown(); + if (tsr != nullptr) return tsr; + FALLTHROUGH; + } default: return ResolverObject::GetScope(scope, relative); } } diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp index b43fb4733e..4339f4978c 100644 --- a/src/newgrf_airporttiles.cpp +++ b/src/newgrf_airporttiles.cpp @@ -223,7 +223,9 @@ static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32 */ AirportTileResolverObject::AirportTileResolverObject(const AirportTileSpec *ats, TileIndex tile, Station *st, CallbackID callback, uint32 callback_param1, uint32 callback_param2) - : ResolverObject(ats->grf_prop.grffile, callback, callback_param1, callback_param2), tiles_scope(*this, ats, tile, st) + : ResolverObject(ats->grf_prop.grffile, callback, callback_param1, callback_param2), + tiles_scope(*this, ats, tile, st), + airport_scope(*this, tile, st, st != nullptr ? st->airport.type : (byte)AT_DUMMY, st != nullptr ? st->airport.layout : 0) { this->root_spritegroup = ats->grf_prop.spritegroup[0]; } diff --git a/src/newgrf_airporttiles.h b/src/newgrf_airporttiles.h index dff59e1375..aa2965583e 100644 --- a/src/newgrf_airporttiles.h +++ b/src/newgrf_airporttiles.h @@ -44,6 +44,7 @@ struct AirportTileScopeResolver : public ScopeResolver { /** Resolver for tiles of an airport. */ struct AirportTileResolverObject : public ResolverObject { AirportTileScopeResolver tiles_scope; ///< Scope resolver for the tiles. + AirportScopeResolver airport_scope; ///< Scope resolver for the airport owning the tile. AirportTileResolverObject(const AirportTileSpec *ats, TileIndex tile, Station *st, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0); @@ -52,6 +53,7 @@ struct AirportTileResolverObject : public ResolverObject { { switch (scope) { case VSG_SCOPE_SELF: return &tiles_scope; + case VSG_SCOPE_PARENT: return &airport_scope; default: return ResolverObject::GetScope(scope, relative); } }