diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index 7ffb05e11c..42a9a8717f 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -338,6 +338,7 @@ enum SpriteGroupCallbacksUsed : uint8 { SGCU_ALL = 0xFF, SGCU_VEHICLE_32DAY_CALLBACK = 1 << 0, SGCU_VEHICLE_REFIT_COST = 1 << 1, + SGCU_RANDOM_TRIGGER = 1 << 2, }; DECLARE_ENUM_AS_BIT_SET(SpriteGroupCallbacksUsed) diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index ce49977563..aaf5792fd5 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -1378,19 +1378,28 @@ static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_rando /* We can't trigger a non-existent vehicle... */ assert(v != nullptr); - VehicleResolverObject object(v->engine_type, v, VehicleResolverObject::WO_CACHED, false, CBID_RANDOM_TRIGGER); - object.waiting_triggers = v->waiting_triggers | trigger; - v->waiting_triggers = object.waiting_triggers; // store now for var 5F + uint32 reseed = 0; + if (Engine::Get(v->engine_type)->callbacks_used & SGCU_RANDOM_TRIGGER) { + VehicleResolverObject object(v->engine_type, v, VehicleResolverObject::WO_CACHED, false, CBID_RANDOM_TRIGGER); + object.waiting_triggers = v->waiting_triggers | trigger; + v->waiting_triggers = object.waiting_triggers; // store now for var 5F - const SpriteGroup *group = object.Resolve(); - if (group == nullptr) return; + const SpriteGroup *group = object.Resolve(); + if (group == nullptr) return; - /* Store remaining triggers. */ - v->waiting_triggers = object.GetRemainingTriggers(); + /* Store remaining triggers. */ + v->waiting_triggers = object.GetRemainingTriggers(); + + reseed = object.GetReseedSum(); + } else { + v->waiting_triggers |= trigger; + + const Engine *e = Engine::Get(v->engine_type); + if (!(e->grf_prop.spritegroup[v->cargo_type] || e->grf_prop.spritegroup[CT_DEFAULT])) return; + } /* Rerandomise bits. Scopes other than SELF are invalid for rerandomisation. For bug-to-bug-compatibility with TTDP we ignore the scope. */ byte new_random_bits = Random(); - uint32 reseed = object.GetReseedSum(); v->random_bits &= ~reseed; v->random_bits |= (first ? new_random_bits : base_random_bits) & reseed; diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index f26b30062c..d79f44e7ee 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.cpp @@ -341,6 +341,10 @@ void DeterministicSpriteGroup::AnalyseCallbacks(AnalyseCallbackOperation &op) co op.callbacks_used |= SGCU_VEHICLE_REFIT_COST; break; + case CBID_RANDOM_TRIGGER: + op.callbacks_used |= SGCU_RANDOM_TRIGGER; + break; + case CBID_VEHICLE_MODIFY_PROPERTY: if (range.group != nullptr) { AnalyseCallbackOperation cb36_op; @@ -433,6 +437,10 @@ const SpriteGroup *RandomizedSpriteGroup::Resolve(ResolverObject &object) const return SpriteGroup::Resolve(this->groups[index], object, false); } +void RandomizedSpriteGroup::AnalyseCallbacks(AnalyseCallbackOperation &op) const +{ + if (op.mode == ACOM_CB_VAR) op.callbacks_used |= SGCU_RANDOM_TRIGGER; +} const SpriteGroup *RealSpriteGroup::Resolve(ResolverObject &object) const { diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index edd3df0f0e..4f9f1e5fe1 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -219,6 +219,8 @@ struct RandomizedSpriteGroup : SpriteGroup { std::vector groups; ///< Take the group with appropriate index: + void AnalyseCallbacks(AnalyseCallbackOperation &op) const override; + protected: const SpriteGroup *Resolve(ResolverObject &object) const; };