src/newgrf_industries.cpp
branchnoai
changeset 9723 eee46cb39750
parent 9722 ebf0ece7d8f6
child 9724 b39bc69bb2f2
equal deleted inserted replaced
9722:ebf0ece7d8f6 9723:eee46cb39750
     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"
    10 #include "table/strings.h"
    13 #include "industry.h"
    11 #include "industry.h"
    14 #include "industry_map.h"
    12 #include "industry_map.h"
    18 #include "newgrf_industries.h"
    16 #include "newgrf_industries.h"
    19 #include "newgrf_industrytiles.h"
    17 #include "newgrf_industrytiles.h"
    20 #include "newgrf_commons.h"
    18 #include "newgrf_commons.h"
    21 #include "newgrf_text.h"
    19 #include "newgrf_text.h"
    22 #include "newgrf_town.h"
    20 #include "newgrf_town.h"
    23 #include "date.h"
    21 #include "window_func.h"
       
    22 #include "town.h"
    24 
    23 
    25 /* Since the industry IDs defined by the GRF file don't necessarily correlate
    24 /* 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
    25  * to those used by the game, the IDs used for overriding old industries must be
    27  * translated when the idustry spec is set. */
    26  * translated when the idustry spec is set. */
    28 IndustryOverrideManager _industry_mngr(NEW_INDUSTRYOFFSET, NUM_INDUSTRYTYPES, INVALID_INDUSTRYTYPE);
    27 IndustryOverrideManager _industry_mngr(NEW_INDUSTRYOFFSET, NUM_INDUSTRYTYPES, INVALID_INDUSTRYTYPE);
    32 {
    31 {
    33 	if (grf_type == IT_INVALID) return IT_INVALID;
    32 	if (grf_type == IT_INVALID) return IT_INVALID;
    34 	if (!HasBit(grf_type, 7)) return GB(grf_type, 0, 6);
    33 	if (!HasBit(grf_type, 7)) return GB(grf_type, 0, 6);
    35 
    34 
    36 	return _industry_mngr.GetID(GB(grf_type, 0, 6), grf_id);
    35 	return _industry_mngr.GetID(GB(grf_type, 0, 6), grf_id);
       
    36 }
       
    37 
       
    38 static uint32 GetGRFParameter(IndustryType ind_id, byte parameter)
       
    39 {
       
    40 	const IndustrySpec *indspec = GetIndustrySpec(ind_id);
       
    41 	const GRFFile *file = indspec->grf_prop.grffile;
       
    42 
       
    43 	if (parameter >= file->param_end) return 0;
       
    44 	return file->param[parameter];
    37 }
    45 }
    38 
    46 
    39 /**
    47 /**
    40  * Finds the distance for the closest tile with water/land given a tile
    48  * Finds the distance for the closest tile with water/land given a tile
    41  * @param tile  the tile to find the distance too
    49  * @param tile  the tile to find the distance too
   199 		case 0x40:
   207 		case 0x40:
   200 		case 0x41:
   208 		case 0x41:
   201 		case 0x42: { // waiting cargo, but only if those two callback flags are set
   209 		case 0x42: { // waiting cargo, but only if those two callback flags are set
   202 			uint16 callback = indspec->callback_flags;
   210 			uint16 callback = indspec->callback_flags;
   203 			if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(callback, CBM_IND_PRODUCTION_256_TICKS)) {
   211 			if (HasBit(callback, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(callback, CBM_IND_PRODUCTION_256_TICKS)) {
   204 				return min(industry->incoming_cargo_waiting[variable - 0x40], (uint16)0xFFFF);
   212 				if ((indspec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) {
       
   213 					return min(industry->incoming_cargo_waiting[variable - 0x40] / industry->prod_level, (uint16)0xFFFF);
       
   214 				} else {
       
   215 					return min(industry->incoming_cargo_waiting[variable - 0x40], (uint16)0xFFFF);
       
   216 				}
   205 			} else {
   217 			} else {
   206 				return 0;
   218 				return 0;
   207 			}
   219 			}
   208 		}
   220 		}
   209 
   221 
   262 		case 0x67:
   274 		case 0x67:
   263 		case 0x68: return GetCountAndDistanceOfClosestInstance(parameter, variable == 0x68 ? GB(GetRegister(0x101), 0, 8) : 0, industry);
   275 		case 0x68: return GetCountAndDistanceOfClosestInstance(parameter, variable == 0x68 ? GB(GetRegister(0x101), 0, 8) : 0, industry);
   264 
   276 
   265 		/* Get a variable from the persistent storage */
   277 		/* Get a variable from the persistent storage */
   266 		case 0x7C: return industry->psa.Get(parameter);
   278 		case 0x7C: return industry->psa.Get(parameter);
       
   279 
       
   280 		/* Read GRF parameter */
       
   281 		case 0x7F: return GetGRFParameter(industry->type, parameter);
   267 
   282 
   268 		/* Industry structure access*/
   283 		/* Industry structure access*/
   269 		case 0x80: return industry->xy;
   284 		case 0x80: return industry->xy;
   270 		case 0x81: return GB(industry->xy, 8, 8);
   285 		case 0x81: return GB(industry->xy, 8, 8);
   271 		/* Pointer to the town the industry is associated with */
   286 		/* Pointer to the town the industry is associated with */
   313 		case 0xA5: return GB(industry->last_month_transported[0], 8, 8);
   328 		case 0xA5: return GB(industry->last_month_transported[0], 8, 8);
   314 
   329 
   315 		case 0xA6: return industry->type;
   330 		case 0xA6: return industry->type;
   316 		case 0xA7: return industry->founder;
   331 		case 0xA7: return industry->founder;
   317 		case 0xA8: return industry->random_color;
   332 		case 0xA8: return industry->random_color;
   318 		case 0xA9: return Clamp(0, industry->last_prod_year - 1920, 255);
   333 		case 0xA9: return Clamp(0, industry->last_prod_year - ORIGINAL_BASE_YEAR, 255);
   319 		case 0xAA: return industry->counter;
   334 		case 0xAA: return industry->counter;
   320 		case 0xAB: return GB(industry->counter, 8, 8);
   335 		case 0xAB: return GB(industry->counter, 8, 8);
   321 		case 0xAC: return industry->was_cargo_delivered;
   336 		case 0xAC: return industry->was_cargo_delivered;
   322 
   337 
   323 		case 0xB0: return Clamp(0, industry->construction_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 65535); // Date when built since 1920 (in days)
   338 		case 0xB0: return Clamp(0, industry->construction_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 65535); // Date when built since 1920 (in days)
   503 {
   518 {
   504 	const IndustrySpec *spec = GetIndustrySpec(ind->type);
   519 	const IndustrySpec *spec = GetIndustrySpec(ind->type);
   505 	ResolverObject object;
   520 	ResolverObject object;
   506 	NewIndustryResolver(&object, ind->xy, ind);
   521 	NewIndustryResolver(&object, ind->xy, ind);
   507 	if ((spec->behaviour & INDUSTRYBEH_PRODCALLBACK_RANDOM) != 0) object.callback_param1 = Random();
   522 	if ((spec->behaviour & INDUSTRYBEH_PRODCALLBACK_RANDOM) != 0) object.callback_param1 = Random();
       
   523 	int multiplier = 1;
       
   524 	if ((spec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) multiplier = ind->prod_level;
   508 	object.callback_param2 = reason;
   525 	object.callback_param2 = reason;
   509 
   526 
   510 	for (uint loop = 0;; loop++) {
   527 	for (uint loop = 0;; loop++) {
   511 		SB(object.callback_param2, 8, 16, loop);
   528 		SB(object.callback_param2, 8, 16, loop);
   512 		const SpriteGroup *group = Resolve(spec->grf_prop.spritegroup, &object);
   529 		const SpriteGroup *group = Resolve(spec->grf_prop.spritegroup, &object);
   513 		if (group == NULL || group->type != SGT_INDUSTRY_PRODUCTION) break;
   530 		if (group == NULL || group->type != SGT_INDUSTRY_PRODUCTION) break;
   514 
   531 
   515 		bool deref = (group->g.indprod.version == 1);
   532 		bool deref = (group->g.indprod.version == 1);
   516 
   533 
   517 		for (uint i = 0; i < 3; i++) {
   534 		for (uint i = 0; i < 3; i++) {
   518 			ind->incoming_cargo_waiting[i] = Clamp(ind->incoming_cargo_waiting[i] - DerefIndProd(group->g.indprod.substract_input[i], deref), 0, 0xFFFF);
   535 			ind->incoming_cargo_waiting[i] = Clamp(ind->incoming_cargo_waiting[i] - DerefIndProd(group->g.indprod.substract_input[i], deref) * multiplier, 0, 0xFFFF);
   519 		}
   536 		}
   520 		for (uint i = 0; i < 2; i++) {
   537 		for (uint i = 0; i < 2; i++) {
   521 			ind->produced_cargo_waiting[i] = Clamp(ind->produced_cargo_waiting[i] + DerefIndProd(group->g.indprod.add_output[i], deref), 0, 0xFFFF);
   538 			ind->produced_cargo_waiting[i] = Clamp(ind->produced_cargo_waiting[i] + max(DerefIndProd(group->g.indprod.add_output[i], deref), 0) * multiplier, 0, 0xFFFF);
   522 		}
   539 		}
   523 
   540 
   524 		int32 again = DerefIndProd(group->g.indprod.again, deref);
   541 		int32 again = DerefIndProd(group->g.indprod.again, deref);
   525 		if (again == 0) break;
   542 		if (again == 0) break;
   526 
   543 
   527 		SB(object.callback_param2, 24, 8, again);
   544 		SB(object.callback_param2, 24, 8, again);
   528 	}
   545 	}
   529 
   546 
   530 	InvalidateWindow(WC_INDUSTRY_VIEW, ind->index);
   547 	InvalidateWindow(WC_INDUSTRY_VIEW, ind->index);
   531 }
   548 }
   532 
       
   533 void DoTriggerIndustry(Industry *ind, IndustryTileTrigger trigger)
       
   534 {
       
   535 	ResolverObject object;
       
   536 
       
   537 	NewIndustryResolver(&object, ind->xy, ind);
       
   538 	object.callback = CBID_RANDOM_TRIGGER;
       
   539 	object.trigger = trigger;
       
   540 
       
   541 	const SpriteGroup *group = Resolve(GetIndustrySpec(ind->type)->grf_prop.spritegroup, &object);
       
   542 	if (group == NULL) return;
       
   543 
       
   544 	byte new_random_bits = Random();
       
   545 	ind->random &= ~object.reseed;
       
   546 	ind->random |= new_random_bits & object.reseed;
       
   547 }