src/newgrf_industries.cpp
branchNewGRF_ports
changeset 6872 1c4a4a609f85
parent 6871 5a9dc001e1ad
child 6877 889301acc299
equal deleted inserted replaced
6871:5a9dc001e1ad 6872:1c4a4a609f85
     3 /** @file newgrf_industries.cpp */
     3 /** @file newgrf_industries.cpp */
     4 
     4 
     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 "functions.h"
       
     9 #include "macros.h"
       
    10 #include "variables.h"
     8 #include "variables.h"
    11 #include "landscape.h"
     9 #include "landscape.h"
    12 #include "table/strings.h"
       
    13 #include "industry.h"
    10 #include "industry.h"
    14 #include "industry_map.h"
    11 #include "industry_map.h"
    15 #include "newgrf.h"
    12 #include "newgrf.h"
    16 #include "newgrf_callbacks.h"
    13 #include "newgrf_callbacks.h"
    17 #include "newgrf_spritegroup.h"
    14 #include "newgrf_spritegroup.h"
    18 #include "newgrf_industries.h"
    15 #include "newgrf_industries.h"
    19 #include "newgrf_industrytiles.h"
    16 #include "newgrf_industrytiles.h"
    20 #include "newgrf_commons.h"
    17 #include "newgrf_commons.h"
    21 #include "newgrf_text.h"
    18 #include "newgrf_text.h"
    22 #include "newgrf_town.h"
    19 #include "newgrf_town.h"
    23 #include "date.h"
    20 #include "window_func.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"
    24 
    27 
    25 /* Since the industry IDs defined by the GRF file don't necessarily correlate
    28 /* Since the industry IDs defined by the GRF file don't necessarily correlate
    26  * to those used by the game, the IDs used for overriding old industries must be
    29  * to those used by the game, the IDs used for overriding old industries must be
    27  * translated when the idustry spec is set. */
    30  * translated when the idustry spec is set. */
    28 IndustryOverrideManager _industry_mngr(NEW_INDUSTRYOFFSET, NUM_INDUSTRYTYPES, INVALID_INDUSTRYTYPE);
    31 IndustryOverrideManager _industry_mngr(NEW_INDUSTRYOFFSET, NUM_INDUSTRYTYPES, INVALID_INDUSTRYTYPE);
    32 {
    35 {
    33 	if (grf_type == IT_INVALID) return IT_INVALID;
    36 	if (grf_type == IT_INVALID) return IT_INVALID;
    34 	if (!HasBit(grf_type, 7)) return GB(grf_type, 0, 6);
    37 	if (!HasBit(grf_type, 7)) return GB(grf_type, 0, 6);
    35 
    38 
    36 	return _industry_mngr.GetID(GB(grf_type, 0, 6), grf_id);
    39 	return _industry_mngr.GetID(GB(grf_type, 0, 6), grf_id);
       
    40 }
       
    41 
       
    42 static uint32 GetGRFParameter(IndustryType ind_id, byte parameter)
       
    43 {
       
    44 	const IndustrySpec *indspec = GetIndustrySpec(ind_id);
       
    45 	const GRFFile *file = indspec->grf_prop.grffile;
       
    46 
       
    47 	if (parameter >= file->param_end) return 0;
       
    48 	return file->param[parameter];
    37 }
    49 }
    38 
    50 
    39 /**
    51 /**
    40  * Finds the distance for the closest tile with water/land given a tile
    52  * Finds the distance for the closest tile with water/land given a tile
    41  * @param tile  the tile to find the distance too
    53  * @param tile  the tile to find the distance too
   191  * @return the value stored in the corresponding variable*/
   203  * @return the value stored in the corresponding variable*/
   192 uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
   204 uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
   193 {
   205 {
   194 	const Industry *industry = object->u.industry.ind;
   206 	const Industry *industry = object->u.industry.ind;
   195 	TileIndex tile = object->u.industry.tile;
   207 	TileIndex tile = object->u.industry.tile;
   196 	const IndustrySpec *indspec = GetIndustrySpec(industry->type);
   208 	IndustryType type = object->u.industry.type;
       
   209 	const IndustrySpec *indspec = GetIndustrySpec(type);
       
   210 
       
   211 	if (industry == NULL) {
       
   212 		/* industry does not exist, only use those variables that are "safe" */
       
   213 		switch (variable) {
       
   214 			/* Read GRF parameter */
       
   215 			case 0x7F: return GetGRFParameter(type, parameter);
       
   216 			/* Manhattan distance of closes dry/water tile */
       
   217 			case 0x43: return GetClosestWaterDistance(tile, (indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) == 0);
       
   218 		}
       
   219 
       
   220 		DEBUG(grf, 1, "Unhandled property 0x%X (no available industry) in callback 0x%x", variable, object->callback);
       
   221 
       
   222 		*available = false;
       
   223 		return UINT_MAX;
       
   224 	}
   197 
   225 
   198 	switch (variable) {
   226 	switch (variable) {
   199 		case 0x40:
   227 		case 0x40:
   200 		case 0x41:
   228 		case 0x41:
   201 		case 0x42: { // waiting cargo, but only if those two callback flags are set
   229 		case 0x42: { // waiting cargo, but only if those two callback flags are set
   266 		case 0x67:
   294 		case 0x67:
   267 		case 0x68: return GetCountAndDistanceOfClosestInstance(parameter, variable == 0x68 ? GB(GetRegister(0x101), 0, 8) : 0, industry);
   295 		case 0x68: return GetCountAndDistanceOfClosestInstance(parameter, variable == 0x68 ? GB(GetRegister(0x101), 0, 8) : 0, industry);
   268 
   296 
   269 		/* Get a variable from the persistent storage */
   297 		/* Get a variable from the persistent storage */
   270 		case 0x7C: return industry->psa.Get(parameter);
   298 		case 0x7C: return industry->psa.Get(parameter);
       
   299 
       
   300 		/* Read GRF parameter */
       
   301 		case 0x7F: return GetGRFParameter(type, parameter);
   271 
   302 
   272 		/* Industry structure access*/
   303 		/* Industry structure access*/
   273 		case 0x80: return industry->xy;
   304 		case 0x80: return industry->xy;
   274 		case 0x81: return GB(industry->xy, 8, 8);
   305 		case 0x81: return GB(industry->xy, 8, 8);
   275 		/* Pointer to the town the industry is associated with */
   306 		/* Pointer to the town the industry is associated with */
   317 		case 0xA5: return GB(industry->last_month_transported[0], 8, 8);
   348 		case 0xA5: return GB(industry->last_month_transported[0], 8, 8);
   318 
   349 
   319 		case 0xA6: return industry->type;
   350 		case 0xA6: return industry->type;
   320 		case 0xA7: return industry->founder;
   351 		case 0xA7: return industry->founder;
   321 		case 0xA8: return industry->random_color;
   352 		case 0xA8: return industry->random_color;
   322 		case 0xA9: return Clamp(0, industry->last_prod_year - 1920, 255);
   353 		case 0xA9: return Clamp(0, industry->last_prod_year - ORIGINAL_BASE_YEAR, 255);
   323 		case 0xAA: return industry->counter;
   354 		case 0xAA: return industry->counter;
   324 		case 0xAB: return GB(industry->counter, 8, 8);
   355 		case 0xAB: return GB(industry->counter, 8, 8);
   325 		case 0xAC: return industry->was_cargo_delivered;
   356 		case 0xAC: return industry->was_cargo_delivered;
   326 
   357 
   327 		case 0xB0: return Clamp(0, industry->construction_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 65535); // Date when built since 1920 (in days)
   358 		case 0xB0: return Clamp(0, industry->construction_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 65535); // Date when built since 1920 (in days)
   355 {
   386 {
   356 	if (object->u.industry.ind == NULL) return;
   387 	if (object->u.industry.ind == NULL) return;
   357 	object->u.industry.ind->random_triggers = triggers;
   388 	object->u.industry.ind->random_triggers = triggers;
   358 }
   389 }
   359 
   390 
   360 static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus)
   391 static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus, IndustryType type)
   361 {
   392 {
   362 	res->GetRandomBits = IndustryGetRandomBits;
   393 	res->GetRandomBits = IndustryGetRandomBits;
   363 	res->GetTriggers   = IndustryGetTriggers;
   394 	res->GetTriggers   = IndustryGetTriggers;
   364 	res->SetTriggers   = IndustrySetTriggers;
   395 	res->SetTriggers   = IndustrySetTriggers;
   365 	res->GetVariable   = IndustryGetVariable;
   396 	res->GetVariable   = IndustryGetVariable;
   367 
   398 
   368 	res->psa             = &indus->psa;
   399 	res->psa             = &indus->psa;
   369 	res->u.industry.tile = tile;
   400 	res->u.industry.tile = tile;
   370 	res->u.industry.ind  = indus;
   401 	res->u.industry.ind  = indus;
   371 	res->u.industry.gfx  = INVALID_INDUSTRYTILE;
   402 	res->u.industry.gfx  = INVALID_INDUSTRYTILE;
       
   403 	res->u.industry.type = type;
   372 
   404 
   373 	res->callback        = CBID_NO_CALLBACK;
   405 	res->callback        = CBID_NO_CALLBACK;
   374 	res->callback_param1 = 0;
   406 	res->callback_param1 = 0;
   375 	res->callback_param2 = 0;
   407 	res->callback_param2 = 0;
   376 	res->last_value      = 0;
   408 	res->last_value      = 0;
   381 uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile)
   413 uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile)
   382 {
   414 {
   383 	ResolverObject object;
   415 	ResolverObject object;
   384 	const SpriteGroup *group;
   416 	const SpriteGroup *group;
   385 
   417 
   386 	NewIndustryResolver(&object, tile, industry);
   418 	NewIndustryResolver(&object, tile, industry, type);
   387 	object.callback = callback;
   419 	object.callback = callback;
   388 	object.callback_param1 = param1;
   420 	object.callback_param1 = param1;
   389 	object.callback_param2 = param2;
   421 	object.callback_param2 = param2;
   390 
   422 
   391 	group = Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
   423 	group = Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
   452 	ind.width = 0;
   484 	ind.width = 0;
   453 	ind.type = type;
   485 	ind.type = type;
   454 	ind.selected_layout = itspec_index;
   486 	ind.selected_layout = itspec_index;
   455 	ind.town = ClosestTownFromTile(tile, (uint)-1);
   487 	ind.town = ClosestTownFromTile(tile, (uint)-1);
   456 
   488 
   457 	NewIndustryResolver(&object, tile, &ind);
   489 	NewIndustryResolver(&object, tile, &ind, type);
   458 	object.GetVariable = IndustryLocationGetVariable;
   490 	object.GetVariable = IndustryLocationGetVariable;
   459 	object.callback = CBID_INDUSTRY_LOCATION;
   491 	object.callback = CBID_INDUSTRY_LOCATION;
   460 
   492 
   461 	group = Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
   493 	group = Resolve(GetIndustrySpec(type)->grf_prop.spritegroup, &object);
   462 
   494 
   505  */
   537  */
   506 void IndustryProductionCallback(Industry *ind, int reason)
   538 void IndustryProductionCallback(Industry *ind, int reason)
   507 {
   539 {
   508 	const IndustrySpec *spec = GetIndustrySpec(ind->type);
   540 	const IndustrySpec *spec = GetIndustrySpec(ind->type);
   509 	ResolverObject object;
   541 	ResolverObject object;
   510 	NewIndustryResolver(&object, ind->xy, ind);
   542 	NewIndustryResolver(&object, ind->xy, ind, ind->type);
   511 	if ((spec->behaviour & INDUSTRYBEH_PRODCALLBACK_RANDOM) != 0) object.callback_param1 = Random();
   543 	if ((spec->behaviour & INDUSTRYBEH_PRODCALLBACK_RANDOM) != 0) object.callback_param1 = Random();
   512 	int multiplier = 1;
   544 	int multiplier = 1;
   513 	if ((spec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) multiplier = ind->prod_level;
   545 	if ((spec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) multiplier = ind->prod_level;
   514 	object.callback_param2 = reason;
   546 	object.callback_param2 = reason;
   515 
   547 
   533 		SB(object.callback_param2, 24, 8, again);
   565 		SB(object.callback_param2, 24, 8, again);
   534 	}
   566 	}
   535 
   567 
   536 	InvalidateWindow(WC_INDUSTRY_VIEW, ind->index);
   568 	InvalidateWindow(WC_INDUSTRY_VIEW, ind->index);
   537 }
   569 }
   538 
       
   539 void DoTriggerIndustry(Industry *ind, IndustryTileTrigger trigger)
       
   540 {
       
   541 	ResolverObject object;
       
   542 
       
   543 	NewIndustryResolver(&object, ind->xy, ind);
       
   544 	object.callback = CBID_RANDOM_TRIGGER;
       
   545 	object.trigger = trigger;
       
   546 
       
   547 	const SpriteGroup *group = Resolve(GetIndustrySpec(ind->type)->grf_prop.spritegroup, &object);
       
   548 	if (group == NULL) return;
       
   549 
       
   550 	byte new_random_bits = Random();
       
   551 	ind->random &= ~object.reseed;
       
   552 	ind->random |= new_random_bits & object.reseed;
       
   553 }