From 30b1eb6e5fd7f3072d1a42cc175c6dadae188d69 Mon Sep 17 00:00:00 2001 From: frosch Date: Mon, 28 Apr 2025 23:24:42 +0200 Subject: [PATCH] Fix: [NewGRF] The result of Action123 evaluation affected rerandomisation in a weird corner case. (#14139) Rerandomisation does not care about the Resolve result. But we skipped it, in case of 'invalid SpriteGroup reference'. --- src/newgrf_engine.cpp | 3 +-- src/newgrf_house.cpp | 3 +-- src/newgrf_industrytiles.cpp | 3 +-- src/newgrf_roadstop.cpp | 3 +-- src/newgrf_spritegroup.h | 16 +++++++++++++++- src/newgrf_station.cpp | 3 +-- 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index f792866609..8ea7af4a34 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -1255,8 +1255,7 @@ static void DoTriggerVehicleRandomisation(Vehicle *v, VehicleRandomTrigger trigg v->waiting_random_triggers.Set(trigger); // store now for var 5F object.SetWaitingRandomTriggers(v->waiting_random_triggers); - const SpriteGroup *group = object.Resolve(); - if (group == nullptr) return; + object.ResolveRerandomisation(); /* Store remaining triggers. */ v->waiting_random_triggers.Reset(object.GetUsedRandomTriggers()); diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index d7dc676715..9390dc2bd8 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -675,8 +675,7 @@ static void DoTriggerHouseRandomisation(TileIndex tile, HouseRandomTrigger trigg SetHouseRandomTriggers(tile, waiting_random_triggers); // store now for var 5F object.SetWaitingRandomTriggers(waiting_random_triggers); - const SpriteGroup *group = object.Resolve(); - if (group == nullptr) return; + object.ResolveRerandomisation(); /* Store remaining triggers. */ waiting_random_triggers.Reset(object.GetUsedRandomTriggers()); diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index ac5838e759..bd078ac977 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -336,8 +336,7 @@ static void DoTriggerIndustryTileRandomisation(TileIndex tile, IndustryRandomTri SetIndustryRandomTriggers(tile, waiting_random_triggers); // store now for var 5F object.SetWaitingRandomTriggers(waiting_random_triggers); - const SpriteGroup *group = object.Resolve(); - if (group == nullptr) return; + object.ResolveRerandomisation(); /* Store remaining triggers. */ waiting_random_triggers.Reset(object.GetUsedRandomTriggers()); diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index ba98dc7691..75fad616e9 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -451,8 +451,7 @@ void TriggerRoadStopRandomisation(BaseStation *st, TileIndex tile, StationRandom RoadStopResolverObject object(ss, st, cur_tile, INVALID_ROADTYPE, GetStationType(cur_tile), GetStationGfx(cur_tile)); object.SetWaitingRandomTriggers(st->waiting_random_triggers); - const SpriteGroup *group = object.Resolve(); - if (group == nullptr) return; + object.ResolveRerandomisation(); used_random_triggers.Set(object.GetUsedRandomTriggers()); diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index 2b511cf131..45a4abd00b 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -336,13 +336,27 @@ public: return SpriteGroup::Resolve(this->root_spritegroup, *this); } + /** + * Resolve bits to be rerandomised. + * Access results via: + * - reseed: Bits to rerandomise per scope, for features with proper PARENT rerandomisation. (only industry tiles) + * - GetReseedSum: Bits to rerandomise for SELF scope, for features with broken-by-design PARENT randomisation. (all but industry tiles) + * - GetUsedRandomTriggers: Consumed random triggers to be reset. + */ + void ResolveRerandomisation() + { + /* The Resolve result has no meaning. + * It can be a SpriteSet, a callback result, or even an invalid SpriteGroup reference (nullptr). */ + this->Resolve(); + } + /** * Resolve callback. * @return Callback result. */ uint16_t ResolveCallback() { - const SpriteGroup *result = Resolve(); + const SpriteGroup *result = this->Resolve(); return result != nullptr ? result->GetCallbackResult() : CALLBACK_FAILED; } diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 0edd6ef9b8..524e73290c 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -996,8 +996,7 @@ void TriggerStationRandomisation(BaseStation *st, TileIndex trigger_tile, Statio StationResolverObject object(ss, st, tile, CBID_RANDOM_TRIGGER, 0); object.SetWaitingRandomTriggers(st->waiting_random_triggers); - const SpriteGroup *group = object.Resolve(); - if (group == nullptr) continue; + object.ResolveRerandomisation(); used_random_triggers.Set(object.GetUsedRandomTriggers());