(svn r26388) -Codechange: Move resolving of Action 3 into ResolverObject constructor.

This commit is contained in:
frosch 2014-03-03 20:02:31 +00:00
parent b935cb8415
commit 6b61c4608f
17 changed files with 143 additions and 184 deletions

View File

@ -237,6 +237,7 @@ AirportResolverObject::AirportResolverObject(TileIndex tile, Station *st, byte a
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)
{
this->root_spritegroup = AirportSpec::Get(airport_id)->grf_prop.spritegroup[0];
}
/**
@ -258,7 +259,7 @@ AirportScopeResolver::AirportScopeResolver(ResolverObject &ro, TileIndex tile, S
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);
const SpriteGroup *group = object.Resolve();
if (group == NULL) return as->preview_sprite;
return group->GetResult();
@ -267,10 +268,7 @@ SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout)
uint16 GetAirportCallback(CallbackID callback, uint32 param1, uint32 param2, Station *st, TileIndex tile)
{
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;
return group->GetCallbackResult();
return object.ResolveCallback();
}
/**
@ -283,8 +281,7 @@ uint16 GetAirportCallback(CallbackID callback, uint32 param1, uint32 param2, Sta
StringID GetAirportTextCallback(const AirportSpec *as, byte layout, uint16 callback)
{
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;
uint16 cb_res = object.ResolveCallback();
if (cb_res == CALLBACK_FAILED || cb_res == 0x400) return STR_UNDEFINED;
if (cb_res > 0x400) {
ErrorUnknownCallbackResult(as->grf_prop.grffile->grfid, callback, cb_res);

View File

@ -217,6 +217,7 @@ AirportTileResolverObject::AirportTileResolverObject(const AirportTileSpec *ats,
CallbackID callback, uint32 callback_param1, uint32 callback_param2)
: ResolverObject(ats->grf_prop.grffile, callback, callback_param1, callback_param2), tiles_scope(*this, ats, tile, st)
{
this->root_spritegroup = ats->grf_prop.spritegroup[0];
}
/**
@ -237,10 +238,7 @@ AirportTileScopeResolver::AirportTileScopeResolver(ResolverObject &ro, const Air
uint16 GetAirportTileCallback(CallbackID callback, uint32 param1, uint32 param2, const AirportTileSpec *ats, Station *st, TileIndex tile, int extra_data = 0)
{
AirportTileResolverObject object(ats, tile, st, callback, param1, param2);
const SpriteGroup *group = SpriteGroup::Resolve(ats->grf_prop.spritegroup[0], object);
if (group == NULL) return CALLBACK_FAILED;
return group->GetCallbackResult();
return object.ResolveCallback();
}
static void AirportDrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, byte colour, StationGfx gfx)
@ -275,7 +273,7 @@ bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const Airport
}
AirportTileResolverObject object(airts, ti->tile, st);
const SpriteGroup *group = SpriteGroup::Resolve(airts->grf_prop.spritegroup[0], object);
const SpriteGroup *group = object.Resolve();
if (group == NULL || group->type != SGT_TILELAYOUT) {
return false;
}

View File

@ -33,7 +33,7 @@ struct CanalScopeResolver : public ScopeResolver {
struct CanalResolverObject : public ResolverObject {
CanalScopeResolver canal_scope;
CanalResolverObject(const GRFFile *grffile, TileIndex tile,
CanalResolverObject(CanalFeature feature, TileIndex tile,
CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0);
/* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0)
@ -115,16 +115,17 @@ CanalScopeResolver::CanalScopeResolver(ResolverObject &ro, TileIndex tile) : Sco
/**
* Canal resolver constructor.
* @param grffile Grf file.
* @param feature Which canal feature we want.
* @param tile Tile index of canal.
* @param callback Callback ID.
* @param callback_param1 First parameter (var 10) of the callback.
* @param callback_param2 Second parameter (var 18) of the callback.
*/
CanalResolverObject::CanalResolverObject(const GRFFile *grffile, TileIndex tile,
CanalResolverObject::CanalResolverObject(CanalFeature feature, TileIndex tile,
CallbackID callback, uint32 callback_param1, uint32 callback_param2)
: ResolverObject(grffile, callback, callback_param1, callback_param2), canal_scope(*this, tile)
: ResolverObject(_water_feature[feature].grffile, callback, callback_param1, callback_param2), canal_scope(*this, tile)
{
this->root_spritegroup = _water_feature[feature].group;
}
/**
@ -135,8 +136,8 @@ CanalResolverObject::CanalResolverObject(const GRFFile *grffile, TileIndex tile,
*/
SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile)
{
CanalResolverObject object(_water_feature[feature].grffile, tile);
const SpriteGroup *group = SpriteGroup::Resolve(_water_feature[feature].group, object);
CanalResolverObject object(feature, tile);
const SpriteGroup *group = object.Resolve();
if (group == NULL) return 0;
return group->GetResult();
@ -153,11 +154,8 @@ SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile)
*/
static uint16 GetCanalCallback(CallbackID callback, uint32 param1, uint32 param2, CanalFeature feature, TileIndex tile)
{
CanalResolverObject object(_water_feature[feature].grffile, tile, callback, param1, param2);
const SpriteGroup *group = SpriteGroup::Resolve(_water_feature[feature].group, object);
if (group == NULL) return CALLBACK_FAILED;
return group->GetCallbackResult();
CanalResolverObject object(feature, tile, callback, param1, param2);
return object.ResolveCallback();
}
/**

View File

@ -40,6 +40,7 @@ struct CargoResolverObject : public ResolverObject {
CargoResolverObject::CargoResolverObject(const CargoSpec *cs, CallbackID callback, uint32 callback_param1, uint32 callback_param2)
: ResolverObject(cs->grffile, callback, callback_param1, callback_param2)
{
this->root_spritegroup = cs->group;
}
/**
@ -50,7 +51,7 @@ CargoResolverObject::CargoResolverObject(const CargoSpec *cs, CallbackID callbac
SpriteID GetCustomCargoSprite(const CargoSpec *cs)
{
CargoResolverObject object(cs);
const SpriteGroup *group = SpriteGroup::Resolve(cs->group, object);
const SpriteGroup *group = object.Resolve();
if (group == NULL) return 0;
return group->GetResult();
@ -60,10 +61,7 @@ SpriteID GetCustomCargoSprite(const CargoSpec *cs)
uint16 GetCargoCallback(CallbackID callback, uint32 param1, uint32 param2, const CargoSpec *cs)
{
CargoResolverObject object(cs, callback, param1, param2);
const SpriteGroup *group = SpriteGroup::Resolve(cs->group, object);
if (group == NULL) return CALLBACK_FAILED;
return group->GetCallbackResult();
return object.ResolveCallback();
}
/**

View File

@ -973,12 +973,13 @@ static const GRFFile *GetEngineGrfFile(EngineID engine_type)
* Resolver of a vehicle (chain).
* @param engine_type Engine type
* @param v %Vehicle being resolved.
* @param wagon_override Application of wagon overrides.
* @param info_view Indicates if the item is being drawn in an info window.
* @param callback Callback ID.
* @param callback_param1 First parameter (var 10) of the callback.
* @param callback_param2 Second parameter (var 18) of the callback.
*/
VehicleResolverObject::VehicleResolverObject(EngineID engine_type, const Vehicle *v, bool info_view,
VehicleResolverObject::VehicleResolverObject(EngineID engine_type, const Vehicle *v, WagonOverride wagon_override, bool info_view,
CallbackID callback, uint32 callback_param1, uint32 callback_param2)
: ResolverObject(GetEngineGrfFile(engine_type), callback, callback_param1, callback_param2),
self_scope(*this, engine_type, v, info_view),
@ -986,55 +987,37 @@ VehicleResolverObject::VehicleResolverObject(EngineID engine_type, const Vehicle
relative_scope(*this, engine_type, v, info_view),
cached_relative_count(0)
{
}
/**
* Retrieve the SpriteGroup for the specified vehicle.
* If the vehicle is not specified, the purchase list group for the engine is
* chosen. For trains, an additional engine override lookup is performed.
* @param engine Engine type of the vehicle.
* @param v The vehicle itself.
* @param use_cache Use cached override
* @returns The selected SpriteGroup for the vehicle.
*/
static const SpriteGroup *GetVehicleSpriteGroup(EngineID engine, const Vehicle *v, bool use_cache = true)
{
const SpriteGroup *group;
CargoID cargo;
if (v == NULL) {
cargo = CT_PURCHASE;
if (wagon_override == WO_SELF) {
this->root_spritegroup = GetWagonOverrideSpriteSet(engine_type, CT_DEFAULT, engine_type);
} else {
cargo = v->cargo_type;
if (wagon_override != WO_NONE && v != NULL && v->IsGroundVehicle()) {
assert(v->engine_type == engine_type); // overrides make little sense with fake scopes
if (v->IsGroundVehicle()) {
/* For trains we always use cached value, except for callbacks because the override spriteset
* to use may be different than the one cached. It happens for callback 0x15 (refit engine),
* as v->cargo_type is temporary changed to the new type */
if (use_cache && v->type == VEH_TRAIN) {
group = Train::From(v)->tcache.cached_override;
if (wagon_override == WO_CACHED && v->type == VEH_TRAIN) {
this->root_spritegroup = Train::From(v)->tcache.cached_override;
} else {
group = GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, v->GetGroundVehicleCache()->first_engine);
this->root_spritegroup = GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, v->GetGroundVehicleCache()->first_engine);
}
if (group != NULL) return group;
}
if (this->root_spritegroup == NULL) {
const Engine *e = Engine::Get(engine_type);
CargoID cargo = v != NULL ? v->cargo_type : CT_PURCHASE;
assert(cargo < lengthof(e->grf_prop.spritegroup));
this->root_spritegroup = e->grf_prop.spritegroup[cargo] != NULL ? e->grf_prop.spritegroup[cargo] : e->grf_prop.spritegroup[CT_DEFAULT];
}
}
const Engine *e = Engine::Get(engine);
assert(cargo < lengthof(e->grf_prop.spritegroup));
group = e->grf_prop.spritegroup[cargo];
if (group != NULL) return group;
/* Fall back to the default set if the selected cargo type is not defined */
return e->grf_prop.spritegroup[CT_DEFAULT];
}
SpriteID GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction direction, EngineImageType image_type)
{
VehicleResolverObject object(engine, v, false, CBID_NO_CALLBACK, image_type);
const SpriteGroup *group = SpriteGroup::Resolve(GetVehicleSpriteGroup(engine, v), object);
VehicleResolverObject object(engine, v, VehicleResolverObject::WO_CACHED, false, CBID_NO_CALLBACK, image_type);
const SpriteGroup *group = object.Resolve();
if (group == NULL || group->GetNumResults() == 0) return 0;
return group->GetResult() + (direction % group->GetNumResults());
@ -1049,15 +1032,14 @@ SpriteID GetRotorOverrideSprite(EngineID engine, const Aircraft *v, bool info_vi
assert(e->type == VEH_AIRCRAFT);
assert(!(e->u.air.subtype & AIR_CTOL));
VehicleResolverObject object(engine, v, info_view, CBID_NO_CALLBACK, image_type);
const SpriteGroup *group = GetWagonOverrideSpriteSet(engine, CT_DEFAULT, engine);
group = SpriteGroup::Resolve(group, object);
VehicleResolverObject object(engine, v, VehicleResolverObject::WO_SELF, info_view, CBID_NO_CALLBACK, image_type);
const SpriteGroup *group = object.Resolve();
if (group == NULL || group->GetNumResults() == 0) return 0;
if (v == NULL) return group->GetResult();
if (v == NULL || info_view) return group->GetResult();
return group->GetResult() + (info_view ? 0 : (v->Next()->Next()->state % group->GetNumResults()));
return group->GetResult() + (v->Next()->Next()->state % group->GetNumResults());
}
@ -1083,11 +1065,8 @@ bool UsesWagonOverride(const Vehicle *v)
*/
uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v)
{
VehicleResolverObject object(engine, v, false, callback, param1, param2);
const SpriteGroup *group = SpriteGroup::Resolve(GetVehicleSpriteGroup(engine, v, false), object);
if (group == NULL) return CALLBACK_FAILED;
return group->GetCallbackResult();
VehicleResolverObject object(engine, v, VehicleResolverObject::WO_UNCACHED, false, callback, param1, param2);
return object.ResolveCallback();
}
/**
@ -1102,13 +1081,9 @@ uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, Eng
*/
uint16 GetVehicleCallbackParent(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v, const Vehicle *parent)
{
VehicleResolverObject object(engine, v, false, callback, param1, param2);
VehicleResolverObject object(engine, v, VehicleResolverObject::WO_NONE, false, callback, param1, param2);
object.parent_scope.SetVehicle(parent);
const SpriteGroup *group = SpriteGroup::Resolve(GetVehicleSpriteGroup(engine, v, false), object);
if (group == NULL) return CALLBACK_FAILED;
return group->GetCallbackResult();
return object.ResolveCallback();
}
@ -1133,10 +1108,10 @@ static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_rando
/* We can't trigger a non-existent vehicle... */
assert(v != NULL);
VehicleResolverObject object(v->engine_type, v, false, CBID_RANDOM_TRIGGER);
VehicleResolverObject object(v->engine_type, v, VehicleResolverObject::WO_CACHED, false, CBID_RANDOM_TRIGGER);
object.trigger = trigger;
const SpriteGroup *group = SpriteGroup::Resolve(GetVehicleSpriteGroup(v->engine_type, v), object);
const SpriteGroup *group = object.Resolve();
if (group == NULL) return;
byte new_random_bits = Random();
@ -1300,7 +1275,7 @@ void CommitVehicleListOrderChanges()
*/
void FillNewGRFVehicleCache(const Vehicle *v)
{
VehicleResolverObject ro(v->engine_type, v);
VehicleResolverObject ro(v->engine_type, v, VehicleResolverObject::WO_NONE);
/* These variables we have to check; these are the ones with a cache. */
static const int cache_entries[][2] = {

View File

@ -38,13 +38,21 @@ struct VehicleScopeResolver : public ScopeResolver {
/** Resolver for a vehicle (chain) */
struct VehicleResolverObject : public ResolverObject {
/** Application of 'wagon overrides'. */
enum WagonOverride {
WO_NONE, //!< Resolve no wagon overrides.
WO_UNCACHED, //!< Resolve wagon overrides.
WO_CACHED, //!< Resolve wagon overrides using TrainCache::cached_override.
WO_SELF, //!< Resolve self-override (helicopter rotors and such).
};
VehicleScopeResolver self_scope; ///< Scope resolver for the indicated vehicle.
VehicleScopeResolver parent_scope; ///< Scope resolver for its parent vehicle.
VehicleScopeResolver relative_scope; ///< Scope resolver for an other vehicle in the chain.
byte cached_relative_count; ///< Relative position of the other vehicle.
VehicleResolverObject(EngineID engine_type, const Vehicle *v, bool info_view = false,
VehicleResolverObject(EngineID engine_type, const Vehicle *v, WagonOverride wagon_override, bool info_view = false,
CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0);
/* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0);

View File

@ -179,17 +179,17 @@ static uint16 GetGenericCallbackResult(uint8 feature, ResolverObject &object, ui
/* Test each feature callback sprite group. */
for (GenericCallbackList::const_iterator it = _gcl[feature].begin(); it != _gcl[feature].end(); ++it) {
const SpriteGroup *group = it->group;
object.grffile = it->file;
object.root_spritegroup = it->group;
/* Set callback param based on GRF version. */
object.callback_param1 = it->file->grf_version >= 8 ? param1_grfv8 : param1_grfv7;
group = SpriteGroup::Resolve(group, object);
if (group == NULL || group->GetCallbackResult() == CALLBACK_FAILED) continue;
uint16 result = object.ResolveCallback();
if (result == CALLBACK_FAILED) continue;
/* Return NewGRF file if necessary */
if (file != NULL) *file = it->file;
return group->GetCallbackResult();
return result;
}
/* No callback returned a valid result, so we've failed. */

View File

@ -81,6 +81,7 @@ HouseResolverObject::HouseResolverObject(HouseID house_id, TileIndex tile, Town
house_scope(*this, house_id, tile, town, not_yet_constructed, initial_random_bits, watched_cargo_triggers),
town_scope(*this, town, not_yet_constructed) // Don't access StorePSA if house is not yet constructed.
{
this->root_spritegroup = HouseSpec::Get(house_id)->grf_prop.spritegroup[0];
}
HouseClassID AllocateHouseClassID(byte grf_class_id, uint32 grfid)
@ -439,11 +440,7 @@ uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, House
HouseResolverObject object(house_id, tile, town, callback, param1, param2,
not_yet_constructed, initial_random_bits, watched_cargo_triggers);
const SpriteGroup *group = SpriteGroup::Resolve(HouseSpec::Get(house_id)->grf_prop.spritegroup[0], object);
if (group == NULL) return CALLBACK_FAILED;
return group->GetCallbackResult();
return object.ResolveCallback();
}
static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, byte stage, HouseID house_id)
@ -490,7 +487,7 @@ void DrawNewHouseTile(TileInfo *ti, HouseID house_id)
HouseResolverObject object(house_id, ti->tile, Town::GetByTile(ti->tile));
const SpriteGroup *group = SpriteGroup::Resolve(hs->grf_prop.spritegroup[0], object);
const SpriteGroup *group = object.Resolve();
if (group != NULL && group->type == SGT_TILELAYOUT) {
/* Limit the building stage to the number of stages supplied. */
const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group;
@ -615,7 +612,7 @@ static void DoTriggerHouse(TileIndex tile, HouseTrigger trigger, byte base_rando
HouseResolverObject object(hid, tile, Town::GetByTile(tile), CBID_RANDOM_TRIGGER);
object.trigger = trigger;
const SpriteGroup *group = SpriteGroup::Resolve(hs->grf_prop.spritegroup[0], object);
const SpriteGroup *group = object.Resolve();
if (group == NULL) return;
byte new_random_bits = Random();

View File

@ -432,6 +432,7 @@ IndustriesResolverObject::IndustriesResolverObject(TileIndex tile, Industry *ind
industries_scope(*this, tile, indus, type, random_bits),
town_scope(NULL)
{
this->root_spritegroup = GetIndustrySpec(type)->grf_prop.spritegroup[0];
}
IndustriesResolverObject::~IndustriesResolverObject()
@ -490,10 +491,7 @@ IndustriesScopeResolver::IndustriesScopeResolver(ResolverObject &ro, TileIndex t
uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile)
{
IndustriesResolverObject object(tile, industry, type, 0, callback, param1, param2);
const SpriteGroup *group = SpriteGroup::Resolve(GetIndustrySpec(type)->grf_prop.spritegroup[0], object);
if (group == NULL) return CALLBACK_FAILED;
return group->GetCallbackResult();
return object.ResolveCallback();
}
/**
@ -523,12 +521,10 @@ CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uin
ind.psa = NULL;
IndustriesResolverObject object(tile, &ind, type, seed, CBID_INDUSTRY_LOCATION, 0, creation_type);
const SpriteGroup *group = SpriteGroup::Resolve(GetIndustrySpec(type)->grf_prop.spritegroup[0], object);
uint16 result = object.ResolveCallback();
/* Unlike the "normal" cases, not having a valid result means we allow
* the building of the industry, as that's how it's done in TTDP. */
if (group == NULL) return CommandCost();
uint16 result = group->GetCallbackResult();
if (result == CALLBACK_FAILED) return CommandCost();
return GetErrorMessageFromLocationCallbackResult(result, indspec->grf_prop.grffile, STR_ERROR_SITE_UNSUITABLE);
@ -596,7 +592,7 @@ void IndustryProductionCallback(Industry *ind, int reason)
}
SB(object.callback_param2, 8, 16, loop);
const SpriteGroup *tgroup = SpriteGroup::Resolve(spec->grf_prop.spritegroup[0], object);
const SpriteGroup *tgroup = object.Resolve();
if (tgroup == NULL || tgroup->type != SGT_INDUSTRY_PRODUCTION) break;
const IndustryProductionSpriteGroup *group = (const IndustryProductionSpriteGroup *)tgroup;

View File

@ -147,6 +147,7 @@ IndustryTileResolverObject::IndustryTileResolverObject(IndustryGfx gfx, TileInde
indtile_scope(*this, indus, tile),
ind_scope(*this, tile, indus, indus->type)
{
this->root_spritegroup = GetIndustryTileSpec(gfx)->grf_prop.spritegroup[0];
}
/**
@ -190,10 +191,7 @@ uint16 GetIndustryTileCallback(CallbackID callback, uint32 param1, uint32 param2
assert(industry->index == INVALID_INDUSTRY || IsTileType(tile, MP_INDUSTRY));
IndustryTileResolverObject object(gfx_id, tile, industry, callback, param1, param2);
const SpriteGroup *group = SpriteGroup::Resolve(GetIndustryTileSpec(gfx_id)->grf_prop.spritegroup[0], object);
if (group == NULL || group->type != SGT_CALLBACK) return CALLBACK_FAILED;
return group->GetCallbackResult();
return object.ResolveCallback();
}
bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const IndustryTileSpec *inds)
@ -211,7 +209,7 @@ bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const Indus
IndustryTileResolverObject object(gfx, ti->tile, i);
const SpriteGroup *group = SpriteGroup::Resolve(inds->grf_prop.spritegroup[0], object);
const SpriteGroup *group = object.Resolve();
if (group == NULL || group->type != SGT_TILELAYOUT) return false;
/* Limit the building stage to the number of stages supplied. */
@ -328,7 +326,7 @@ static void DoTriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger, I
IndustryTileResolverObject object(gfx, tile, ind, CBID_RANDOM_TRIGGER);
object.trigger = trigger;
const SpriteGroup *group = SpriteGroup::Resolve(itspec->grf_prop.spritegroup[0], object);
const SpriteGroup *group = object.Resolve();
if (group == NULL) return;
byte new_random_bits = Random();

View File

@ -355,24 +355,6 @@ unhandled:
return UINT_MAX;
}
/**
* Get the object's sprite group.
* @param spec The specification to get the sprite group from.
* @param o The object to get he sprite group for.
* @return The resolved sprite group.
*/
static const SpriteGroup *GetObjectSpriteGroup(const ObjectSpec *spec, const Object *o)
{
const SpriteGroup *group = NULL;
if (o == NULL) group = spec->grf_prop.spritegroup[CT_PURCHASE_OBJECT];
if (group != NULL) return group;
/* Fall back to the default set if the selected cargo type is not defined */
return spec->grf_prop.spritegroup[0];
}
/**
* Constructor of the object resolver.
* @param obj Object being resolved.
@ -387,6 +369,8 @@ ObjectResolverObject::ObjectResolverObject(const ObjectSpec *spec, Object *obj,
: ResolverObject(spec->grf_prop.grffile, callback, param1, param2), object_scope(*this, obj, tile, view)
{
this->town_scope = NULL;
this->root_spritegroup = (obj == NULL && spec->grf_prop.spritegroup[CT_PURCHASE_OBJECT] != NULL) ?
spec->grf_prop.spritegroup[CT_PURCHASE_OBJECT] : spec->grf_prop.spritegroup[0];
}
ObjectResolverObject::~ObjectResolverObject()
@ -428,10 +412,7 @@ TownScopeResolver *ObjectResolverObject::GetTown()
uint16 GetObjectCallback(CallbackID callback, uint32 param1, uint32 param2, const ObjectSpec *spec, Object *o, TileIndex tile, uint8 view)
{
ObjectResolverObject object(spec, o, tile, view, callback, param1, param2);
const SpriteGroup *group = SpriteGroup::Resolve(GetObjectSpriteGroup(spec, o), object);
if (group == NULL) return CALLBACK_FAILED;
return group->GetCallbackResult();
return object.ResolveCallback();
}
/**
@ -471,7 +452,7 @@ void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec)
Object *o = Object::GetByTile(ti->tile);
ObjectResolverObject object(spec, o, ti->tile);
const SpriteGroup *group = SpriteGroup::Resolve(GetObjectSpriteGroup(spec, o), object);
const SpriteGroup *group = object.Resolve();
if (group == NULL || group->type != SGT_TILELAYOUT) return;
DrawTileLayout(ti, (const TileLayoutSpriteGroup *)group, spec);
@ -487,7 +468,7 @@ void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec)
void DrawNewObjectTileInGUI(int x, int y, const ObjectSpec *spec, uint8 view)
{
ObjectResolverObject object(spec, NULL, INVALID_TILE, view);
const SpriteGroup *group = SpriteGroup::Resolve(GetObjectSpriteGroup(spec, NULL), object);
const SpriteGroup *group = object.Resolve();
if (group == NULL || group->type != SGT_TILELAYOUT) return;
const DrawTileSprites *dts = ((const TileLayoutSpriteGroup *)group)->ProcessRegisters(NULL);

View File

@ -79,15 +79,17 @@ RailTypeScopeResolver::RailTypeScopeResolver(ResolverObject &ro, TileIndex tile,
/**
* Resolver object for rail types.
* @param rti Railtype. NULL in NewGRF Inspect window.
* @param tile %Tile containing the track. For track on a bridge this is the southern bridgehead.
* @param context Are we resolving sprites for the upper halftile, or on a bridge?
* @param grffile The GRF to do the lookup for.
* @param rtsg Railpart of interest
* @param param1 Extra parameter (first parameter of the callback, except railtypes do not have callbacks).
* @param param2 Extra parameter (second parameter of the callback, except railtypes do not have callbacks).
*/
RailTypeResolverObject::RailTypeResolverObject(TileIndex tile, TileContext context, const GRFFile *grffile, uint32 param1, uint32 param2)
: ResolverObject(grffile, CBID_NO_CALLBACK, param1, param2), railtype_scope(*this, tile, context)
RailTypeResolverObject::RailTypeResolverObject(const RailtypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32 param1, uint32 param2)
: ResolverObject(rti != NULL ? rti->grffile[rtsg] : NULL, CBID_NO_CALLBACK, param1, param2), railtype_scope(*this, tile, context)
{
this->root_spritegroup = rti != NULL ? rti->group[rtsg] : NULL;
}
/**
@ -104,8 +106,8 @@ SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSp
if (rti->group[rtsg] == NULL) return 0;
RailTypeResolverObject object(tile, context, rti->grffile[rtsg]);
const SpriteGroup *group = SpriteGroup::Resolve(rti->group[rtsg], object);
RailTypeResolverObject object(rti, tile, context, rtsg);
const SpriteGroup *group = object.Resolve();
if (group == NULL || group->GetNumResults() == 0) return 0;
return group->GetResult();
@ -127,9 +129,9 @@ SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalTy
uint32 param1 = gui ? 0x10 : 0x00;
uint32 param2 = (type << 16) | (var << 8) | state;
RailTypeResolverObject object(tile, TCX_NORMAL, rti->grffile[RTSG_SIGNALS], param1, param2);
RailTypeResolverObject object(rti, tile, TCX_NORMAL, RTSG_SIGNALS, param1, param2);
const SpriteGroup *group = SpriteGroup::Resolve(rti->group[RTSG_SIGNALS], object);
const SpriteGroup *group = object.Resolve();
if (group == NULL || group->GetNumResults() == 0) return 0;
return group->GetResult();

View File

@ -31,7 +31,7 @@ struct RailTypeScopeResolver : public ScopeResolver {
struct RailTypeResolverObject : public ResolverObject {
RailTypeScopeResolver railtype_scope; ///< Resolver for the railtype scope.
RailTypeResolverObject(TileIndex tile, TileContext context, const GRFFile *grffile, uint32 param1 = 0, uint32 param2 = 0);
RailTypeResolverObject(const RailtypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32 param1 = 0, uint32 param2 = 0);
/* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0)
{

View File

@ -150,6 +150,7 @@ ResolverObject::ResolverObject(const GRFFile *grffile, CallbackID callback, uint
this->ResetState();
this->grffile = grffile;
this->root_spritegroup = NULL;
}
ResolverObject::~ResolverObject() {}

View File

@ -321,6 +321,26 @@ struct ResolverObject {
uint32 reseed[VSG_END]; ///< Collects bits to rerandomise while triggering triggers.
const GRFFile *grffile; ///< GRFFile the resolved SpriteGroup belongs to
const SpriteGroup *root_spritegroup; ///< Root SpriteGroup to use for resolving
/**
* Resolve SpriteGroup.
* @return Result spritegroup.
*/
const SpriteGroup *Resolve()
{
return SpriteGroup::Resolve(this->root_spritegroup, *this);
}
/**
* Resolve callback.
* @return Callback result.
*/
uint16 ResolveCallback()
{
const SpriteGroup *result = Resolve();
return result != NULL ? result->GetCallbackResult() : CALLBACK_FAILED;
}
virtual const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const;

View File

@ -550,6 +550,32 @@ StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseSt
{
/* Invalidate all cached vars */
_svc.valid = 0;
CargoID ctype = CT_DEFAULT_NA;
if (this->station_scope.st == NULL) {
/* No station, so we are in a purchase list */
ctype = CT_PURCHASE;
} else if (Station::IsExpected(this->station_scope.st)) {
const Station *st = Station::From(this->station_scope.st);
/* Pick the first cargo that we have waiting */
const CargoSpec *cs;
FOR_ALL_CARGOSPECS(cs) {
if (this->station_scope.statspec->grf_prop.spritegroup[cs->Index()] != NULL &&
st->goods[cs->Index()].cargo.TotalCount() > 0) {
ctype = cs->Index();
break;
}
}
}
if (this->station_scope.statspec->grf_prop.spritegroup[ctype] == NULL) {
ctype = CT_DEFAULT;
}
/* Remember the cargo type we've picked */
this->station_scope.cargo_type = ctype;
this->root_spritegroup = this->station_scope.statspec->grf_prop.spritegroup[this->station_scope.cargo_type];
}
StationResolverObject::~StationResolverObject()
@ -574,39 +600,6 @@ StationScopeResolver::StationScopeResolver(ResolverObject &ro, const StationSpec
this->axis = INVALID_AXIS;
}
static const SpriteGroup *ResolveStation(StationResolverObject &object)
{
CargoID ctype = CT_DEFAULT_NA;
if (object.station_scope.st == NULL) {
/* No station, so we are in a purchase list */
ctype = CT_PURCHASE;
} else if (Station::IsExpected(object.station_scope.st)) {
const Station *st = Station::From(object.station_scope.st);
/* Pick the first cargo that we have waiting */
const CargoSpec *cs;
FOR_ALL_CARGOSPECS(cs) {
if (object.station_scope.statspec->grf_prop.spritegroup[cs->Index()] != NULL &&
st->goods[cs->Index()].cargo.TotalCount() > 0) {
ctype = cs->Index();
break;
}
}
}
const SpriteGroup *group = object.station_scope.statspec->grf_prop.spritegroup[ctype];
if (group == NULL) {
ctype = CT_DEFAULT;
group = object.station_scope.statspec->grf_prop.spritegroup[ctype];
if (group == NULL) return NULL;
}
/* Remember the cargo type we've picked */
object.station_scope.cargo_type = ctype;
return SpriteGroup::Resolve(group, object);
}
/**
* Resolve sprites for drawing a station tile.
* @param statspec Station spec
@ -618,7 +611,7 @@ static const SpriteGroup *ResolveStation(StationResolverObject &object)
SpriteID GetCustomStationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint32 var10)
{
StationResolverObject object(statspec, st, tile, CBID_NO_CALLBACK, var10);
const SpriteGroup *group = ResolveStation(object);
const SpriteGroup *group = object.Resolve();
if (group == NULL || group->type != SGT_RESULT) return 0;
return group->GetResult() - 0x42D;
}
@ -637,7 +630,7 @@ SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseS
/* callback_param1 == 2 means we are resolving the foundation sprites. */
StationResolverObject object(statspec, st, tile, CBID_NO_CALLBACK, 2, layout | (edge_info << 16));
const SpriteGroup *group = ResolveStation(object);
const SpriteGroup *group = object.Resolve();
if (group == NULL || group->type != SGT_RESULT) return 0;
/* Note: SpriteGroup::Resolve zeroes all registers, so register 0x100 is initialised to 0. (compatibility) */
@ -648,9 +641,7 @@ SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseS
uint16 GetStationCallback(CallbackID callback, uint32 param1, uint32 param2, const StationSpec *statspec, BaseStation *st, TileIndex tile)
{
StationResolverObject object(statspec, st, tile, callback, param1, param2);
const SpriteGroup *group = ResolveStation(object);
if (group == NULL) return CALLBACK_FAILED;
return group->GetCallbackResult();
return object.ResolveCallback();
}
/**
@ -673,8 +664,7 @@ CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_til
(numtracks << 24) | (plat_len << 16) | (axis == AXIS_Y ? TileX(diff) << 8 | TileY(diff) : TileY(diff) << 8 | TileX(diff)));
object.station_scope.axis = axis;
const SpriteGroup *group = ResolveStation(object);
uint16 cb_res = group != NULL ? group->GetCallbackResult() : CALLBACK_FAILED;
uint16 cb_res = object.ResolveCallback();
/* Failed callback means success. */
if (cb_res == CALLBACK_FAILED) return CommandCost();
@ -1024,7 +1014,7 @@ void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigg
StationResolverObject object(ss, st, tile, CBID_RANDOM_TRIGGER, 0);
object.trigger = trigger_bit;
const SpriteGroup *group = ResolveStation(object);
const SpriteGroup *group = object.Resolve();
if (group == NULL) continue;
uint32 reseed = object.GetReseedSum();

View File

@ -79,7 +79,7 @@ class NIHVehicle : public NIHelper {
/* virtual */ uint Resolve(uint index, uint var, uint param, bool *avail) const
{
Vehicle *v = Vehicle::Get(index);
VehicleResolverObject ro(v->engine_type, v);
VehicleResolverObject ro(v->engine_type, v, VehicleResolverObject::WO_CACHED);
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
}
};
@ -429,7 +429,7 @@ class NIHRailType : public NIHelper {
{
/* There is no unique GRFFile for the tile. Multiple GRFs can define different parts of the railtype.
* However, currently the NewGRF Debug GUI does not display variables depending on the GRF (like 0x7F) anyway. */
RailTypeResolverObject ro(index, TCX_NORMAL, NULL);
RailTypeResolverObject ro(NULL, index, TCX_NORMAL, RTSG_END);
return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail);
}
};