OpenTTD
newgrf_industries.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "stdafx.h"
11 #include "debug.h"
12 #include "industry.h"
13 #include "newgrf_industries.h"
14 #include "newgrf_town.h"
15 #include "newgrf_cargo.h"
16 #include "window_func.h"
17 #include "town.h"
18 #include "company_base.h"
19 #include "error.h"
20 #include "strings_func.h"
21 #include "core/random_func.hpp"
22 
23 #include "table/strings.h"
24 
25 #include "safeguards.h"
26 
27 /* Since the industry IDs defined by the GRF file don't necessarily correlate
28  * to those used by the game, the IDs used for overriding old industries must be
29  * translated when the idustry spec is set. */
32 
39 IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32 grf_id)
40 {
41  if (grf_type == IT_INVALID) return IT_INVALID;
42  if (!HasBit(grf_type, 7)) return GB(grf_type, 0, 7);
43 
44  return _industry_mngr.GetID(GB(grf_type, 0, 7), grf_id);
45 }
46 
55 uint32 GetIndustryIDAtOffset(TileIndex tile, const Industry *i, uint32 cur_grfid)
56 {
57  if (!i->TileBelongsToIndustry(tile)) {
58  /* No industry and/or the tile does not have the same industry as the one we match it with */
59  return 0xFFFF;
60  }
61 
62  IndustryGfx gfx = GetCleanIndustryGfx(tile);
63  const IndustryTileSpec *indtsp = GetIndustryTileSpec(gfx);
64 
65  if (gfx < NEW_INDUSTRYTILEOFFSET) { // Does it belongs to an old type?
66  /* It is an old tile. We have to see if it's been overridden */
67  if (indtsp->grf_prop.override == INVALID_INDUSTRYTILE) { // has it been overridden?
68  return 0xFF << 8 | gfx; // no. Tag FF + the gfx id of that tile
69  }
70  /* Overridden */
71  const IndustryTileSpec *tile_ovr = GetIndustryTileSpec(indtsp->grf_prop.override);
72 
73  if (tile_ovr->grf_prop.grffile->grfid == cur_grfid) {
74  return tile_ovr->grf_prop.local_id; // same grf file
75  } else {
76  return 0xFFFE; // not the same grf file
77  }
78  }
79  /* Not an 'old type' tile */
80  if (indtsp->grf_prop.spritegroup[0] != nullptr) { // tile has a spritegroup ?
81  if (indtsp->grf_prop.grffile->grfid == cur_grfid) { // same industry, same grf ?
82  return indtsp->grf_prop.local_id;
83  } else {
84  return 0xFFFE; // Defined in another grf file
85  }
86  }
87  /* The tile has no spritegroup */
88  return 0xFF << 8 | indtsp->grf_prop.subst_id; // so just give him the substitute
89 }
90 
91 static uint32 GetClosestIndustry(TileIndex tile, IndustryType type, const Industry *current)
92 {
93  uint32 best_dist = UINT32_MAX;
94  for (const Industry *i : Industry::Iterate()) {
95  if (i->type != type || i == current) continue;
96 
97  best_dist = min(best_dist, DistanceManhattan(tile, i->location.tile));
98  }
99 
100  return best_dist;
101 }
102 
113 static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout_filter, bool town_filter, const Industry *current)
114 {
115  uint32 GrfID = GetRegister(0x100);
116  IndustryType ind_index;
117  uint32 closest_dist = UINT32_MAX;
118  byte count = 0;
119 
120  /* Determine what will be the industry type to look for */
121  switch (GrfID) {
122  case 0: // this is a default industry type
123  ind_index = param_setID;
124  break;
125 
126  case 0xFFFFFFFF: // current grf
127  GrfID = GetIndustrySpec(current->type)->grf_prop.grffile->grfid;
128  FALLTHROUGH;
129 
130  default: // use the grfid specified in register 100h
131  SetBit(param_setID, 7); // bit 7 means it is not an old type
132  ind_index = MapNewGRFIndustryType(param_setID, GrfID);
133  break;
134  }
135 
136  /* If the industry type is invalid, there is none and the closest is far away. */
137  if (ind_index >= NUM_INDUSTRYTYPES) return 0 | 0xFFFF;
138 
139  if (layout_filter == 0 && !town_filter) {
140  /* If the filter is 0, it could be because none was specified as well as being really a 0.
141  * In either case, just do the regular var67 */
142  closest_dist = GetClosestIndustry(current->location.tile, ind_index, current);
143  count = min(Industry::GetIndustryTypeCount(ind_index), UINT8_MAX); // clamp to 8 bit
144  } else {
145  /* Count only those who match the same industry type and layout filter
146  * Unfortunately, we have to do it manually */
147  for (const Industry *i : Industry::Iterate()) {
148  if (i->type == ind_index && i != current && (i->selected_layout == layout_filter || layout_filter == 0) && (!town_filter || i->town == current->town)) {
149  closest_dist = min(closest_dist, DistanceManhattan(current->location.tile, i->location.tile));
150  count++;
151  }
152  }
153  }
154 
155  return count << 16 | GB(closest_dist, 0, 16);
156 }
157 
158 /* virtual */ uint32 IndustriesScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const
159 {
160  if (this->ro.callback == CBID_INDUSTRY_LOCATION) {
161  /* Variables available during construction check. */
162 
163  switch (variable) {
164  case 0x80: return this->tile;
165  case 0x81: return GB(this->tile, 8, 8);
166 
167  /* Pointer to the town the industry is associated with */
168  case 0x82: return this->industry->town->index;
169  case 0x83:
170  case 0x84:
171  case 0x85: DEBUG(grf, 0, "NewGRFs shouldn't be doing pointer magic"); break; // not supported
172 
173  /* Number of the layout */
174  case 0x86: return this->industry->selected_layout;
175 
176  /* Ground type */
177  case 0x87: return GetTerrainType(this->tile);
178 
179  /* Town zone */
180  case 0x88: return GetTownRadiusGroup(this->industry->town, this->tile);
181 
182  /* Manhattan distance of the closest town */
183  case 0x89: return min(DistanceManhattan(this->industry->town->xy, this->tile), 255);
184 
185  /* Lowest height of the tile */
186  case 0x8A: return Clamp(GetTileZ(this->tile) * (this->ro.grffile->grf_version >= 8 ? 1 : TILE_HEIGHT), 0, 0xFF);
187 
188  /* Distance to the nearest water/land tile */
190 
191  /* Square of Euclidian distance from town */
192  case 0x8D: return min(DistanceSquare(this->industry->town->xy, this->tile), 65535);
193 
194  /* 32 random bits */
195  case 0x8F: return this->random_bits;
196  }
197  }
198 
199  const IndustrySpec *indspec = GetIndustrySpec(this->type);
200 
201  if (this->industry == nullptr) {
202  DEBUG(grf, 1, "Unhandled variable 0x%X (no available industry) in callback 0x%x", variable, this->ro.callback);
203 
204  *available = false;
205  return UINT_MAX;
206  }
207 
208  switch (variable) {
209  case 0x40:
210  case 0x41:
211  case 0x42: { // waiting cargo, but only if those two callback flags are set
212  uint16 callback = indspec->callback_mask;
214  if ((indspec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) {
215  if (this->industry->prod_level == 0) return 0;
216  return min(this->industry->incoming_cargo_waiting[variable - 0x40] / this->industry->prod_level, (uint16)0xFFFF);
217  } else {
218  return min(this->industry->incoming_cargo_waiting[variable - 0x40], (uint16)0xFFFF);
219  }
220  } else {
221  return 0;
222  }
223  }
224 
225  /* Manhattan distance of closes dry/water tile */
226  case 0x43:
227  if (this->tile == INVALID_TILE) break;
228  return GetClosestWaterDistance(this->tile, (indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) == 0);
229 
230  /* Layout number */
231  case 0x44: return this->industry->selected_layout;
232 
233  /* Company info */
234  case 0x45: {
235  byte colours = 0;
236  bool is_ai = false;
237 
238  const Company *c = Company::GetIfValid(this->industry->founder);
239  if (c != nullptr) {
240  const Livery *l = &c->livery[LS_DEFAULT];
241 
242  is_ai = c->is_ai;
243  colours = l->colour1 + l->colour2 * 16;
244  }
245 
246  return this->industry->founder | (is_ai ? 0x10000 : 0) | (colours << 24);
247  }
248 
249  case 0x46: return this->industry->construction_date; // Date when built - long format - (in days)
250 
251  /* Get industry ID at offset param */
252  case 0x60: return GetIndustryIDAtOffset(GetNearbyTile(parameter, this->industry->location.tile, false), this->industry, this->ro.grffile->grfid);
253 
254  /* Get random tile bits at offset param */
255  case 0x61: {
256  if (this->tile == INVALID_TILE) break;
257  TileIndex tile = GetNearbyTile(parameter, this->tile, false);
258  return this->industry->TileBelongsToIndustry(tile) ? GetIndustryRandomBits(tile) : 0;
259  }
260 
261  /* Land info of nearby tiles */
262  case 0x62:
263  if (this->tile == INVALID_TILE) break;
264  return GetNearbyIndustryTileInformation(parameter, this->tile, INVALID_INDUSTRY, false, this->ro.grffile->grf_version >= 8);
265 
266  /* Animation stage of nearby tiles */
267  case 0x63: {
268  if (this->tile == INVALID_TILE) break;
269  TileIndex tile = GetNearbyTile(parameter, this->tile, false);
270  if (this->industry->TileBelongsToIndustry(tile)) {
271  return GetAnimationFrame(tile);
272  }
273  return 0xFFFFFFFF;
274  }
275 
276  /* Distance of nearest industry of given type */
277  case 0x64:
278  if (this->tile == INVALID_TILE) break;
279  return GetClosestIndustry(this->tile, MapNewGRFIndustryType(parameter, indspec->grf_prop.grffile->grfid), this->industry);
280  /* Get town zone and Manhattan distance of closest town */
281  case 0x65:
282  if (this->tile == INVALID_TILE) break;
283  return GetTownRadiusGroup(this->industry->town, this->tile) << 16 | min(DistanceManhattan(this->tile, this->industry->town->xy), 0xFFFF);
284  /* Get square of Euclidian distance of closes town */
285  case 0x66:
286  if (this->tile == INVALID_TILE) break;
287  return GetTownRadiusGroup(this->industry->town, this->tile) << 16 | min(DistanceSquare(this->tile, this->industry->town->xy), 0xFFFF);
288 
289  /* Count of industry, distance of closest instance
290  * 68 is the same as 67, but with a filtering on selected layout */
291  case 0x67:
292  case 0x68: {
293  byte layout_filter = 0;
294  bool town_filter = false;
295  if (variable == 0x68) {
296  uint32 reg = GetRegister(0x101);
297  layout_filter = GB(reg, 0, 8);
298  town_filter = HasBit(reg, 8);
299  }
300  return GetCountAndDistanceOfClosestInstance(parameter, layout_filter, town_filter, this->industry);
301  }
302 
303  case 0x69:
304  case 0x6A:
305  case 0x6B:
306  case 0x6C:
307  case 0x6D:
308  case 0x70:
309  case 0x71: {
310  CargoID cargo = GetCargoTranslation(parameter, this->ro.grffile);
311  int index = this->industry->GetCargoProducedIndex(cargo);
312  if (index < 0) return 0; // invalid cargo
313  switch (variable) {
314  case 0x69: return this->industry->produced_cargo_waiting[index];
315  case 0x6A: return this->industry->this_month_production[index];
316  case 0x6B: return this->industry->this_month_transported[index];
317  case 0x6C: return this->industry->last_month_production[index];
318  case 0x6D: return this->industry->last_month_transported[index];
319  case 0x70: return this->industry->production_rate[index];
320  case 0x71: return this->industry->last_month_pct_transported[index];
321  default: NOT_REACHED();
322  }
323  }
324 
325 
326  case 0x6E:
327  case 0x6F: {
328  CargoID cargo = GetCargoTranslation(parameter, this->ro.grffile);
329  int index = this->industry->GetCargoAcceptedIndex(cargo);
330  if (index < 0) return 0; // invalid cargo
331  if (variable == 0x6E) return this->industry->last_cargo_accepted_at[index];
332  if (variable == 0x6F) return this->industry->incoming_cargo_waiting[index];
333  NOT_REACHED();
334  }
335 
336  /* Get a variable from the persistent storage */
337  case 0x7C: return (this->industry->psa != nullptr) ? this->industry->psa->GetValue(parameter) : 0;
338 
339  /* Industry structure access*/
340  case 0x80: return this->industry->location.tile;
341  case 0x81: return GB(this->industry->location.tile, 8, 8);
342  /* Pointer to the town the industry is associated with */
343  case 0x82: return this->industry->town->index;
344  case 0x83:
345  case 0x84:
346  case 0x85: DEBUG(grf, 0, "NewGRFs shouldn't be doing pointer magic"); break; // not supported
347  case 0x86: return this->industry->location.w;
348  case 0x87: return this->industry->location.h;// xy dimensions
349 
350  case 0x88:
351  case 0x89: return this->industry->produced_cargo[variable - 0x88];
352  case 0x8A: return this->industry->produced_cargo_waiting[0];
353  case 0x8B: return GB(this->industry->produced_cargo_waiting[0], 8, 8);
354  case 0x8C: return this->industry->produced_cargo_waiting[1];
355  case 0x8D: return GB(this->industry->produced_cargo_waiting[1], 8, 8);
356  case 0x8E:
357  case 0x8F: return this->industry->production_rate[variable - 0x8E];
358  case 0x90:
359  case 0x91:
360  case 0x92: return this->industry->accepts_cargo[variable - 0x90];
361  case 0x93: return this->industry->prod_level;
362  /* amount of cargo produced so far THIS month. */
363  case 0x94: return this->industry->this_month_production[0];
364  case 0x95: return GB(this->industry->this_month_production[0], 8, 8);
365  case 0x96: return this->industry->this_month_production[1];
366  case 0x97: return GB(this->industry->this_month_production[1], 8, 8);
367  /* amount of cargo transported so far THIS month. */
368  case 0x98: return this->industry->this_month_transported[0];
369  case 0x99: return GB(this->industry->this_month_transported[0], 8, 8);
370  case 0x9A: return this->industry->this_month_transported[1];
371  case 0x9B: return GB(this->industry->this_month_transported[1], 8, 8);
372  /* fraction of cargo transported LAST month. */
373  case 0x9C:
374  case 0x9D: return this->industry->last_month_pct_transported[variable - 0x9C];
375  /* amount of cargo produced LAST month. */
376  case 0x9E: return this->industry->last_month_production[0];
377  case 0x9F: return GB(this->industry->last_month_production[0], 8, 8);
378  case 0xA0: return this->industry->last_month_production[1];
379  case 0xA1: return GB(this->industry->last_month_production[1], 8, 8);
380  /* amount of cargo transported last month. */
381  case 0xA2: return this->industry->last_month_transported[0];
382  case 0xA3: return GB(this->industry->last_month_transported[0], 8, 8);
383  case 0xA4: return this->industry->last_month_transported[1];
384  case 0xA5: return GB(this->industry->last_month_transported[1], 8, 8);
385 
386  case 0xA6: return indspec->grf_prop.local_id;
387  case 0xA7: return this->industry->founder;
388  case 0xA8: return this->industry->random_colour;
389  case 0xA9: return Clamp(this->industry->last_prod_year - ORIGINAL_BASE_YEAR, 0, 255);
390  case 0xAA: return this->industry->counter;
391  case 0xAB: return GB(this->industry->counter, 8, 8);
392  case 0xAC: return this->industry->was_cargo_delivered;
393 
394  case 0xB0: return Clamp(this->industry->construction_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Date when built since 1920 (in days)
395  case 0xB3: return this->industry->construction_type; // Construction type
396  case 0xB4: {
397  Date *latest = std::max_element(this->industry->last_cargo_accepted_at, endof(this->industry->last_cargo_accepted_at));
398  return Clamp((*latest) - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); // Date last cargo accepted since 1920 (in days)
399  }
400  }
401 
402  DEBUG(grf, 1, "Unhandled industry variable 0x%X", variable);
403 
404  *available = false;
405  return UINT_MAX;
406 }
407 
408 /* virtual */ uint32 IndustriesScopeResolver::GetRandomBits() const
409 {
410  return this->industry != nullptr ? this->industry->random : 0;
411 }
412 
413 /* virtual */ uint32 IndustriesScopeResolver::GetTriggers() const
414 {
415  return 0;
416 }
417 
418 /* virtual */ void IndustriesScopeResolver::StorePSA(uint pos, int32 value)
419 {
420  if (this->industry->index == INVALID_INDUSTRY) return;
421 
422  if (this->industry->psa == nullptr) {
423  /* There is no need to create a storage if the value is zero. */
424  if (value == 0) return;
425 
426  /* Create storage on first modification. */
427  const IndustrySpec *indsp = GetIndustrySpec(this->industry->type);
428  uint32 grfid = (indsp->grf_prop.grffile != nullptr) ? indsp->grf_prop.grffile->grfid : 0;
430  this->industry->psa = new PersistentStorage(grfid, GSF_INDUSTRIES, this->industry->location.tile);
431  }
432 
433  this->industry->psa->StoreValue(pos, value);
434 }
435 
441 static const GRFFile *GetGrffile(IndustryType type)
442 {
443  const IndustrySpec *indspec = GetIndustrySpec(type);
444  return (indspec != nullptr) ? indspec->grf_prop.grffile : nullptr;
445 }
446 
458  CallbackID callback, uint32 callback_param1, uint32 callback_param2)
459  : ResolverObject(GetGrffile(type), callback, callback_param1, callback_param2),
460  industries_scope(*this, tile, indus, type, random_bits),
461  town_scope(nullptr)
462 {
464 }
465 
466 IndustriesResolverObject::~IndustriesResolverObject()
467 {
468  delete this->town_scope;
469 }
470 
476 {
477  if (this->town_scope == nullptr) {
478  Town *t = nullptr;
479  bool readonly = true;
480  if (this->industries_scope.industry != nullptr) {
481  t = this->industries_scope.industry->town;
482  readonly = this->industries_scope.industry->index == INVALID_INDUSTRY;
483  } else if (this->industries_scope.tile != INVALID_TILE) {
484  t = ClosestTownFromTile(this->industries_scope.tile, UINT_MAX);
485  }
486  if (t == nullptr) return nullptr;
487  this->town_scope = new TownScopeResolver(*this, t, readonly);
488  }
489  return this->town_scope;
490 }
491 
502 uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile)
503 {
504  IndustriesResolverObject object(tile, industry, type, 0, callback, param1, param2);
505  return object.ResolveCallback();
506 }
507 
519 CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, size_t layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type)
520 {
521  const IndustrySpec *indspec = GetIndustrySpec(type);
522 
523  Industry ind;
524  ind.index = INVALID_INDUSTRY;
525  ind.location.tile = tile;
526  ind.location.w = 0; // important to mark the industry invalid
527  ind.type = type;
528  ind.selected_layout = (byte)layout;
529  ind.town = ClosestTownFromTile(tile, UINT_MAX);
530  ind.random = initial_random_bits;
531  ind.founder = founder;
532  ind.psa = nullptr;
533 
534  IndustriesResolverObject object(tile, &ind, type, seed, CBID_INDUSTRY_LOCATION, 0, creation_type);
535  uint16 result = object.ResolveCallback();
536 
537  /* Unlike the "normal" cases, not having a valid result means we allow
538  * the building of the industry, as that's how it's done in TTDP. */
539  if (result == CALLBACK_FAILED) return CommandCost();
540 
541  return GetErrorMessageFromLocationCallbackResult(result, indspec->grf_prop.grffile, STR_ERROR_SITE_UNSUITABLE);
542 }
543 
550 uint32 GetIndustryProbabilityCallback(IndustryType type, IndustryAvailabilityCallType creation_type, uint32 default_prob)
551 {
552  const IndustrySpec *indspec = GetIndustrySpec(type);
553 
554  if (HasBit(indspec->callback_mask, CBM_IND_PROBABILITY)) {
555  uint16 res = GetIndustryCallback(CBID_INDUSTRY_PROBABILITY, 0, creation_type, nullptr, type, INVALID_TILE);
556  if (res != CALLBACK_FAILED) {
557  if (indspec->grf_prop.grffile->grf_version < 8) {
558  /* Disallow if result != 0 */
559  if (res != 0) default_prob = 0;
560  } else {
561  /* Use returned probability. 0x100 to use default */
562  if (res < 0x100) {
563  default_prob = res;
564  } else if (res > 0x100) {
566  }
567  }
568  }
569  }
570  return default_prob;
571 }
572 
573 static int32 DerefIndProd(int field, bool use_register)
574 {
575  return use_register ? (int32)GetRegister(field) : field;
576 }
577 
583 void IndustryProductionCallback(Industry *ind, int reason)
584 {
585  const IndustrySpec *spec = GetIndustrySpec(ind->type);
586  IndustriesResolverObject object(ind->location.tile, ind, ind->type);
587  if ((spec->behaviour & INDUSTRYBEH_PRODCALLBACK_RANDOM) != 0) object.callback_param1 = Random();
588  int multiplier = 1;
589  if ((spec->behaviour & INDUSTRYBEH_PROD_MULTI_HNDLING) != 0) multiplier = ind->prod_level;
590  object.callback_param2 = reason;
591 
592  for (uint loop = 0;; loop++) {
593  /* limit the number of calls to break infinite loops.
594  * 'loop' is provided as 16 bits to the newgrf, so abort when those are exceeded. */
595  if (loop >= 0x10000) {
596  /* display error message */
597  SetDParamStr(0, spec->grf_prop.grffile->filename);
598  SetDParam(1, spec->name);
599  ShowErrorMessage(STR_NEWGRF_BUGGY, STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK, WL_WARNING);
600 
601  /* abort the function early, this error isn't critical and will allow the game to continue to run */
602  break;
603  }
604 
605  SB(object.callback_param2, 8, 16, loop);
606  const SpriteGroup *tgroup = object.Resolve();
607  if (tgroup == nullptr || tgroup->type != SGT_INDUSTRY_PRODUCTION) break;
608  const IndustryProductionSpriteGroup *group = (const IndustryProductionSpriteGroup *)tgroup;
609 
610  if (group->version == 0xFF) {
611  /* Result was marked invalid on load, display error message */
612  SetDParamStr(0, spec->grf_prop.grffile->filename);
613  SetDParam(1, spec->name);
614  SetDParam(2, ind->location.tile);
615  ShowErrorMessage(STR_NEWGRF_BUGGY, STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK, WL_WARNING);
616 
617  /* abort the function early, this error isn't critical and will allow the game to continue to run */
618  break;
619  }
620 
621  bool deref = (group->version >= 1);
622 
623  if (group->version < 2) {
624  /* Callback parameters map directly to industry cargo slot indices */
625  for (uint i = 0; i < group->num_input; i++) {
626  ind->incoming_cargo_waiting[i] = Clamp(ind->incoming_cargo_waiting[i] - DerefIndProd(group->subtract_input[i], deref) * multiplier, 0, 0xFFFF);
627  }
628  for (uint i = 0; i < group->num_output; i++) {
629  ind->produced_cargo_waiting[i] = Clamp(ind->produced_cargo_waiting[i] + max(DerefIndProd(group->add_output[i], deref), 0) * multiplier, 0, 0xFFFF);
630  }
631  } else {
632  /* Callback receives list of cargos to apply for, which need to have their cargo slots in industry looked up */
633  for (uint i = 0; i < group->num_input; i++) {
634  int cargo_index = ind->GetCargoAcceptedIndex(group->cargo_input[i]);
635  if (cargo_index < 0) continue;
636  ind->incoming_cargo_waiting[cargo_index] = Clamp(ind->incoming_cargo_waiting[cargo_index] - DerefIndProd(group->subtract_input[i], deref) * multiplier, 0, 0xFFFF);
637  }
638  for (uint i = 0; i < group->num_output; i++) {
639  int cargo_index = ind->GetCargoProducedIndex(group->cargo_output[i]);
640  if (cargo_index < 0) continue;
641  ind->produced_cargo_waiting[cargo_index] = Clamp(ind->produced_cargo_waiting[cargo_index] + max(DerefIndProd(group->add_output[i], deref), 0) * multiplier, 0, 0xFFFF);
642  }
643  }
644 
645  int32 again = DerefIndProd(group->again, deref);
646  if (again == 0) break;
647 
648  SB(object.callback_param2, 24, 8, again);
649  }
650 
652 }
653 
662 {
663  assert(std::find(ind->accepts_cargo, endof(ind->accepts_cargo), cargo_type) != endof(ind->accepts_cargo));
664 
665  const IndustrySpec *indspec = GetIndustrySpec(ind->type);
666  if (HasBit(indspec->callback_mask, CBM_IND_REFUSE_CARGO)) {
668  0, indspec->grf_prop.grffile->cargo_map[cargo_type],
669  ind, ind->type, ind->location.tile);
671  }
672  return false;
673 }
Functions related to OTTD&#39;s strings.
Owner
Enum for all companies/owners.
Definition: company_type.h:18
static IndustryGfx GetCleanIndustryGfx(TileIndex t)
Get the industry graphics ID for the given industry tile as stored in the without translation...
Definition: industry_map.h:125
Called to determine if the given industry can be built on specific area.
Definition of stuff that is very close to a company, like the company struct itself.
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:302
CargoID cargo_output[INDUSTRY_NUM_OUTPUTS]
Which output cargoes to add to (only cb version 2)
byte production_rate[INDUSTRY_NUM_OUTPUTS]
production rate for each cargo
Definition: industry.h:47
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
int16 subtract_input[INDUSTRY_NUM_INPUTS]
Take this much of the input cargo (can be negative, is indirect in cb version 1+) ...
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3215
uint32 GetRandomBits() const override
Get a few random bits.
ResolverObject & ro
Surrounding resolver object.
CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, size_t layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type)
Check that the industry callback allows creation of the industry.
uint16 counter
used for animation and/or production (if available cargo)
Definition: industry.h:55
#define DAYS_TILL_ORIGINAL_BASE_YEAR
The offset in days from the &#39;_date == 0&#39; till &#39;ConvertYMDToDate(ORIGINAL_BASE_YEAR, 0, 1)&#39;.
Definition: date_type.h:80
Functions for NewGRF industries.
Town * town
Nearest town.
Definition: industry.h:42
static byte GetAnimationFrame(TileIndex t)
Get the current animation frame.
Definition: tile_map.h:250
Functions related to debugging.
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
static const IndustryGfx INVALID_INDUSTRYTILE
one above amount is considered invalid
Definition: industry_type.h:34
CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoID.
Interface for SpriteGroup-s to access the gamestate.
uint32 GetTerrainType(TileIndex tile, TileContext context)
Function used by houses (and soon industries) to get information on type of "terrain" the tile it is ...
uint32 GetIndustryProbabilityCallback(IndustryType type, IndustryAvailabilityCallType creation_type, uint32 default_prob)
Check with callback CBID_INDUSTRY_PROBABILITY whether the industry can be built.
byte selected_layout
Which tile layout was used when creating the industry.
Definition: industry.h:70
uint8 construction_type
Way the industry was constructed (.
Definition: industry.h:68
uint32 GetTriggers() const override
Get the triggers.
TownScopeResolver * town_scope
Scope resolver for the associated town (if needed and available, else nullptr).
uint16 callback_mask
Bitmask of industry callbacks that have to be called.
Definition: industrytype.h:137
Defines the internal data of a functional industry.
Definition: industry.h:40
uint32 GetNearbyIndustryTileInformation(byte parameter, TileIndex tile, IndustryID index, bool signed_offsets, bool grf_version8)
Based on newhouses equivalent, but adapted for newindustries.
Tindex index
Index of this pool item.
Definition: pool_type.hpp:189
void IndustryProductionCallback(Industry *ind, int reason)
Get the industry production callback and apply it to the industry.
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x=0, int y=0, const GRFFile *textref_stack_grffile=nullptr, uint textref_stack_size=0, const uint32 *textref_stack=nullptr)
Display an error message in a window.
Definition: error_gui.cpp:380
Date last_cargo_accepted_at[INDUSTRY_NUM_INPUTS]
Last day each cargo type was accepted by this industry.
Definition: industry.h:69
byte was_cargo_delivered
flag that indicate this has been the closest industry chosen for cargo delivery by a station...
Definition: industry.h:61
uint16 random
Random value used for randomisation of all kinds of things.
Definition: industry.h:72
Common return value for all commands.
Definition: command_type.h:23
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:24
uint16 w
The width of the area.
Definition: tilearea_type.h:18
CommandCost GetErrorMessageFromLocationCallbackResult(uint16 cb_res, const GRFFile *grffile, StringID default_error)
Get the error message from a shape/location/slope check callback result.
byte random_colour
randomized colour of the industry, for display purpose
Definition: industry.h:59
StringID name
Displayed name of the industry.
Definition: industrytype.h:126
Automatic production multiplier handling.
Definition: industrytype.h:78
static T SB(T &x, const uint8 s, const uint8 n, const U d)
Set n bits in x starting at bit s to d.
bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type)
Check whether an industry temporarily refuses to accept a certain cargo.
uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override
Get a variable value.
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition: tile_map.cpp:121
Date construction_date
Date of the construction of the industry.
Definition: industry.h:67
Pseudo random number generator.
const SpriteGroup * root_spritegroup
Root SpriteGroup to use for resolving.
uint16 GetID(uint8 grf_local_id, uint32 grfid) const override
Return the ID (if ever available) of a previously inserted entity.
uint16 add_output[INDUSTRY_NUM_OUTPUTS]
Add this much output cargo when successful (unsigned, is indirect in cb version 1+) ...
Town * ClosestTownFromTile(TileIndex tile, uint threshold)
Return the town closest (in distance or ownership) to a given tile, within a given threshold...
Definition: town_cmd.cpp:3488
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
Definition: strings.cpp:279
uint16 this_month_production[INDUSTRY_NUM_OUTPUTS]
stats of this month&#39;s production per cargo
Definition: industry.h:50
uint8 num_output
How many add_output values are valid.
uint32 callback_param2
Second parameter (var 18) of the callback.
static uint32 GetRegister(uint i)
Gets the value of a so-called newgrf "register".
virtual const SpriteGroup * Resolve(ResolverObject &object) const
Base sprite group resolver.
TileIndex xy
town center tile
Definition: town.h:54
Other information.
Definition: error.h:22
TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets, Axis axis)
Get the tile at the given offset.
TYPE GetValue(uint pos) const
Gets the value from a given position.
Functions related to errors.
PersistentStorage * psa
Persistent storage for NewGRF industries.
Definition: industry.h:74
Called to determine if the given industry type is available.
uint16 this_month_transported[INDUSTRY_NUM_OUTPUTS]
stats of this month&#39;s transport per cargo
Definition: industry.h:51
void StoreValue(uint pos, int32 value)
Stores some value at a given position.
Year last_prod_year
last year of production
Definition: industry.h:60
bool ConvertBooleanCallback(const GRFFile *grffile, uint16 cbid, uint16 cb_res)
Converts a callback result into a boolean.
const IndustrySpec * GetIndustrySpec(IndustryType thistype)
Accessor for array _industry_specs.
Definition of base types and functions in a cross-platform compatible way.
A number of safeguards to prevent using unsafe methods.
Scope resolver for a town.
Definition: newgrf_town.h:22
IndustryType type
type of industry.
Definition: industry.h:57
IndustryType MapNewGRFIndustryType(IndustryType grf_type, uint32 grf_id)
Map the GRF local type to an industry type.
static const IndustryGfx NEW_INDUSTRYTILEOFFSET
original number of tiles
Definition: industry_type.h:32
TileArea location
Location of the industry.
Definition: industry.h:41
uint16 last_month_production[INDUSTRY_NUM_OUTPUTS]
total units produced per cargo in the last full month
Definition: industry.h:53
static const uint TILE_HEIGHT
Height of a height level in world coordinate AND in pixels in #ZOOM_LVL_BASE.
Definition: tile_type.h:16
Information about a particular livery.
Definition: livery.h:78
CargoID produced_cargo[INDUSTRY_NUM_OUTPUTS]
16 production cargo slots
Definition: industry.h:44
Class for pooled persistent storage of data.
static const IndustryGfx NUM_INDUSTRYTILES
total number of industry tiles, new and old
Definition: industry_type.h:33
uint32 GetIndustryIDAtOffset(TileIndex tile, const Industry *i, uint32 cur_grfid)
Make an analysis of a tile and check for its belonging to the same industry, and/or the same grf file...
Defines the data structure for constructing industry.
Definition: industrytype.h:106
static uint16 GetIndustryTypeCount(IndustryType type)
Get the count of industries for this type.
Definition: industry.h:148
bool is_ai
If true, the company is (also) controlled by the computer (a NoAI program).
Definition: company_base.h:93
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:171
IndustryType type
Type of the industry.
const IndustryTileSpec * GetIndustryTileSpec(IndustryGfx gfx)
Accessor for array _industry_tile_specs.
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
16 input cargo slots
Definition: industry.h:49
void StorePSA(uint pos, int32 value) override
Store a value into the persistent storage area (PSA).
IndustryAvailabilityCallType
From where has callback CBID_INDUSTRY_PROBABILITY been called.
Industry view; Window numbers:
Definition: window_type.h:356
uint8 cargo_map[NUM_CARGO]
Inverse cargo translation table (CargoID -> local ID)
Definition: newgrf.h:127
uint16 incoming_cargo_waiting[INDUSTRY_NUM_INPUTS]
incoming cargo waiting to be processed
Definition: industry.h:46
IndustryBehaviour behaviour
How this industry will behave, and how others entities can use it.
Definition: industrytype.h:124
byte prod_level
general production level
Definition: industry.h:48
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:140
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:40
HouseZonesBits GetTownRadiusGroup(const Town *t, TileIndex tile)
Returns the bit corresponding to the town zone of the specified tile.
Definition: town_cmd.cpp:2181
Called to determine if the industry can still accept or refuse more cargo arrival.
static const Year ORIGINAL_BASE_YEAR
The minimum starting year/base year of the original TTD.
Definition: date_type.h:49
byte colour2
Second colour, for vehicles with 2CC support.
Definition: livery.h:81
const struct SpriteGroup * spritegroup[Tcnt]
pointer to the different sprites of the entity
industry availability/probability callback
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:137
static const GRFFile * GetGrffile(IndustryType type)
Get the grf file associated with the given industry type.
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:35
uint16 override
id of the entity been replaced by
TileIndex tile
The base tile of the area.
Definition: tilearea_type.h:17
uint GetClosestWaterDistance(TileIndex tile, bool water)
Finds the distance for the closest tile with water/land given a tile.
Definition: map.cpp:340
const GRFFile * grffile
GRFFile the resolved SpriteGroup belongs to.
void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
static const IndustryType INVALID_INDUSTRYTYPE
one above amount is considered invalid
Definition: industry_type.h:27
uint16 produced_cargo_waiting[INDUSTRY_NUM_OUTPUTS]
amount of cargo produced per cargo
Definition: industry.h:45
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:340
is built on water (oil rig)
Definition: industrytype.h:65
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition: map.cpp:157
Cargo support for NewGRFs.
option out of accepting cargo
static const IndustryType NUM_INDUSTRYTYPES
total number of industry types, new and old; limited to 240 because we need some special ids like INV...
Definition: industry_type.h:26
TownScopeResolver * GetTown()
Get or create the town scope object associated with the industry.
CallbackID callback
Callback being resolved.
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
uint8 version
Production callback version used, or 0xFF if marked invalid.
#define endof(x)
Get the end element of an fixed size array.
Definition: stdafx.h:384
Town data structure.
Definition: town.h:53
call production callback when cargo arrives at the industry
Resolver for industries.
static const IndustryType NEW_INDUSTRYOFFSET
original number of industry types
Definition: industry_type.h:25
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:261
static byte GetIndustryRandomBits(TileIndex tile)
Get the random bits for this tile.
Definition: industry_map.h:224
Owner founder
Founder of the industry.
Definition: industry.h:66
uint16 local_id
id defined by the grf file for this entity
uint16 last_month_transported[INDUSTRY_NUM_OUTPUTS]
total units transported per cargo in the last full month
Definition: industry.h:54
Base of all industries.
int32 Date
The type to store our dates in.
Definition: date_type.h:14
const struct GRFFile * grffile
grf file that introduced this entity
CallbackID
List of implemented NewGRF callbacks.
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:83
Base of the town class.
byte colour1
First colour, for all vehicles.
Definition: livery.h:80
Functions to handle the town part of NewGRF towns.
bool TileBelongsToIndustry(TileIndex tile) const
Check if a given tile belongs to this industry.
Definition: industry.h:86
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:20
Defines the data structure of each individual tile of an industry.
Definition: industrytype.h:155
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the &#39;Square&#39; distance between the two given tiles.
Definition: map.cpp:174
Window functions not directly related to making/drawing windows.
uint32 random_bits
Random bits of the new industry.
static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout_filter, bool town_filter, const Industry *current)
Implementation of both var 67 and 68 since the mechanism is almost the same, it is easier to regroup ...
byte last_month_pct_transported[INDUSTRY_NUM_OUTPUTS]
percentage transported per cargo in the last full month
Definition: industry.h:52
uint8 num_input
How many subtract_input values are valid.
call production callback every 256 ticks
Industry * industry
Industry being resolved.
Production callback needs random bits in var 10.
Definition: industrytype.h:79
uint16 h
The height of the area.
Definition: tilearea_type.h:19
IndustriesScopeResolver industries_scope
Scope resolver for the industry.
CargoID cargo_input[INDUSTRY_NUM_INPUTS]
Which input cargoes to take from (only cb version 2)
TileIndex tile
Tile owned by the industry.
IndustriesResolverObject(TileIndex tile, Industry *indus, IndustryType type, uint32 random_bits=0, CallbackID callback=CBID_NO_CALLBACK, uint32 callback_param1=0, uint32 callback_param2=0)
Constructor of the industries resolver.
uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile)
Perform an industry callback.
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:105
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings_func.h:199