Changeset - r15104:1752997daf93
[Not reviewed]
master
0 6 0
frosch - 14 years ago 2010-05-01 13:01:21
frosch@openttd.org
(svn r19743) -Fix: NewGrfs could access map bits of not yet constructed industries and houses during construction callbacks.
6 files changed with 48 insertions and 19 deletions:
0 comments (0 inline, 0 general)
src/newgrf_house.cpp
Show inline comments
 
@@ -99,20 +99,25 @@ void DecreaseBuildingCount(Town *t, Hous
 

	
 
static uint32 HouseGetRandomBits(const ResolverObject *object)
 
{
 
	const TileIndex tile = object->u.house.tile;
 
	return (tile == INVALID_TILE || !IsTileType(tile, MP_HOUSE)) ? 0 : GetHouseRandomBits(tile);
 
	/* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */
 
	TileIndex tile = object->u.house.tile;
 
	assert(IsValidTile(tile) && (object->u.house.not_yet_constructed || IsTileType(tile, MP_HOUSE)));
 
	return object->u.house.not_yet_constructed ? 0 : GetHouseRandomBits(tile);
 
}
 

	
 
static uint32 HouseGetTriggers(const ResolverObject *object)
 
{
 
	const TileIndex tile = object->u.house.tile;
 
	return (tile == INVALID_TILE || !IsTileType(tile, MP_HOUSE)) ? 0 : GetHouseTriggers(tile);
 
	/* Note: Towns build houses over houses. So during construction checks 'tile' may be a valid but unrelated house. */
 
	TileIndex tile = object->u.house.tile;
 
	assert(IsValidTile(tile) && (object->u.house.not_yet_constructed || IsTileType(tile, MP_HOUSE)));
 
	return object->u.house.not_yet_constructed ? 0 : GetHouseTriggers(tile);
 
}
 

	
 
static void HouseSetTriggers(const ResolverObject *object, int triggers)
 
{
 
	const TileIndex tile = object->u.house.tile;
 
	if (IsTileType(tile, MP_HOUSE)) SetHouseTriggers(tile, triggers);
 
	TileIndex tile = object->u.house.tile;
 
	assert(!object->u.house.not_yet_constructed && IsValidTile(tile) && IsTileType(tile, MP_HOUSE));
 
	SetHouseTriggers(tile, triggers);
 
}
 

	
 
static uint32 GetNumHouses(HouseID house_id, const Town *town)
 
@@ -370,6 +375,7 @@ static void NewHouseResolver(ResolverObj
 
	res->u.house.tile     = tile;
 
	res->u.house.town     = town;
 
	res->u.house.house_id = house_id;
 
	res->u.house.not_yet_constructed = false;
 

	
 
	res->callback        = CBID_NO_CALLBACK;
 
	res->callback_param1 = 0;
 
@@ -383,15 +389,18 @@ static void NewHouseResolver(ResolverObj
 
	res->grffile         = (hs != NULL ? hs->grffile : NULL);
 
}
 

	
 
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile)
 
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile, bool not_yet_constructed)
 
{
 
	ResolverObject object;
 
	const SpriteGroup *group;
 

	
 
	assert(IsValidTile(tile) && (not_yet_constructed || IsTileType(tile, MP_HOUSE)));
 

	
 
	NewHouseResolver(&object, house_id, tile, town);
 
	object.callback = callback;
 
	object.callback_param1 = param1;
 
	object.callback_param2 = param2;
 
	object.u.house.not_yet_constructed = not_yet_constructed;
 

	
 
	group = SpriteGroup::Resolve(HouseSpec::Get(house_id)->spritegroup, &object);
 
	if (group == NULL) return CALLBACK_FAILED;
src/newgrf_house.h
Show inline comments
 
@@ -44,7 +44,7 @@ void DrawNewHouseTile(TileInfo *ti, Hous
 
void AnimateNewHouseTile(TileIndex tile);
 
void ChangeHouseAnimationFrame(const struct GRFFile *file, TileIndex tile, uint16 callback_result);
 

	
 
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile);
 
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town, TileIndex tile, bool not_yet_constructed = false);
 

	
 
bool CanDeleteHouse(TileIndex tile);
 

	
src/newgrf_industries.cpp
Show inline comments
 
@@ -345,18 +345,23 @@ static const SpriteGroup *IndustryResolv
 

	
 
static uint32 IndustryGetRandomBits(const ResolverObject *object)
 
{
 
	return object->u.industry.ind == NULL ? 0 : object->u.industry.ind->random;
 
	const Industry *ind = object->u.industry.ind;
 
	assert(ind != NULL);
 
	return ind->random;
 
}
 

	
 
static uint32 IndustryGetTriggers(const ResolverObject *object)
 
{
 
	return object->u.industry.ind == NULL ? 0 : object->u.industry.ind->random_triggers;
 
	const Industry *ind = object->u.industry.ind;
 
	assert(ind != NULL);
 
	return ind->random_triggers;
 
}
 

	
 
static void IndustrySetTriggers(const ResolverObject *object, int triggers)
 
{
 
	if (object->u.industry.ind == NULL) return;
 
	object->u.industry.ind->random_triggers = triggers;
 
	Industry *ind = object->u.industry.ind;
 
	assert(ind != NULL && ind->index != INVALID_INDUSTRY);
 
	ind->random_triggers = triggers;
 
}
 

	
 
static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus, IndustryType type)
src/newgrf_industrytiles.cpp
Show inline comments
 
@@ -118,26 +118,35 @@ static const SpriteGroup *IndustryTileRe
 
static uint32 IndustryTileGetRandomBits(const ResolverObject *object)
 
{
 
	const TileIndex tile = object->u.industry.tile;
 
	if (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) return 0;
 
	return (object->scope == VSG_SCOPE_SELF) ? GetIndustryRandomBits(tile) : Industry::GetByTile(tile)->random;
 
	const Industry *ind = object->u.industry.ind;
 
	assert(ind != NULL && IsValidTile(tile));
 
	assert(ind->index == INVALID_INDUSTRY || IsTileType(tile, MP_INDUSTRY));
 

	
 
	return (object->scope == VSG_SCOPE_SELF) ?
 
			(ind->index != INVALID_INDUSTRY ? GetIndustryRandomBits(tile) : 0) :
 
			ind->random;
 
}
 

	
 
static uint32 IndustryTileGetTriggers(const ResolverObject *object)
 
{
 
	const TileIndex tile = object->u.industry.tile;
 
	if (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) return 0;
 
	return (object->scope == VSG_SCOPE_SELF) ? GetIndustryTriggers(tile) : Industry::GetByTile(tile)->random_triggers;
 
	const Industry *ind = object->u.industry.ind;
 
	assert(ind != NULL && IsValidTile(tile));
 
	assert(ind->index == INVALID_INDUSTRY || IsTileType(tile, MP_INDUSTRY));
 
	if (ind->index == INVALID_INDUSTRY) return 0;
 
	return (object->scope == VSG_SCOPE_SELF) ? GetIndustryTriggers(tile) : ind->random_triggers;
 
}
 

	
 
static void IndustryTileSetTriggers(const ResolverObject *object, int triggers)
 
{
 
	const TileIndex tile = object->u.industry.tile;
 
	if (tile == INVALID_TILE || !IsTileType(tile, MP_INDUSTRY)) return;
 
	Industry *ind = object->u.industry.ind;
 
	assert(ind != NULL && ind->index != INVALID_INDUSTRY && IsValidTile(tile) && IsTileType(tile, MP_INDUSTRY));
 

	
 
	if (object->scope == VSG_SCOPE_SELF) {
 
		SetIndustryTriggers(tile, triggers);
 
	} else {
 
		Industry::GetByTile(tile)->random_triggers = triggers;
 
		ind->random_triggers = triggers;
 
	}
 
}
 

	
 
@@ -194,6 +203,9 @@ uint16 GetIndustryTileCallback(CallbackI
 
	ResolverObject object;
 
	const SpriteGroup *group;
 

	
 
	assert(industry != NULL && IsValidTile(tile));
 
	assert(industry->index == INVALID_INDUSTRY || IsTileType(tile, MP_INDUSTRY));
 

	
 
	NewIndustryTileResolver(&object, gfx_id, tile, industry);
 
	object.callback = callback;
 
	object.callback_param1 = param1;
 
@@ -396,6 +408,8 @@ static void DoTriggerIndustryTile(TileIn
 
{
 
	ResolverObject object;
 

	
 
	assert(IsValidTile(tile) && IsTileType(tile, MP_INDUSTRY));
 

	
 
	IndustryGfx gfx = GetIndustryGfx(tile);
 
	const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
 

	
src/newgrf_spritegroup.h
Show inline comments
 
@@ -319,6 +319,7 @@ struct ResolverObject {
 
			TileIndex tile;
 
			Town *town;
 
			HouseID house_id;
 
			bool not_yet_constructed;      ///< True for construction check
 
		} house;
 
		struct {
 
			TileIndex tile;
src/town_cmd.cpp
Show inline comments
 
@@ -2165,7 +2165,7 @@ static bool BuildTownHouse(Town *t, Tile
 
		}
 

	
 
		if (HasBit(hs->callback_mask, CBM_HOUSE_ALLOW_CONSTRUCTION)) {
 
			uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile);
 
			uint16 callback_res = GetHouseCallback(CBID_HOUSE_ALLOW_CONSTRUCTION, 0, 0, house, t, tile, true);
 
			if (callback_res != CALLBACK_FAILED && GB(callback_res, 0, 8) == 0) continue;
 
		}
 

	
0 comments (0 inline, 0 general)