(svn r11797) -Fix: Add protection against not already created industry while doing industry callback.
Some variables used were linked to invalid industry.
--- a/src/newgrf_industries.cpp Wed Jan 09 17:47:05 2008 +0000
+++ b/src/newgrf_industries.cpp Wed Jan 09 18:14:29 2008 +0000
@@ -201,7 +201,23 @@
{
const Industry *industry = object->u.industry.ind;
TileIndex tile = object->u.industry.tile;
- const IndustrySpec *indspec = GetIndustrySpec(industry->type);
+ IndustryType type = object->u.industry.type;
+ const IndustrySpec *indspec = GetIndustrySpec(type);
+
+ if (industry == NULL) {
+ /* industry does not exist, only use those variables that are "safe" */
+ switch (variable) {
+ /* Read GRF parameter */
+ case 0x7F: return GetGRFParameter(type, parameter);
+ /* Manhattan distance of closes dry/water tile */
+ case 0x43: return GetClosestWaterDistance(tile, (indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) == 0);
+ }
+
+ DEBUG(grf, 1, "Unhandled property 0x%X (no available industry) in callback 0x%x", variable, object->callback);
+
+ *available = false;
+ return UINT_MAX;
+ }
switch (variable) {
case 0x40:
@@ -278,7 +294,7 @@
case 0x7C: return industry->psa.Get(parameter);
/* Read GRF parameter */
- case 0x7F: return GetGRFParameter(industry->type, parameter);
+ case 0x7F: return GetGRFParameter(type, parameter);
/* Industry structure access*/
case 0x80: return industry->xy;
@@ -368,7 +384,7 @@
object->u.industry.ind->random_triggers = triggers;
}
-static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus)
+static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus, IndustryType type)
{
res->GetRandomBits = IndustryGetRandomBits;
res->GetTriggers = IndustryGetTriggers;
@@ -380,6 +396,7 @@
res->u.industry.tile = tile;
res->u.industry.ind = indus;
res->u.industry.gfx = INVALID_INDUSTRYTILE;
+ res->u.industry.type = type;
res->callback = CBID_NO_CALLBACK;
res->callback_param1 = 0;
@@ -394,7 +411,7 @@
ResolverObject object;
const SpriteGroup *group;
- NewIndustryResolver(&object, tile, industry);
+ NewIndustryResolver(&object, tile, industry, type);
object.callback = callback;
object.callback_param1 = param1;
object.callback_param2 = param2;
@@ -465,7 +482,7 @@
ind.selected_layout = itspec_index;
ind.town = ClosestTownFromTile(tile, (uint)-1);
- NewIndustryResolver(&object, tile, &ind);
+ NewIndustryResolver(&object, tile, &ind, type);
object.GetVariable = IndustryLocationGetVariable;
object.callback = CBID_INDUSTRY_LOCATION;
@@ -518,7 +535,7 @@
{
const IndustrySpec *spec = GetIndustrySpec(ind->type);
ResolverObject object;
- NewIndustryResolver(&object, ind->xy, ind);
+ NewIndustryResolver(&object, ind->xy, ind, ind->type);
if ((spec->behaviour & INDUSTRYBEH_PRODCALLBACK_RANDOM) != 0) object.callback_param1 = Random();
int multiplier = 1;
if ((spec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) multiplier = ind->prod_level;
--- a/src/newgrf_spritegroup.h Wed Jan 09 17:47:05 2008 +0000
+++ b/src/newgrf_spritegroup.h Wed Jan 09 18:14:29 2008 +0000
@@ -231,6 +231,7 @@
TileIndex tile;
Industry *ind;
IndustryGfx gfx;
+ IndustryType type;
} industry;
struct {
const struct CargoSpec *cs;