Changeset - r17834:447b5cb3ee1a
[Not reviewed]
master
0 5 0
frosch - 13 years ago 2011-07-04 20:37:20
frosch@openttd.org
(svn r22635) -Fix: Correctly reseed random bits of industries and industry tiles.
5 files changed with 74 insertions and 17 deletions:
0 comments (0 inline, 0 general)
src/newgrf_engine.cpp
Show inline comments
 
@@ -1070,8 +1070,9 @@ static void DoTriggerVehicle(Vehicle *v,
 
	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:
src/newgrf_house.cpp
Show inline comments
 
@@ -606,8 +606,9 @@ static void DoTriggerHouse(TileIndex til
 

	
 
	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) {
src/newgrf_industrytiles.cpp
Show inline comments
 
@@ -369,7 +369,14 @@ bool StartStopIndustryTileAnimation(cons
 
	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(TileIn
 

	
 
	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);
 
}
 

	
 
/**
src/newgrf_spritegroup.cpp
Show inline comments
 
@@ -207,7 +207,7 @@ const SpriteGroup *RandomizedSpriteGroup
 

	
 
		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;
 
		}
src/newgrf_spritegroup.h
Show inline comments
 
@@ -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));
 
	}
 
};
 

	
0 comments (0 inline, 0 general)