summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfrosch <frosch@openttd.org>2011-07-04 20:37:20 +0000
committerfrosch <frosch@openttd.org>2011-07-04 20:37:20 +0000
commit8930337aaec29771b991f2f89f7b7279466278a8 (patch)
tree3e89fb9bace9fa113eeec8c9cff7c32dec4f2f2a
parent8b18292a2ec1be31d7c1fe7cfcba26facb9c7ada (diff)
downloadopenttd-8930337aaec29771b991f2f89f7b7279466278a8.tar.xz
(svn r22635) -Fix: Correctly reseed random bits of industries and industry tiles.
-rw-r--r--src/newgrf_engine.cpp5
-rw-r--r--src/newgrf_house.cpp5
-rw-r--r--src/newgrf_industrytiles.cpp48
-rw-r--r--src/newgrf_spritegroup.cpp2
-rw-r--r--src/newgrf_spritegroup.h31
5 files changed, 74 insertions, 17 deletions
diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp
index 0491ec762..f2f28883a 100644
--- a/src/newgrf_engine.cpp
+++ b/src/newgrf_engine.cpp
@@ -1070,8 +1070,9 @@ static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_rando
if (group == NULL) return;
new_random_bits = Random();
- v->random_bits &= ~object.reseed;
- v->random_bits |= (first ? new_random_bits : base_random_bits) & object.reseed;
+ uint32 reseed = object.GetReseedSum(); // The scope only affects triggers, not the reseeding
+ v->random_bits &= ~reseed;
+ v->random_bits |= (first ? new_random_bits : base_random_bits) & reseed;
switch (trigger) {
case VEHICLE_TRIGGER_NEW_CARGO:
diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp
index f6e1d3790..04a0d8617 100644
--- a/src/newgrf_house.cpp
+++ b/src/newgrf_house.cpp
@@ -606,8 +606,9 @@ static void DoTriggerHouse(TileIndex tile, HouseTrigger trigger, byte base_rando
byte new_random_bits = Random();
byte random_bits = GetHouseRandomBits(tile);
- random_bits &= ~object.reseed;
- random_bits |= (first ? new_random_bits : base_random) & object.reseed;
+ uint32 reseed = object.GetReseedSum(); // The scope only affects triggers, not the reseeding
+ random_bits &= ~reseed;
+ random_bits |= (first ? new_random_bits : base_random) & reseed;
SetHouseRandomBits(tile, random_bits);
switch (trigger) {
diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp
index 74a48cd3b..1191f3162 100644
--- a/src/newgrf_industrytiles.cpp
+++ b/src/newgrf_industrytiles.cpp
@@ -369,7 +369,14 @@ bool StartStopIndustryTileAnimation(const Industry *ind, IndustryAnimationTrigge
return ret;
}
-static void DoTriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger, Industry *ind)
+/**
+ * Trigger random triggers for an industry tile and reseed its random bits.
+ * @param tile Industry tile to trigger.
+ * @param trigger Trigger to trigger.
+ * @param ind Industry of the tile.
+ * @param [in,out] reseed_industry Collects bits to reseed for the industry.
+ */
+static void DoTriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger, Industry *ind, uint32 &reseed_industry)
{
ResolverObject object;
@@ -390,24 +397,55 @@ static void DoTriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger, I
byte new_random_bits = Random();
byte random_bits = GetIndustryRandomBits(tile);
- random_bits &= ~object.reseed;
- random_bits |= new_random_bits & object.reseed;
+ random_bits &= ~object.reseed[VSG_SCOPE_SELF];
+ random_bits |= new_random_bits & object.reseed[VSG_SCOPE_SELF];
SetIndustryRandomBits(tile, random_bits);
MarkTileDirtyByTile(tile);
+
+ reseed_industry |= object.reseed[VSG_SCOPE_PARENT];
}
+/**
+ * Reseeds the random bits of an industry.
+ * @param ind Industry.
+ * @param reseed Bits to reseed.
+ */
+static void DoReseedIndustry(Industry *ind, uint32 reseed)
+{
+ if (reseed == 0 || ind == NULL) return;
+
+ uint16 random_bits = Random();
+ ind->random &= reseed;
+ ind->random |= random_bits & reseed;
+}
+
+/**
+ * Trigger a random trigger for a single industry tile.
+ * @param tile Industry tile to trigger.
+ * @param trigger Trigger to trigger.
+ */
void TriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger)
{
- DoTriggerIndustryTile(tile, trigger, Industry::GetByTile(tile));
+ uint32 reseed_industry = 0;
+ Industry *ind = Industry::GetByTile(tile);
+ DoTriggerIndustryTile(tile, trigger, ind, reseed_industry);
+ DoReseedIndustry(ind, reseed_industry);
}
+/**
+ * Trigger a random trigger for all industry tiles.
+ * @param ind Industry to trigger.
+ * @param trigger Trigger to trigger.
+ */
void TriggerIndustry(Industry *ind, IndustryTileTrigger trigger)
{
+ uint32 reseed_industry = 0;
TILE_AREA_LOOP(tile, ind->location) {
if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == ind->index) {
- DoTriggerIndustryTile(tile, trigger, ind);
+ DoTriggerIndustryTile(tile, trigger, ind, reseed_industry);
}
}
+ DoReseedIndustry(ind, reseed_industry);
}
/**
diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp
index a327a3be1..387366352 100644
--- a/src/newgrf_spritegroup.cpp
+++ b/src/newgrf_spritegroup.cpp
@@ -207,7 +207,7 @@ const SpriteGroup *RandomizedSpriteGroup::Resolve(ResolverObject *object) const
if (res) {
waiting_triggers &= ~match;
- object->reseed |= (this->num_groups - 1) << this->lowest_randbit;
+ object->reseed[this->var_scope] |= (this->num_groups - 1) << this->lowest_randbit;
} else {
waiting_triggers |= object->trigger;
}
diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h
index bf72e96ce..d18ad643f 100644
--- a/src/newgrf_spritegroup.h
+++ b/src/newgrf_spritegroup.h
@@ -122,12 +122,15 @@ protected:
/* Shared by deterministic and random groups. */
enum VarSpriteGroupScope {
- VSG_SCOPE_SELF,
- /* Engine of consists for vehicles, city for stations. */
- VSG_SCOPE_PARENT,
- /* Any vehicle in the consist (vehicles only) */
- VSG_SCOPE_RELATIVE,
+ VSG_BEGIN,
+
+ VSG_SCOPE_SELF = VSG_BEGIN, ///< Resolved object itself
+ VSG_SCOPE_PARENT, ///< Related object of the resolved one
+ VSG_SCOPE_RELATIVE, ///< Relative position (vehicles only)
+
+ VSG_END
};
+DECLARE_POSTFIX_INCREMENT(VarSpriteGroupScope)
enum DeterministicSpriteGroupSize {
DSG_SIZE_BYTE,
@@ -309,7 +312,7 @@ struct ResolverObject {
byte trigger;
uint32 last_value; ///< Result of most recent DeterministicSpriteGroup (including procedure calls)
- uint32 reseed; ///< Collects bits to rerandomise while triggering triggers.
+ uint32 reseed[VSG_END]; ///< Collects bits to rerandomise while triggering triggers.
VarSpriteGroupScope scope; ///< Scope of currently resolved DeterministicSpriteGroup resp. RandomizedSpriteGroup
byte count; ///< Additional scope for RandomizedSpriteGroup
@@ -383,6 +386,20 @@ struct ResolverObject {
void (*StorePSA)(struct ResolverObject*, uint, int32);
/**
+ * Returns the OR-sum of all bits that need reseeding
+ * independent of the scope they were accessed with.
+ * @return OR-sum of the bits.
+ */
+ uint32 GetReseedSum() const
+ {
+ uint32 sum = 0;
+ for (VarSpriteGroupScope vsg = VSG_BEGIN; vsg < VSG_END; vsg++) {
+ sum |= this->reseed[vsg];
+ }
+ return sum;
+ }
+
+ /**
* Resets the dynamic state of the resolver object.
* To be called before resolving an Action-1-2-3 chain.
*/
@@ -390,7 +407,7 @@ struct ResolverObject {
{
this->last_value = 0;
this->trigger = 0;
- this->reseed = 0;
+ memset(this->reseed, 0, sizeof(this->reseed));
}
};