src/newgrf_industries.cpp
branchnoai
changeset 9724 b39bc69bb2f2
parent 9723 eee46cb39750
child 9800 ab08ca2a2018
equal deleted inserted replaced
9723:eee46cb39750 9724:b39bc69bb2f2
     5 #include "stdafx.h"
     5 #include "stdafx.h"
     6 #include "openttd.h"
     6 #include "openttd.h"
     7 #include "debug.h"
     7 #include "debug.h"
     8 #include "variables.h"
     8 #include "variables.h"
     9 #include "landscape.h"
     9 #include "landscape.h"
    10 #include "table/strings.h"
       
    11 #include "industry.h"
    10 #include "industry.h"
    12 #include "industry_map.h"
    11 #include "industry_map.h"
    13 #include "newgrf.h"
    12 #include "newgrf.h"
    14 #include "newgrf_callbacks.h"
    13 #include "newgrf_callbacks.h"
    15 #include "newgrf_spritegroup.h"
    14 #include "newgrf_spritegroup.h"
    18 #include "newgrf_commons.h"
    17 #include "newgrf_commons.h"
    19 #include "newgrf_text.h"
    18 #include "newgrf_text.h"
    20 #include "newgrf_town.h"
    19 #include "newgrf_town.h"
    21 #include "window_func.h"
    20 #include "window_func.h"
    22 #include "town.h"
    21 #include "town.h"
       
    22 #include "player_func.h"
       
    23 #include "player_base.h"
       
    24 #include "command_func.h"
       
    25 
       
    26 #include "table/strings.h"
       
    27 
       
    28 static Randomizer _industry_creation_randomizer;
    23 
    29 
    24 /* Since the industry IDs defined by the GRF file don't necessarily correlate
    30 /* Since the industry IDs defined by the GRF file don't necessarily correlate
    25  * to those used by the game, the IDs used for overriding old industries must be
    31  * to those used by the game, the IDs used for overriding old industries must be
    26  * translated when the idustry spec is set. */
    32  * translated when the idustry spec is set. */
    27 IndustryOverrideManager _industry_mngr(NEW_INDUSTRYOFFSET, NUM_INDUSTRYTYPES, INVALID_INDUSTRYTYPE);
    33 IndustryOverrideManager _industry_mngr(NEW_INDUSTRYOFFSET, NUM_INDUSTRYTYPES, INVALID_INDUSTRYTYPE);
   199  * @return the value stored in the corresponding variable*/
   205  * @return the value stored in the corresponding variable*/
   200 uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
   206 uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
   201 {
   207 {
   202 	const Industry *industry = object->u.industry.ind;
   208 	const Industry *industry = object->u.industry.ind;
   203 	TileIndex tile = object->u.industry.tile;
   209 	TileIndex tile = object->u.industry.tile;
   204 	const IndustrySpec *indspec = GetIndustrySpec(industry->type);
   210 	IndustryType type = object->u.industry.type;
       
   211 	const IndustrySpec *indspec = GetIndustrySpec(type);
       
   212 
       
   213 	if (industry == NULL) {
       
   214 		/* industry does not exist, only use those variables that are "safe" */
       
   215 		switch (variable) {
       
   216 			/* Read GRF parameter */
       
   217 			case 0x7F: return GetGRFParameter(type, parameter);
       
   218 			/* Manhattan distance of closes dry/water tile */
       
   219 			case 0x43: return GetClosestWaterDistance(tile, (indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) == 0);
       
   220 		}
       
   221 
       
   222 		DEBUG(grf, 1, "Unhandled property 0x%X (no available industry) in callback 0x%x", variable, object->callback);
       
   223 
       
   224 		*available = false;
       
   225 		return UINT_MAX;
       
   226 	}
   205 
   227 
   206 	switch (variable) {
   228 	switch (variable) {
   207 		case 0x40:
   229 		case 0x40:
   208 		case 0x41:
   230 		case 0x41:
   209 		case 0x42: { // waiting cargo, but only if those two callback flags are set
   231 		case 0x42: { // waiting cargo, but only if those two callback flags are set
   276 
   298 
   277 		/* Get a variable from the persistent storage */
   299 		/* Get a variable from the persistent storage */
   278 		case 0x7C: return industry->psa.Get(parameter);
   300 		case 0x7C: return industry->psa.Get(parameter);
   279 
   301 
   280 		/* Read GRF parameter */
   302 		/* Read GRF parameter */
   281 		case 0x7F: return GetGRFParameter(industry->type, parameter);
   303 		case 0x7F: return GetGRFParameter(type, parameter);
   282 
   304 
   283 		/* Industry structure access*/
   305 		/* Industry structure access*/
   284 		case 0x80: return industry->xy;
   306 		case 0x80: return industry->xy;
   285 		case 0x81: return GB(industry->xy, 8, 8);
   307 		case 0x81: return GB(industry->xy, 8, 8);
   286 		/* Pointer to the town the industry is associated with */
   308 		/* Pointer to the town the industry is associated with */
   366 {
   388 {
   367 	if (object->u.industry.ind == NULL) return;
   389 	if (object->u.industry.ind == NULL) return;
   368 	object->u.industry.ind->random_triggers = triggers;
   390 	object->u.industry.ind->random_triggers = triggers;
   369 }
   391 }
   370 
   392 
   371 static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus)
   393 static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus, IndustryType type)
   372 {
   394 {
   373 	res->GetRandomBits = IndustryGetRandomBits;
   395 	res->GetRandomBits = IndustryGetRandomBits;
   374 	res->GetTriggers   = IndustryGetTriggers;
   396 	res->GetTriggers   = IndustryGetTriggers;
   375 	res->SetTriggers   = IndustrySetTriggers;
   397 	res->SetTriggers   = IndustrySetTriggers;
   376 	res->GetVariable   = IndustryGetVariable;
   398 	res->GetVariable   = IndustryGetVariable;
   378 
   400 
   379 	res->psa             = &indus->psa;
   401 	res->psa             = &indus->psa;
   380 	res->u.industry.tile = tile;
   402 	res->u.industry.tile = tile;
   381 	res->u.industry.ind  = indus;
   403 	res->u.industry.ind  = indus;
   382 	res->u.industry.gfx  = INVALID_INDUSTRYTILE;
   404 	res->u.industry.gfx  = INVALID_INDUSTRYTILE;
       
   405 	res->u.industry.type = type;
   383 
   406 
   384 	res->callback        = CBID_NO_CALLBACK;
   407 	res->callback        = CBID_NO_CALLBACK;
   385 	res->callback_param1 = 0;
   408 	res->callback_param1 = 0;
   386 	res->callback_param2 = 0;
   409 	res->callback_param2 = 0;
   387 	res->last_value      = 0;
   410 	res->last_value      = 0;
   392 uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile)
   415 uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile)
   393 {
   416 {
   394 	ResolverObject object;
   417 	ResolverObject object;
   395 	const SpriteGroup *group;
   418 	const SpriteGroup *group;
   396 
   419 
   397 	NewIndustryResolver(&object, tile, industry);
   420 	NewIndustryResolver(&object, tile, industry, type);
   398 	object.callback = callback;
   421 	object.callback = callback;
   399 	object.callback_param1 = param1;
   422 	object.callback_param1 = param1;
   400 	object.callback_param2 = param2;
   423 	object.callback_param2 = param2;
   401 
   424 
   402 	group = Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
   425 	group = Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
   442 		/* Distance to the nearest water/land tile */
   465 		/* Distance to the nearest water/land tile */
   443 		case 0x8B: return GetClosestWaterDistance(tile, (GetIndustrySpec(industry->type)->behaviour & INDUSTRYBEH_BUILT_ONWATER) == 0);
   466 		case 0x8B: return GetClosestWaterDistance(tile, (GetIndustrySpec(industry->type)->behaviour & INDUSTRYBEH_BUILT_ONWATER) == 0);
   444 
   467 
   445 		/* Square of Euclidian distance from town */
   468 		/* Square of Euclidian distance from town */
   446 		case 0x8D: return min(DistanceSquare(industry->town->xy, tile), 65535);
   469 		case 0x8D: return min(DistanceSquare(industry->town->xy, tile), 65535);
       
   470 
       
   471 		/* 32 random bits */
       
   472 		case 0x8F: return _industry_creation_randomizer.Next();
   447 	}
   473 	}
   448 
   474 
   449 	/* None of the special ones, so try the general ones */
   475 	/* None of the special ones, so try the general ones */
   450 	return IndustryGetVariable(object, variable, parameter, available);
   476 	return IndustryGetVariable(object, variable, parameter, available);
   451 }
   477 }
   452 
   478 
   453 bool CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint itspec_index)
   479 bool CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint itspec_index, uint32 seed)
   454 {
   480 {
   455 	const IndustrySpec *indspec = GetIndustrySpec(type);
   481 	const IndustrySpec *indspec = GetIndustrySpec(type);
   456 
   482 
   457 	ResolverObject object;
   483 	ResolverObject object;
   458 	const SpriteGroup *group;
   484 	const SpriteGroup *group;
   463 	ind.width = 0;
   489 	ind.width = 0;
   464 	ind.type = type;
   490 	ind.type = type;
   465 	ind.selected_layout = itspec_index;
   491 	ind.selected_layout = itspec_index;
   466 	ind.town = ClosestTownFromTile(tile, (uint)-1);
   492 	ind.town = ClosestTownFromTile(tile, (uint)-1);
   467 
   493 
   468 	NewIndustryResolver(&object, tile, &ind);
   494 	NewIndustryResolver(&object, tile, &ind, type);
   469 	object.GetVariable = IndustryLocationGetVariable;
   495 	object.GetVariable = IndustryLocationGetVariable;
   470 	object.callback = CBID_INDUSTRY_LOCATION;
   496 	object.callback = CBID_INDUSTRY_LOCATION;
       
   497 	_industry_creation_randomizer.SetSeed(seed);
   471 
   498 
   472 	group = Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
   499 	group = Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
   473 
   500 
   474 	/* Unlike the "normal" cases, not having a valid result means we allow
   501 	/* Unlike the "normal" cases, not having a valid result means we allow
   475 	 * the building of the industry, as that's how it's done in TTDP. */
   502 	 * the building of the industry, as that's how it's done in TTDP. */
   516  */
   543  */
   517 void IndustryProductionCallback(Industry *ind, int reason)
   544 void IndustryProductionCallback(Industry *ind, int reason)
   518 {
   545 {
   519 	const IndustrySpec *spec = GetIndustrySpec(ind->type);
   546 	const IndustrySpec *spec = GetIndustrySpec(ind->type);
   520 	ResolverObject object;
   547 	ResolverObject object;
   521 	NewIndustryResolver(&object, ind->xy, ind);
   548 	NewIndustryResolver(&object, ind->xy, ind, ind->type);
   522 	if ((spec->behaviour & INDUSTRYBEH_PRODCALLBACK_RANDOM) != 0) object.callback_param1 = Random();
   549 	if ((spec->behaviour & INDUSTRYBEH_PRODCALLBACK_RANDOM) != 0) object.callback_param1 = Random();
   523 	int multiplier = 1;
   550 	int multiplier = 1;
   524 	if ((spec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) multiplier = ind->prod_level;
   551 	if ((spec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) multiplier = ind->prod_level;
   525 	object.callback_param2 = reason;
   552 	object.callback_param2 = reason;
   526 
   553