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 } |
|