summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/newgrf_engine.cpp24
-rw-r--r--src/newgrf_engine.h1
-rw-r--r--src/newgrf_house.cpp15
-rw-r--r--src/newgrf_house.h1
-rw-r--r--src/newgrf_industries.cpp6
-rw-r--r--src/newgrf_industries.h1
-rw-r--r--src/newgrf_industrytiles.cpp13
-rw-r--r--src/newgrf_industrytiles.h1
-rw-r--r--src/newgrf_spritegroup.cpp18
-rw-r--r--src/newgrf_spritegroup.h17
-rw-r--r--src/newgrf_station.cpp17
-rw-r--r--src/newgrf_station.h1
12 files changed, 43 insertions, 72 deletions
diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp
index 8dd8d545a..94c8df1d1 100644
--- a/src/newgrf_engine.cpp
+++ b/src/newgrf_engine.cpp
@@ -347,21 +347,6 @@ static byte MapAircraftMovementAction(const Aircraft *v)
return this->v == NULL ? 0 : this->v->waiting_triggers;
}
-/* virtual */ void VehicleScopeResolver::SetTriggers(int triggers) const
-{
- /* Evil cast to get around const-ness. This used to be achieved by an
- * innocent looking function pointer cast... Currently I cannot see a
- * way of avoiding this without removing consts deep within gui code.
- */
- Vehicle *v = const_cast<Vehicle *>(this->v);
-
- /* This function must only be called when processing triggers -- any
- * other time is an error. */
- assert(this->ro.trigger != 0);
-
- if (v != NULL) v->waiting_triggers = triggers;
-}
-
/* virtual */ ScopeResolver *VehicleResolverObject::GetScope(VarSpriteGroupScope scope, byte relative)
{
@@ -1140,13 +1125,18 @@ static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_rando
assert(v != NULL);
VehicleResolverObject object(v->engine_type, v, VehicleResolverObject::WO_CACHED, false, CBID_RANDOM_TRIGGER);
- object.trigger = 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 == NULL) return;
+ /* Store remaining triggers. */
+ v->waiting_triggers = object.GetRemainingTriggers();
+
+ /* 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(); // The scope only affects triggers, not the reseeding
+ uint32 reseed = object.GetReseedSum();
v->random_bits &= ~reseed;
v->random_bits |= (first ? new_random_bits : base_random_bits) & reseed;
diff --git a/src/newgrf_engine.h b/src/newgrf_engine.h
index 3c8108737..6406b0f4e 100644
--- a/src/newgrf_engine.h
+++ b/src/newgrf_engine.h
@@ -33,7 +33,6 @@ struct VehicleScopeResolver : public ScopeResolver {
/* virtual */ uint32 GetRandomBits() const;
/* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
/* virtual */ uint32 GetTriggers() const;
- /* virtual */ void SetTriggers(int triggers) const;
};
/** Resolver for a vehicle (chain) */
diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp
index 2bc85f9ac..bcd83f2f1 100644
--- a/src/newgrf_house.cpp
+++ b/src/newgrf_house.cpp
@@ -169,12 +169,6 @@ void DecreaseBuildingCount(Town *t, HouseID house_id)
return this->not_yet_constructed ? 0 : GetHouseTriggers(this->tile);
}
-/* virtual */ void HouseScopeResolver::SetTriggers(int triggers) const
-{
- assert(!this->not_yet_constructed && IsValidTile(this->tile) && IsTileType(this->tile, MP_HOUSE));
- SetHouseTriggers(this->tile, triggers);
-}
-
static uint32 GetNumHouses(HouseID house_id, const Town *town)
{
uint8 map_id_count, town_id_count, map_class_count, town_class_count;
@@ -613,14 +607,19 @@ static void DoTriggerHouse(TileIndex tile, HouseTrigger trigger, byte base_rando
if (hs->grf_prop.spritegroup[0] == NULL) return;
HouseResolverObject object(hid, tile, Town::GetByTile(tile), CBID_RANDOM_TRIGGER);
- object.trigger = trigger;
+ object.waiting_triggers = GetHouseTriggers(tile) | trigger;
+ SetHouseTriggers(tile, object.waiting_triggers); // store now for var 5F
const SpriteGroup *group = object.Resolve();
if (group == NULL) return;
+ /* Store remaining triggers. */
+ SetHouseTriggers(tile, object.GetRemainingTriggers());
+
+ /* Rerandomise bits. Scopes other than SELF are invalid for houses. For bug-to-bug-compatibility with TTDP we ignore the scope. */
byte new_random_bits = Random();
byte random_bits = GetHouseRandomBits(tile);
- uint32 reseed = object.GetReseedSum(); // The scope only affects triggers, not the reseeding
+ uint32 reseed = object.GetReseedSum();
random_bits &= ~reseed;
random_bits |= (first ? new_random_bits : base_random) & reseed;
SetHouseRandomBits(tile, random_bits);
diff --git a/src/newgrf_house.h b/src/newgrf_house.h
index 37c167947..efc0c6cbb 100644
--- a/src/newgrf_house.h
+++ b/src/newgrf_house.h
@@ -33,7 +33,6 @@ struct HouseScopeResolver : public ScopeResolver {
/* virtual */ uint32 GetRandomBits() const;
/* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
/* virtual */ uint32 GetTriggers() const;
- /* virtual */ void SetTriggers(int triggers) const;
};
/** Resolver object to be used for houses (feature 07 spritegroups). */
diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp
index e8486e760..f0c8dd3b7 100644
--- a/src/newgrf_industries.cpp
+++ b/src/newgrf_industries.cpp
@@ -383,12 +383,6 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout
return this->industry != NULL ? this->industry->random_triggers : 0;
}
-/* virtual */ void IndustriesScopeResolver::SetTriggers(int triggers) const
-{
- assert(this->industry != NULL && this->industry->index != INVALID_INDUSTRY);
- this->industry->random_triggers = triggers;
-}
-
/* virtual */ void IndustriesScopeResolver::StorePSA(uint pos, int32 value)
{
if (this->industry->index == INVALID_INDUSTRY) return;
diff --git a/src/newgrf_industries.h b/src/newgrf_industries.h
index 94a502166..45b0333a6 100644
--- a/src/newgrf_industries.h
+++ b/src/newgrf_industries.h
@@ -26,7 +26,6 @@ struct IndustriesScopeResolver : public ScopeResolver {
/* virtual */ uint32 GetRandomBits() const;
/* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
/* virtual */ uint32 GetTriggers() const;
- /* virtual */ void SetTriggers(int triggers) const;
/* virtual */ void StorePSA(uint pos, int32 value);
};
diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp
index 90a17550d..b4b8f77c4 100644
--- a/src/newgrf_industrytiles.cpp
+++ b/src/newgrf_industrytiles.cpp
@@ -117,12 +117,6 @@ uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile)
return GetIndustryTriggers(this->tile);
}
-/* virtual */ void IndustryTileScopeResolver::SetTriggers(int triggers) const
-{
- assert(this->industry != NULL && this->industry->index != INVALID_INDUSTRY && IsValidTile(this->tile) && IsTileType(this->tile, MP_INDUSTRY));
- SetIndustryTriggers(this->tile, triggers);
-}
-
/**
* Get the associated NewGRF file from the industry graphics.
* @param gfx Graphics to query.
@@ -326,11 +320,16 @@ static void DoTriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger, I
if (itspec->grf_prop.spritegroup[0] == NULL) return;
IndustryTileResolverObject object(gfx, tile, ind, CBID_RANDOM_TRIGGER);
- object.trigger = trigger;
+ object.waiting_triggers = GetIndustryTriggers(tile) | trigger;
+ SetIndustryTriggers(tile, object.waiting_triggers); // store now for var 5F
const SpriteGroup *group = object.Resolve();
if (group == NULL) return;
+ /* Store remaining triggers. */
+ SetIndustryTriggers(tile, object.GetRemainingTriggers());
+
+ /* Rerandomise tile bits */
byte new_random_bits = Random();
byte random_bits = GetIndustryRandomBits(tile);
random_bits &= ~object.reseed[VSG_SCOPE_SELF];
diff --git a/src/newgrf_industrytiles.h b/src/newgrf_industrytiles.h
index 394f75e1c..2af064054 100644
--- a/src/newgrf_industrytiles.h
+++ b/src/newgrf_industrytiles.h
@@ -26,7 +26,6 @@ struct IndustryTileScopeResolver : public ScopeResolver {
/* virtual */ uint32 GetRandomBits() const;
/* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
/* virtual */ uint32 GetTriggers() const;
- /* virtual */ void SetTriggers(int triggers) const;
};
/** Resolver for industry tiles. */
diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp
index c6fcd0a9e..a838a1388 100644
--- a/src/newgrf_spritegroup.cpp
+++ b/src/newgrf_spritegroup.cpp
@@ -110,12 +110,6 @@ ScopeResolver::~ScopeResolver() {}
}
/**
- * Set the triggers. Base class implementation does nothing.
- * @param triggers Triggers to set.
- */
-/* virtual */ void ScopeResolver::SetTriggers(int triggers) const {}
-
-/**
* Get a variable value. Default implementation has no available variables.
* @param variable Variable to read
* @param parameter Parameter for 60+x variables
@@ -304,21 +298,15 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con
const SpriteGroup *RandomizedSpriteGroup::Resolve(ResolverObject &object) const
{
ScopeResolver *scope = object.GetScope(this->var_scope, this->count);
- if (object.trigger != 0) {
+ if (object.callback == CBID_RANDOM_TRIGGER) {
/* Handle triggers */
- /* Magic code that may or may not do the right things... */
- byte waiting_triggers = scope->GetTriggers();
- byte match = this->triggers & (waiting_triggers | object.trigger);
+ byte match = this->triggers & object.waiting_triggers;
bool res = (this->cmp_mode == RSG_CMP_ANY) ? (match != 0) : (match == this->triggers);
if (res) {
- waiting_triggers &= ~match;
+ object.used_triggers |= match;
object.reseed[this->var_scope] |= (this->num_groups - 1) << this->lowest_randbit;
- } else {
- waiting_triggers |= object.trigger;
}
-
- scope->SetTriggers(waiting_triggers);
}
uint32 mask = (this->num_groups - 1) << this->lowest_randbit;
diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h
index 0a7705d66..a0ae6ce51 100644
--- a/src/newgrf_spritegroup.h
+++ b/src/newgrf_spritegroup.h
@@ -293,7 +293,6 @@ struct ScopeResolver {
virtual uint32 GetRandomBits() const;
virtual uint32 GetTriggers() const;
- virtual void SetTriggers(int triggers) const;
virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
virtual void StorePSA(uint reg, int32 value);
@@ -315,9 +314,10 @@ struct ResolverObject {
uint32 callback_param1; ///< First parameter (var 10) of the callback.
uint32 callback_param2; ///< Second parameter (var 18) of the callback.
- byte trigger;
-
uint32 last_value; ///< Result of most recent DeterministicSpriteGroup (including procedure calls)
+
+ uint32 waiting_triggers; ///< Waiting triggers to be used by any rerandomisation. (scope independent)
+ uint32 used_triggers; ///< Subset of cur_triggers, which actually triggered some rerandomisation. (scope independent)
uint32 reseed[VSG_END]; ///< Collects bits to rerandomise while triggering triggers.
const GRFFile *grffile; ///< GRFFile the resolved SpriteGroup belongs to
@@ -347,6 +347,14 @@ struct ResolverObject {
virtual ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0);
/**
+ * Returns the waiting triggers that did not trigger any rerandomisation.
+ */
+ uint32 GetRemainingTriggers() const
+ {
+ return this->waiting_triggers & ~this->used_triggers;
+ }
+
+ /**
* Returns the OR-sum of all bits that need reseeding
* independent of the scope they were accessed with.
* @return OR-sum of the bits.
@@ -367,7 +375,8 @@ struct ResolverObject {
void ResetState()
{
this->last_value = 0;
- this->trigger = 0;
+ this->waiting_triggers = 0;
+ this->used_triggers = 0;
memset(this->reseed, 0, sizeof(this->reseed));
}
};
diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp
index cd5dad7b4..091182185 100644
--- a/src/newgrf_station.cpp
+++ b/src/newgrf_station.cpp
@@ -235,13 +235,6 @@ static uint32 GetRailContinuationInfo(TileIndex tile)
}
-/* virtual */ void StationScopeResolver::SetTriggers(int triggers) const
-{
- BaseStation *st = const_cast<BaseStation *>(this->st);
- assert(st != NULL);
- st->waiting_triggers = triggers;
-}
-
/**
* Station variable cache
* This caches 'expensive' station variable lookups which iterate over
@@ -997,8 +990,9 @@ void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigg
}
}
- /* Convert trigger to bit */
- uint8 trigger_bit = 1 << trigger;
+ /* Store triggers now for var 5F */
+ SetBit(st->waiting_triggers, trigger);
+ uint32 used_triggers = 0;
/* Check all tiles over the station to check if the specindex is still in use */
TILE_AREA_LOOP(tile, area) {
@@ -1014,11 +1008,13 @@ void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigg
if (cargo_type == CT_INVALID || HasBit(ss->cargo_triggers, cargo_type)) {
StationResolverObject object(ss, st, tile, CBID_RANDOM_TRIGGER, 0);
- object.trigger = trigger_bit;
+ object.waiting_triggers = st->waiting_triggers;
const SpriteGroup *group = object.Resolve();
if (group == NULL) continue;
+ used_triggers |= object.used_triggers;
+
uint32 reseed = object.GetReseedSum();
if (reseed != 0) {
whole_reseed |= reseed;
@@ -1037,6 +1033,7 @@ void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigg
}
/* Update whole station random bits */
+ st->waiting_triggers &= ~used_triggers;
if ((whole_reseed & 0xFFFF) != 0) {
st->random_bits &= ~whole_reseed;
st->random_bits |= Random() & whole_reseed;
diff --git a/src/newgrf_station.h b/src/newgrf_station.h
index b9333c105..f6a39efb1 100644
--- a/src/newgrf_station.h
+++ b/src/newgrf_station.h
@@ -34,7 +34,6 @@ struct StationScopeResolver : public ScopeResolver {
/* virtual */ uint32 GetRandomBits() const;
/* virtual */ uint32 GetTriggers() const;
- /* virtual */ void SetTriggers(int triggers) const;
/* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
};