diff -r eee46cb39750 -r b39bc69bb2f2 src/newgrf_industries.cpp --- a/src/newgrf_industries.cpp Wed Jan 09 18:11:12 2008 +0000 +++ b/src/newgrf_industries.cpp Sun Feb 03 20:17:54 2008 +0000 @@ -7,7 +7,6 @@ #include "debug.h" #include "variables.h" #include "landscape.h" -#include "table/strings.h" #include "industry.h" #include "industry_map.h" #include "newgrf.h" @@ -20,6 +19,13 @@ #include "newgrf_town.h" #include "window_func.h" #include "town.h" +#include "player_func.h" +#include "player_base.h" +#include "command_func.h" + +#include "table/strings.h" + +static Randomizer _industry_creation_randomizer; /* Since the industry IDs defined by the GRF file don't necessarily correlate * to those used by the game, the IDs used for overriding old industries must be @@ -201,7 +207,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 +300,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 +390,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 +402,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 +417,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; @@ -444,13 +467,16 @@ /* Square of Euclidian distance from town */ case 0x8D: return min(DistanceSquare(industry->town->xy, tile), 65535); + + /* 32 random bits */ + case 0x8F: return _industry_creation_randomizer.Next(); } /* None of the special ones, so try the general ones */ return IndustryGetVariable(object, variable, parameter, available); } -bool CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint itspec_index) +bool CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint itspec_index, uint32 seed) { const IndustrySpec *indspec = GetIndustrySpec(type); @@ -465,9 +491,10 @@ 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; + _industry_creation_randomizer.SetSeed(seed); group = Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object); @@ -518,7 +545,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;