diff options
-rw-r--r-- | src/newgrf_airport.cpp | 139 | ||||
-rw-r--r-- | src/newgrf_spritegroup.h | 6 |
2 files changed, 63 insertions, 82 deletions
diff --git a/src/newgrf_airport.cpp b/src/newgrf_airport.cpp index e373e2ab5..f06e4c3b8 100644 --- a/src/newgrf_airport.cpp +++ b/src/newgrf_airport.cpp @@ -17,6 +17,37 @@ #include "station_base.h" #include "newgrf_class_func.h" +struct AirportScopeResolver : public ScopeResolver { + struct Station *st; ///< Station of the airport for which the callback is run, or \c NULL for build gui. + byte airport_id; ///< Type of airport for which the callback is run. + byte layout; ///< Layout of the airport to build. + TileIndex tile; ///< Tile for the callback, only valid for airporttile callbacks. + + AirportScopeResolver(ResolverObject *ro, TileIndex tile, Station *st, byte airport_id, byte layout); + + /* virtual */ uint32 GetRandomBits() const; + /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; + /* virtual */ void StorePSA(uint pos, int32 value); +}; + +/** Resolver object for airports. */ +struct AirportResolverObject : public ResolverObject { + AirportScopeResolver airport_scope; + + AirportResolverObject(TileIndex tile, Station *st, byte airport_id, byte layout, + CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0); + + /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) + { + switch (scope) { + case VSG_SCOPE_SELF: return &this->airport_scope; + default: return &this->default_scope; // XXX return ResolverObject::GetScope(scope, relative); + } + } + + /* virtual */ const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const; +}; + /** * Reset airport classes to their default state. * This includes initialising the defaults classes with an empty @@ -132,38 +163,29 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as) } } -uint32 AirportGetVariable(const ResolverObject *object, byte variable, uint32 parameter, bool *available) +/* virtual */ uint32 AirportScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const { - const Station *st = object->u.airport.st; - byte layout = object->u.airport.layout; - - if (object->scope == VSG_SCOPE_PARENT) { - DEBUG(grf, 1, "Parent scope for airports unavailable"); - *available = false; - return UINT_MAX; - } - switch (variable) { - case 0x40: return layout; + case 0x40: return this->layout; } - if (st == NULL) { + if (this->st == NULL) { *available = false; return UINT_MAX; } switch (variable) { /* Get a variable from the persistent storage */ - case 0x7C: return (st->airport.psa != NULL) ? st->airport.psa->GetValue(parameter) : 0; + case 0x7C: return (this->st->airport.psa != NULL) ? this->st->airport.psa->GetValue(parameter) : 0; - case 0xF0: return st->facilities; - case 0xFA: return Clamp(st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); + case 0xF0: return this->st->facilities; + case 0xFA: return Clamp(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); } - return st->GetNewGRFVariable(object, variable, parameter, available); + return this->st->GetNewGRFVariable(this->ro, variable, parameter, available); } -static const SpriteGroup *AirportResolveReal(const ResolverObject *object, const RealSpriteGroup *group) +/* virtual */ const SpriteGroup *AirportResolverObject::ResolveReal(const RealSpriteGroup *group) const { /* Airport action 2s should always have only 1 "loaded" state, but some * times things don't follow the spec... */ @@ -173,19 +195,9 @@ static const SpriteGroup *AirportResolveReal(const ResolverObject *object, const return NULL; } -static uint32 AirportGetRandomBits(const ResolverObject *object) -{ - const Station *st = object->u.airport.st; - return st == NULL ? 0 : st->random_bits; -} - -static uint32 AirportGetTriggers(const ResolverObject *object) -{ - return 0; -} - -static void AirportSetTriggers(const ResolverObject *object, int triggers) +/* virtual */ uint32 AirportScopeResolver::GetRandomBits() const { + return this->st == NULL ? 0 : this->st->random_bits; } /** @@ -194,54 +206,40 @@ static void AirportSetTriggers(const ResolverObject *object, int triggers) * @param pos Position in the persistent storage to use. * @param value Value to store. */ -void AirportStorePSA(ResolverObject *object, uint pos, int32 value) +/* virtual */ void AirportScopeResolver::StorePSA(uint pos, int32 value) { - Station *st = object->u.airport.st; - if (object->scope != VSG_SCOPE_SELF || st == NULL) return; + if (this->st == NULL) return; - if (st->airport.psa == NULL) { + if (this->st->airport.psa == NULL) { /* There is no need to create a storage if the value is zero. */ if (value == 0) return; /* Create storage on first modification. */ - uint32 grfid = (object->grffile != NULL) ? object->grffile->grfid : 0; + uint32 grfid = (this->ro->grffile != NULL) ? this->ro->grffile->grfid : 0; assert(PersistentStorage::CanAllocateItem()); - st->airport.psa = new PersistentStorage(grfid); + this->st->airport.psa = new PersistentStorage(grfid); } - st->airport.psa->StoreValue(pos, value); + this->st->airport.psa->StoreValue(pos, value); } -static void NewAirportResolver(ResolverObject *res, TileIndex tile, Station *st, byte airport_id, byte layout) +AirportResolverObject::AirportResolverObject(TileIndex tile, Station *st, byte airport_id, byte layout, + CallbackID callback, uint32 param1, uint32 param2) + : ResolverObject(AirportSpec::Get(airport_id)->grf_prop.grffile, callback, param1, param2), airport_scope(this, tile, st, airport_id, layout) { - res->GetRandomBits = AirportGetRandomBits; - res->GetTriggers = AirportGetTriggers; - res->SetTriggers = AirportSetTriggers; - res->GetVariable = AirportGetVariable; - res->ResolveRealMethod = AirportResolveReal; - res->StorePSA = AirportStorePSA; - - res->u.airport.st = st; - res->u.airport.airport_id = airport_id; - res->u.airport.layout = layout; - res->u.airport.tile = tile; - - res->callback = CBID_NO_CALLBACK; - res->callback_param1 = 0; - res->callback_param2 = 0; - res->ResetState(); - - const AirportSpec *as = AirportSpec::Get(airport_id); - res->grffile = as->grf_prop.grffile; } -SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout) +AirportScopeResolver::AirportScopeResolver(ResolverObject *ro, TileIndex tile, Station *st, byte airport_id, byte layout) : ScopeResolver(ro) { - const SpriteGroup *group; - ResolverObject object; - - NewAirportResolver(&object, INVALID_TILE, NULL, as->GetIndex(), layout); + this->st = st; + this->airport_id = airport_id; + this->layout = layout; + this->tile = tile; +} - group = SpriteGroup::Resolve(as->grf_prop.spritegroup[0], &object); +SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout) +{ + AirportResolverObject object(INVALID_TILE, NULL, as->GetIndex(), layout); + const SpriteGroup *group = SpriteGroup::Resolve(as->grf_prop.spritegroup[0], &object); if (group == NULL) return as->preview_sprite; return group->GetResult(); @@ -249,13 +247,7 @@ SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout) uint16 GetAirportCallback(CallbackID callback, uint32 param1, uint32 param2, Station *st, TileIndex tile) { - ResolverObject object; - - NewAirportResolver(&object, tile, st, st->airport.type, st->airport.layout); - object.callback = callback; - object.callback_param1 = param1; - object.callback_param2 = param2; - + AirportResolverObject object(tile, st, st->airport.type, st->airport.layout, callback, param1, param2); const SpriteGroup *group = SpriteGroup::Resolve(st->airport.GetSpec()->grf_prop.spritegroup[0], &object); if (group == NULL) return CALLBACK_FAILED; @@ -271,13 +263,8 @@ uint16 GetAirportCallback(CallbackID callback, uint32 param1, uint32 param2, Sta */ StringID GetAirportTextCallback(const AirportSpec *as, byte layout, uint16 callback) { - const SpriteGroup *group; - ResolverObject object; - - NewAirportResolver(&object, INVALID_TILE, NULL, as->GetIndex(), layout); - object.callback = (CallbackID)callback; - - group = SpriteGroup::Resolve(as->grf_prop.spritegroup[0], &object); + AirportResolverObject object(INVALID_TILE, NULL, as->GetIndex(), layout, (CallbackID)callback); + const SpriteGroup *group = SpriteGroup::Resolve(as->grf_prop.spritegroup[0], &object); uint16 cb_res = (group != NULL) ? group->GetCallbackResult() : CALLBACK_FAILED; if (cb_res == CALLBACK_FAILED || cb_res == 0x400) return STR_UNDEFINED; if (cb_res > 0x400) { diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index 2dc5f84d9..746219725 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -373,12 +373,6 @@ struct ResolverObject { uint8 count; uint8 station_size; } generic; - struct { - struct Station *st; ///< Station of the airport for which the callback is run, or NULL for build gui. - byte airport_id; ///< Type of airport for which the callback is run - byte layout; ///< Layout of the airport to build. - TileIndex tile; ///< Tile for the callback, only valid for airporttile callbacks. - } airport; } u; uint32 (*GetRandomBits)(const struct ResolverObject*); |