diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 44068b010b..8f6892ef4b 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -336,7 +336,7 @@ static void DrawTile_Industry(TileInfo *ti) * DrawNewIndustry will return false if ever the resolver could not * find any sprite to display. So in this case, we will jump on the * substitute gfx instead. */ - if (indts->grf_prop.GetSpriteGroup() != nullptr && DrawNewIndustryTile(ti, ind, gfx, indts)) { + if (indts->grf_prop.HasSpriteGroups() && DrawNewIndustryTile(ti, ind, gfx, indts)) { return; } else { /* No sprite group (or no valid one) found, meaning no graphics associated. @@ -405,7 +405,7 @@ static Foundation GetFoundation_Industry(TileIndex tile, Slope tileh) */ if (gfx >= NEW_INDUSTRYTILEOFFSET) { const IndustryTileSpec *indts = GetIndustryTileSpec(gfx); - if (indts->grf_prop.GetSpriteGroup() != nullptr && indts->callback_mask.Test(IndustryTileCallbackMask::DrawFoundations)) { + if (indts->callback_mask.Test(IndustryTileCallbackMask::DrawFoundations)) { uint32_t callback_res = GetIndustryTileCallback(CBID_INDTILE_DRAW_FOUNDATIONS, 0, 0, gfx, Industry::GetByTile(tile), tile); if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(indts->grf_prop.grffile, CBID_INDTILE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE; } diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp index 6d3484ff66..a13482f155 100644 --- a/src/newgrf_airporttiles.cpp +++ b/src/newgrf_airporttiles.cpp @@ -150,7 +150,7 @@ static uint32_t GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint } } /* Not an 'old type' tile */ - if (ats->grf_prop.GetSpriteGroup() != nullptr) { // tile has a spritegroup ? + if (ats->grf_prop.HasSpriteGroups()) { if (ats->grf_prop.grfid == cur_grfid) { // same airport, same grf ? return ats->grf_prop.local_id; } else { diff --git a/src/newgrf_badge.cpp b/src/newgrf_badge.cpp index c088b439d0..4be627cb30 100644 --- a/src/newgrf_badge.cpp +++ b/src/newgrf_badge.cpp @@ -203,8 +203,7 @@ BadgeResolverObject::BadgeResolverObject(const Badge &badge, GrfSpecFeature feat : ResolverObject(badge.grf_prop.grffile, callback, callback_param1, callback_param2), self_scope(*this, badge, introduction_date) { assert(feature <= GSF_END); - this->root_spritegroup = this->self_scope.badge.grf_prop.GetSpriteGroup(feature); - if (this->root_spritegroup == nullptr) this->root_spritegroup = this->self_scope.badge.grf_prop.GetSpriteGroup(GSF_DEFAULT); + this->root_spritegroup = this->self_scope.badge.grf_prop.GetFirstSpriteGroupOf({feature, GSF_DEFAULT}); } /** diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index f4d38e7ee1..c53d064fff 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -320,6 +320,20 @@ struct FixedGRFFileProps : GRFFilePropsBase { */ const struct SpriteGroup *GetSpriteGroup(Tkey index) const { return this->spritegroups[static_cast(index)]; } + /** + * Get the first existing SpriteGroup from a list of options. + * @param indices Valid options. + * @return First existing, or nullptr if none exists. + */ + const struct SpriteGroup *GetFirstSpriteGroupOf(std::initializer_list indices) const + { + for (auto key : indices) { + auto *result = GetSpriteGroup(key); + if (result != nullptr) return result; + } + return nullptr; + } + /** * Set the SpriteGroup at the specified index. * @param index Index to set. @@ -334,6 +348,7 @@ struct FixedGRFFileProps : GRFFilePropsBase { struct SingleGRFFileProps : GRFFilePropsBase { const struct SpriteGroup *spritegroup; + bool HasSpriteGroups() const { return this->spritegroup != nullptr; } const struct SpriteGroup *GetSpriteGroup() const { return this->spritegroup; } void SetSpriteGroup(const struct SpriteGroup *spritegroup) { this->spritegroup = spritegroup; } }; @@ -346,7 +361,31 @@ enum class StandardSpriteGroup { Purchase, ///< Used before an entity exists. End }; -using StandardGRFFileProps = FixedGRFFileProps(StandardSpriteGroup::End)>; + +/** + * Container for standard sprite groups. + */ +struct StandardGRFFileProps : FixedGRFFileProps(StandardSpriteGroup::End)> { + using FixedGRFFileProps(StandardSpriteGroup::End)>::GetSpriteGroup; + + /** + * Check whether the entity has sprite groups. + */ + bool HasSpriteGroups() const + { + return GetSpriteGroup(StandardSpriteGroup::Default) != nullptr; + } + + /** + * Get the standard sprite group. + * @param entity_exists Whether the entity exists (true), or is being constructed or shown in the GUI (false). + */ + const struct SpriteGroup *GetSpriteGroup(bool entity_exists) const + { + auto *res = entity_exists ? nullptr : GetSpriteGroup(StandardSpriteGroup::Purchase); + return res ? res : GetSpriteGroup(StandardSpriteGroup::Default); + } +}; /** * Variable-length list of sprite groups for an entity. @@ -369,6 +408,20 @@ struct VariableGRFFileProps : GRFFilePropsBase { return it->second; } + /** + * Get the first existing SpriteGroup from a list of options. + * @param indices Valid options. + * @return First existing, or nullptr if none exists. + */ + const struct SpriteGroup *GetFirstSpriteGroupOf(std::initializer_list indices) const + { + for (auto key : indices) { + auto *result = GetSpriteGroup(key); + if (result != nullptr) return result; + } + return nullptr; + } + /** * Set the SpriteGroup at the specified index. * @param index Index to set. diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 1f9c55fa30..f792866609 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -1086,8 +1086,7 @@ VehicleResolverObject::VehicleResolverObject(EngineID engine_type, const Vehicle if (this->root_spritegroup == nullptr) { const Engine *e = Engine::Get(engine_type); CargoType cargo = v != nullptr ? v->cargo_type : CargoGRFFileProps::SG_PURCHASE; - this->root_spritegroup = e->grf_prop.GetSpriteGroup(cargo); - if (this->root_spritegroup == nullptr) this->root_spritegroup = e->grf_prop.GetSpriteGroup(CargoGRFFileProps::SG_DEFAULT); + this->root_spritegroup = e->grf_prop.GetFirstSpriteGroupOf({cargo, CargoGRFFileProps::SG_DEFAULT}); } } } diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index bcaf36395d..3bcd644128 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -667,7 +667,7 @@ static void DoTriggerHouseRandomisation(TileIndex tile, HouseRandomTrigger trigg HouseID hid = GetHouseType(tile); HouseSpec *hs = HouseSpec::Get(hid); - if (hs->grf_prop.GetSpriteGroup() == nullptr) return; + if (!hs->grf_prop.HasSpriteGroups()) return; HouseResolverObject object(hid, tile, Town::GetByTile(tile), CBID_RANDOM_TRIGGER); auto waiting_random_triggers = GetHouseRandomTriggers(tile); diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index d463ddb7bc..b10c67fa79 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -79,7 +79,7 @@ uint32_t GetIndustryIDAtOffset(TileIndex tile, const Industry *i, uint32_t cur_g } } /* Not an 'old type' tile */ - if (indtsp->grf_prop.GetSpriteGroup() != nullptr) { // tile has a spritegroup ? + if (indtsp->grf_prop.HasSpriteGroups()) { if (indtsp->grf_prop.grfid == cur_grfid) { // same industry, same grf ? return indtsp->grf_prop.local_id; } else { diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index 76e56c660c..0e8c5ed695 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -328,7 +328,7 @@ static void DoTriggerIndustryTileRandomisation(TileIndex tile, IndustryRandomTri IndustryGfx gfx = GetIndustryGfx(tile); const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx); - if (itspec->grf_prop.GetSpriteGroup() == nullptr) return; + if (!itspec->grf_prop.HasSpriteGroups()) return; IndustryTileResolverObject object(gfx, tile, ind, CBID_RANDOM_TRIGGER); auto waiting_random_triggers = GetIndustryRandomTriggers(tile); diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index cee3f0e1e8..c853ebfff1 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -386,8 +386,7 @@ ObjectResolverObject::ObjectResolverObject(const ObjectSpec *spec, Object *obj, CallbackID callback, uint32_t param1, uint32_t param2) : ResolverObject(spec->grf_prop.grffile, callback, param1, param2), object_scope(*this, obj, spec, tile, view) { - this->root_spritegroup = (obj == nullptr) ? spec->grf_prop.GetSpriteGroup(StandardSpriteGroup::Purchase) : nullptr; - if (this->root_spritegroup == nullptr) this->root_spritegroup = spec->grf_prop.GetSpriteGroup(StandardSpriteGroup::Default); + this->root_spritegroup = spec->grf_prop.GetSpriteGroup(obj != nullptr); } /** diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index a2d32442e6..25e009e19f 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3121,7 +3121,7 @@ static void DrawTile_Station(TileInfo *ti) gfx = GetAirportGfx(ti->tile); if (gfx >= NEW_AIRPORTTILE_OFFSET) { const AirportTileSpec *ats = AirportTileSpec::Get(gfx); - if (ats->grf_prop.GetSpriteGroup() != nullptr && DrawNewAirportTile(ti, Station::GetByTile(ti->tile), ats)) { + if (ats->grf_prop.HasSpriteGroups() && DrawNewAirportTile(ti, Station::GetByTile(ti->tile), ats)) { return; } /* No sprite group (or no valid one) found, meaning no graphics associated. diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 4a1d865499..2ccda65ba4 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -273,7 +273,7 @@ static void DrawTile_Town(TileInfo *ti) /* Houses don't necessarily need new graphics. If they don't have a * spritegroup associated with them, then the sprite for the substitute * house id is drawn instead. */ - if (HouseSpec::Get(house_id)->grf_prop.GetSpriteGroup() != nullptr) { + if (HouseSpec::Get(house_id)->grf_prop.HasSpriteGroups()) { DrawNewHouseTile(ti, house_id); return; } else { @@ -334,7 +334,7 @@ static Foundation GetFoundation_Town(TileIndex tile, Slope tileh) */ if (hid >= NEW_HOUSE_OFFSET) { const HouseSpec *hs = HouseSpec::Get(hid); - if (hs->grf_prop.GetSpriteGroup() != nullptr && hs->callback_mask.Test(HouseCallbackMask::DrawFoundations)) { + if (hs->callback_mask.Test(HouseCallbackMask::DrawFoundations)) { uint32_t callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, hid, Town::GetByTile(tile), tile); if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE; } diff --git a/src/town_gui.cpp b/src/town_gui.cpp index f3f6f3ed3b..e0f5bea8ea 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -1349,7 +1349,7 @@ void DrawHouseInGUI(int x, int y, HouseID house_id, int view) * spritegroup associated with them, then the sprite for the substitute * house id is drawn instead. */ const HouseSpec *spec = HouseSpec::Get(house_id); - if (spec->grf_prop.GetSpriteGroup() != nullptr) { + if (spec->grf_prop.HasSpriteGroups()) { DrawNewHouseTileInGUI(x, y, spec, house_id, view); return; } else {