(svn r11152) -Fix: GetIndustryIDAtOffset crashed when translation of the GFX ID would be needed. Fix by Belugas.

-Fix: GetIndustryIDAtOffset crashed when the industry->xy tile was not an industry tile.
This commit is contained in:
rubidium 2007-09-23 19:55:42 +00:00
parent 4dca543135
commit fc371ad994
4 changed files with 46 additions and 42 deletions

View File

@ -124,6 +124,12 @@ static inline void SetIndustryConstructionStage(TileIndex tile, byte value)
SB(_m[tile].m1, 0, 2, value);
}
static inline IndustryGfx GetCleanIndustryGfx(TileIndex t)
{
assert(IsTileType(t, MP_INDUSTRY));
return _m[t].m5 | (GB(_m[t].m6, 2, 1) << 8);
}
/**
* Get the industry graphics ID for the given industry tile
* @param t the tile to get the gfx for
@ -133,7 +139,7 @@ static inline void SetIndustryConstructionStage(TileIndex tile, byte value)
static inline IndustryGfx GetIndustryGfx(TileIndex t)
{
assert(IsTileType(t, MP_INDUSTRY));
return GetTranslatedIndustryTileID(_m[t].m5 | (GB(_m[t].m6, 2, 1) << 8));
return GetTranslatedIndustryTileID(GetCleanIndustryGfx(t));
}
/**
@ -145,7 +151,8 @@ static inline IndustryGfx GetIndustryGfx(TileIndex t)
static inline void SetIndustryGfx(TileIndex t, IndustryGfx gfx)
{
assert(IsTileType(t, MP_INDUSTRY));
_m[t].m5 = gfx;
_m[t].m5 = GB(gfx, 0, 8);
SB(_m[t].m6, 2, 1, GB(gfx, 8, 1));
}
/**

View File

@ -78,47 +78,44 @@ static uint GetClosestWaterDistance(TileIndex tile, bool water)
/** Make an analysis of a tile and check for its belonging to the same
* industry, and/or the same grf file
* @param new_tile TileIndex of the tile to query
* @param old_tile TileIndex of the reference tile
* @param i Industry to which old_tile belongs to
* @param tile TileIndex of the tile to query
* @param i Industry to which to compare the tile to
* @return value encoded as per NFO specs */
uint32 GetIndustryIDAtOffset(TileIndex new_tile, TileIndex old_tile, const Industry *i)
uint32 GetIndustryIDAtOffset(TileIndex tile, const Industry *i)
{
if (IsTileType(new_tile, MP_INDUSTRY)) { // Is this an industry tile?
if (GetIndustryIndex(new_tile) == i->index) { // Does it belong to the same industry?
IndustryGfx gfx = GetIndustryGfx(new_tile);
const IndustryTileSpec *indtsp = GetIndustryTileSpec(gfx);
const IndustryTileSpec *indold = GetIndustryTileSpec(GetIndustryGfx(old_tile));
if (gfx < NEW_INDUSTRYOFFSET) { // Does it belongs to an old type?
/* It is an old tile. We have to see if it's been overriden */
if (indtsp->grf_prop.override == INVALID_INDUSTRYTILE) { // has it been overridden?
return 0xFF << 8 | gfx; // no. Tag FF + the gfx id of that tile
} else { // yes. FInd out if it is from the same grf file or not
const IndustryTileSpec *old_tile_ovr = GetIndustryTileSpec(indtsp->grf_prop.override);
if (old_tile_ovr->grf_prop.grffile->grfid == indold->grf_prop.grffile->grfid) {
return old_tile_ovr->grf_prop.local_id; // same grf file
} else {
return 0xFFFE; // not the same grf file
}
}
} else {
if (indtsp->grf_prop.spritegroup != NULL) { // tile has a spritegroup ?
if (indtsp->grf_prop.grffile->grfid == indold->grf_prop.grffile->grfid) { // same industry, same grf ?
return indtsp->grf_prop.local_id;
} else {
return 0xFFFE; // Defined in another grf file
}
} else { // tile has no spritegroup
return 0xFF << 8 | indtsp->grf_prop.subst_id; // so just give him the substitute
}
}
}
if (!IsTileType(tile, MP_INDUSTRY) || GetIndustryIndex(tile) == i->index) {
/* No industry and/or the tile does not have the same industry as the one we match it with */
return 0xFFFF;
}
return 0xFFFF; // tile is not an industry one or does not belong to the current industry
IndustryGfx gfx = GetCleanIndustryGfx(tile);
const IndustryTileSpec *indtsp = GetIndustryTileSpec(gfx);
const IndustrySpec *indold = GetIndustrySpec(i->type);
if (gfx < NEW_INDUSTRYOFFSET) { // Does it belongs to an old type?
/* It is an old tile. We have to see if it's been overriden */
if (indtsp->grf_prop.override == INVALID_INDUSTRYTILE) { // has it been overridden?
return 0xFF << 8 | gfx; // no. Tag FF + the gfx id of that tile
}
/* Not overriden */
const IndustryTileSpec *tile_ovr = GetIndustryTileSpec(indtsp->grf_prop.override);
if (tile_ovr->grf_prop.grffile->grfid == indold->grf_prop.grffile->grfid) {
return tile_ovr->grf_prop.local_id; // same grf file
} else {
return 0xFFFE; // not the same grf file
}
}
/* Not an 'old type' tile */
if (indtsp->grf_prop.spritegroup != NULL) { // tile has a spritegroup ?
if (indtsp->grf_prop.grffile->grfid == indold->grf_prop.grffile->grfid) { // same industry, same grf ?
return indtsp->grf_prop.local_id;
} else {
return 0xFFFE; // Defined in another grf file
}
}
/* The tile has no spritegroup */
return 0xFF << 8 | indtsp->grf_prop.subst_id; // so just give him the substitute
}
static uint32 GetClosestIndustry(TileIndex tile, IndustryType type, const Industry *current)
@ -215,7 +212,7 @@ uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte par
case 0x44: return industry->selected_layout;
/* Get industry ID at offset param */
case 0x60: return GetIndustryIDAtOffset(GetNearbyTile(parameter, industry->xy), tile, industry);
case 0x60: return GetIndustryIDAtOffset(GetNearbyTile(parameter, industry->xy), industry);
/* Get random tile bits at offset param */
case 0x61:

View File

@ -21,7 +21,7 @@ enum IndustryTrigger {
/* in newgrf_industry.cpp */
uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available);
uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile);
uint32 GetIndustryIDAtOffset(TileIndex new_tile, TileIndex old_tile, const Industry *i);
uint32 GetIndustryIDAtOffset(TileIndex new_tile, const Industry *i);
void IndustryProductionCallback(Industry *ind, int reason);
bool CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint itspec_index);
bool CheckIfCallBackAllowsAvailability(IndustryType type, IndustryAvailabilityCallType creation_type);

View File

@ -99,7 +99,7 @@ static uint32 IndustryTileGetVariable(const ResolverObject *object, byte variabl
}
/* Get industry tile ID at offset */
case 0x62 : return GetIndustryIDAtOffset(GetNearbyTile(parameter, tile), tile, inds);
case 0x62 : return GetIndustryIDAtOffset(GetNearbyTile(parameter, tile), inds);
}
DEBUG(grf, 1, "Unhandled industry tile property 0x%X", variable);