OpenTTD
industry_cmd.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 "clear_map.h"
12 #include "industry.h"
13 #include "station_base.h"
14 #include "landscape.h"
15 #include "viewport_func.h"
16 #include "command_func.h"
17 #include "town.h"
18 #include "news_func.h"
19 #include "cheat_type.h"
20 #include "genworld.h"
21 #include "tree_map.h"
22 #include "newgrf_cargo.h"
23 #include "newgrf_debug.h"
24 #include "newgrf_industrytiles.h"
25 #include "autoslope.h"
26 #include "water.h"
27 #include "strings_func.h"
28 #include "window_func.h"
29 #include "date_func.h"
30 #include "vehicle_func.h"
31 #include "sound_func.h"
32 #include "animated_tile_func.h"
33 #include "effectvehicle_func.h"
34 #include "effectvehicle_base.h"
35 #include "ai/ai.hpp"
36 #include "core/pool_func.hpp"
37 #include "subsidy_func.h"
38 #include "core/backup_type.hpp"
39 #include "object_base.h"
40 #include "game/game.hpp"
41 #include "error.h"
42 
43 #include "table/strings.h"
44 #include "table/industry_land.h"
45 #include "table/build_industry.h"
46 
47 #include "safeguards.h"
48 
49 IndustryPool _industry_pool("Industry");
51 
52 void ShowIndustryViewWindow(int industry);
53 void BuildOilRig(TileIndex tile);
54 
55 static byte _industry_sound_ctr;
56 static TileIndex _industry_sound_tile;
57 
59 
60 IndustrySpec _industry_specs[NUM_INDUSTRYTYPES];
61 IndustryTileSpec _industry_tile_specs[NUM_INDUSTRYTILES];
63 
71 {
72  for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) {
73  /* Reset the spec to default */
74  if (i < lengthof(_origin_industry_specs)) {
75  _industry_specs[i] = _origin_industry_specs[i];
76  } else {
77  _industry_specs[i] = IndustrySpec{};
78  }
79 
80  /* Enable only the current climate industries */
81  _industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET &&
82  HasBit(_origin_industry_specs[i].climate_availability, _settings_game.game_creation.landscape);
83  }
84 
85  memset(&_industry_tile_specs, 0, sizeof(_industry_tile_specs));
86  memcpy(&_industry_tile_specs, &_origin_industry_tile_specs, sizeof(_origin_industry_tile_specs));
87 
88  /* Reset any overrides that have been set. */
89  _industile_mngr.ResetOverride();
90  _industry_mngr.ResetOverride();
91 }
92 
101 IndustryType GetIndustryType(TileIndex tile)
102 {
103  assert(IsTileType(tile, MP_INDUSTRY));
104 
105  const Industry *ind = Industry::GetByTile(tile);
106  assert(ind != nullptr);
107  return ind->type;
108 }
109 
118 const IndustrySpec *GetIndustrySpec(IndustryType thistype)
119 {
120  assert(thistype < NUM_INDUSTRYTYPES);
121  return &_industry_specs[thistype];
122 }
123 
132 const IndustryTileSpec *GetIndustryTileSpec(IndustryGfx gfx)
133 {
134  assert(gfx < INVALID_INDUSTRYTILE);
135  return &_industry_tile_specs[gfx];
136 }
137 
138 Industry::~Industry()
139 {
140  if (CleaningPool()) return;
141 
142  /* Industry can also be destroyed when not fully initialized.
143  * This means that we do not have to clear tiles either.
144  * Also we must not decrement industry counts in that case. */
145  if (this->location.w == 0) return;
146 
147  const bool has_neutral_station = this->neutral_station != nullptr;
148 
149  TILE_AREA_LOOP(tile_cur, this->location) {
150  if (IsTileType(tile_cur, MP_INDUSTRY)) {
151  if (GetIndustryIndex(tile_cur) == this->index) {
152  DeleteNewGRFInspectWindow(GSF_INDUSTRYTILES, tile_cur);
153 
154  /* MakeWaterKeepingClass() can also handle 'land' */
155  MakeWaterKeepingClass(tile_cur, OWNER_NONE);
156  }
157  } else if (IsTileType(tile_cur, MP_STATION) && IsOilRig(tile_cur)) {
158  DeleteOilRig(tile_cur);
159  }
160  }
161 
162  if (has_neutral_station) {
163  /* Remove possible docking tiles */
164  TILE_AREA_LOOP(tile_cur, this->location) {
166  }
167  }
168 
169  if (GetIndustrySpec(this->type)->behaviour & INDUSTRYBEH_PLANT_FIELDS) {
170  TileArea ta = TileArea(this->location.tile, 0, 0).Expand(21);
171 
172  /* Remove the farmland and convert it to regular tiles over time. */
173  TILE_AREA_LOOP(tile_cur, ta) {
174  if (IsTileType(tile_cur, MP_CLEAR) && IsClearGround(tile_cur, CLEAR_FIELDS) &&
175  GetIndustryIndexOfField(tile_cur) == this->index) {
176  SetIndustryIndexOfField(tile_cur, INVALID_INDUSTRY);
177  }
178  }
179  }
180 
181  /* don't let any disaster vehicle target invalid industry */
183 
184  /* Clear the persistent storage. */
185  delete this->psa;
186 
187  DecIndustryTypeCount(this->type);
188 
189  DeleteIndustryNews(this->index);
191  DeleteNewGRFInspectWindow(GSF_INDUSTRIES, this->index);
192 
195 
196  for (Station *st : this->stations_near) {
197  st->industries_near.erase(this);
198  }
199 }
200 
206 {
208 }
209 
210 
216 {
217  if (Industry::GetNumItems() == 0) return nullptr;
218  int num = RandomRange((uint16)Industry::GetNumItems());
219  size_t index = MAX_UVALUE(size_t);
220 
221  while (num >= 0) {
222  num--;
223  index++;
224 
225  /* Make sure we have a valid industry */
226  while (!Industry::IsValidID(index)) {
227  index++;
228  assert(index < Industry::GetPoolSize());
229  }
230  }
231 
232  return Industry::Get(index);
233 }
234 
235 
236 static void IndustryDrawSugarMine(const TileInfo *ti)
237 {
238  if (!IsIndustryCompleted(ti->tile)) return;
239 
240  const DrawIndustryAnimationStruct *d = &_draw_industry_spec1[GetAnimationFrame(ti->tile)];
241 
242  AddChildSpriteScreen(SPR_IT_SUGAR_MINE_SIEVE + d->image_1, PAL_NONE, d->x, 0);
243 
244  if (d->image_2 != 0) {
245  AddChildSpriteScreen(SPR_IT_SUGAR_MINE_CLOUDS + d->image_2 - 1, PAL_NONE, 8, 41);
246  }
247 
248  if (d->image_3 != 0) {
249  AddChildSpriteScreen(SPR_IT_SUGAR_MINE_PILE + d->image_3 - 1, PAL_NONE,
250  _drawtile_proc1[d->image_3 - 1].x, _drawtile_proc1[d->image_3 - 1].y);
251  }
252 }
253 
254 static void IndustryDrawToffeeQuarry(const TileInfo *ti)
255 {
256  uint8 x = 0;
257 
258  if (IsIndustryCompleted(ti->tile)) {
259  x = _industry_anim_offs_toffee[GetAnimationFrame(ti->tile)];
260  if (x == 0xFF) {
261  x = 0;
262  }
263  }
264 
265  AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_SHOVEL, PAL_NONE, 22 - x, 24 + x);
266  AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_TOFFEE, PAL_NONE, 6, 14);
267 }
268 
269 static void IndustryDrawBubbleGenerator( const TileInfo *ti)
270 {
271  if (IsIndustryCompleted(ti->tile)) {
272  AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_BUBBLE, PAL_NONE, 5, _industry_anim_offs_bubbles[GetAnimationFrame(ti->tile)]);
273  }
274  AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_SPRING, PAL_NONE, 3, 67);
275 }
276 
277 static void IndustryDrawToyFactory(const TileInfo *ti)
278 {
279  const DrawIndustryAnimationStruct *d = &_industry_anim_offs_toys[GetAnimationFrame(ti->tile)];
280 
281  if (d->image_1 != 0xFF) {
282  AddChildSpriteScreen(SPR_IT_TOY_FACTORY_CLAY, PAL_NONE, d->x, 96 + d->image_1);
283  }
284 
285  if (d->image_2 != 0xFF) {
286  AddChildSpriteScreen(SPR_IT_TOY_FACTORY_ROBOT, PAL_NONE, 16 - d->image_2 * 2, 100 + d->image_2);
287  }
288 
289  AddChildSpriteScreen(SPR_IT_TOY_FACTORY_STAMP, PAL_NONE, 7, d->image_3);
290  AddChildSpriteScreen(SPR_IT_TOY_FACTORY_STAMP_HOLDER, PAL_NONE, 0, 42);
291 }
292 
293 static void IndustryDrawCoalPlantSparks(const TileInfo *ti)
294 {
295  if (IsIndustryCompleted(ti->tile)) {
296  uint8 image = GetAnimationFrame(ti->tile);
297 
298  if (image != 0 && image < 7) {
299  AddChildSpriteScreen(image + SPR_IT_POWER_PLANT_TRANSFORMERS,
300  PAL_NONE,
301  _coal_plant_sparks[image - 1].x,
302  _coal_plant_sparks[image - 1].y
303  );
304  }
305  }
306 }
307 
308 typedef void IndustryDrawTileProc(const TileInfo *ti);
309 static IndustryDrawTileProc * const _industry_draw_tile_procs[5] = {
310  IndustryDrawSugarMine,
311  IndustryDrawToffeeQuarry,
312  IndustryDrawBubbleGenerator,
313  IndustryDrawToyFactory,
314  IndustryDrawCoalPlantSparks,
315 };
316 
317 static void DrawTile_Industry(TileInfo *ti)
318 {
319  IndustryGfx gfx = GetIndustryGfx(ti->tile);
320  Industry *ind = Industry::GetByTile(ti->tile);
321  const IndustryTileSpec *indts = GetIndustryTileSpec(gfx);
322 
323  /* Retrieve pointer to the draw industry tile struct */
324  if (gfx >= NEW_INDUSTRYTILEOFFSET) {
325  /* Draw the tile using the specialized method of newgrf industrytile.
326  * DrawNewIndustry will return false if ever the resolver could not
327  * find any sprite to display. So in this case, we will jump on the
328  * substitute gfx instead. */
329  if (indts->grf_prop.spritegroup[0] != nullptr && DrawNewIndustryTile(ti, ind, gfx, indts)) {
330  return;
331  } else {
332  /* No sprite group (or no valid one) found, meaning no graphics associated.
333  * Use the substitute one instead */
334  if (indts->grf_prop.subst_id != INVALID_INDUSTRYTILE) {
335  gfx = indts->grf_prop.subst_id;
336  /* And point the industrytile spec accordingly */
337  indts = GetIndustryTileSpec(gfx);
338  }
339  }
340  }
341 
342  const DrawBuildingsTileStruct *dits = &_industry_draw_tile_data[gfx << 2 | (indts->anim_state ?
345 
346  SpriteID image = dits->ground.sprite;
347 
348  /* DrawFoundation() modifies ti->z and ti->tileh */
350 
351  /* If the ground sprite is the default flat water sprite, draw also canal/river borders.
352  * Do not do this if the tile's WaterClass is 'land'. */
353  if (image == SPR_FLAT_WATER_TILE && IsTileOnWater(ti->tile)) {
354  DrawWaterClassGround(ti);
355  } else {
356  DrawGroundSprite(image, GroundSpritePaletteTransform(image, dits->ground.pal, GENERAL_SPRITE_COLOUR(ind->random_colour)));
357  }
358 
359  /* If industries are transparent and invisible, do not draw the upper part */
360  if (IsInvisibilitySet(TO_INDUSTRIES)) return;
361 
362  /* Add industry on top of the ground? */
363  image = dits->building.sprite;
364  if (image != 0) {
365  AddSortableSpriteToDraw(image, SpriteLayoutPaletteTransform(image, dits->building.pal, GENERAL_SPRITE_COLOUR(ind->random_colour)),
366  ti->x + dits->subtile_x,
367  ti->y + dits->subtile_y,
368  dits->width,
369  dits->height,
370  dits->dz,
371  ti->z,
373 
374  if (IsTransparencySet(TO_INDUSTRIES)) return;
375  }
376 
377  {
378  int proc = dits->draw_proc - 1;
379  if (proc >= 0) _industry_draw_tile_procs[proc](ti);
380  }
381 }
382 
383 static int GetSlopePixelZ_Industry(TileIndex tile, uint x, uint y)
384 {
385  return GetTileMaxPixelZ(tile);
386 }
387 
388 static Foundation GetFoundation_Industry(TileIndex tile, Slope tileh)
389 {
390  IndustryGfx gfx = GetIndustryGfx(tile);
391 
392  /* For NewGRF industry tiles we might not be drawing a foundation. We need to
393  * account for this, as other structures should
394  * draw the wall of the foundation in this case.
395  */
396  if (gfx >= NEW_INDUSTRYTILEOFFSET) {
397  const IndustryTileSpec *indts = GetIndustryTileSpec(gfx);
398  if (indts->grf_prop.spritegroup[0] != nullptr && HasBit(indts->callback_mask, CBM_INDT_DRAW_FOUNDATIONS)) {
399  uint32 callback_res = GetIndustryTileCallback(CBID_INDTILE_DRAW_FOUNDATIONS, 0, 0, gfx, Industry::GetByTile(tile), tile);
400  if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(indts->grf_prop.grffile, CBID_INDTILE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE;
401  }
402  }
403  return FlatteningFoundation(tileh);
404 }
405 
406 static void AddAcceptedCargo_Industry(TileIndex tile, CargoArray &acceptance, CargoTypes *always_accepted)
407 {
408  IndustryGfx gfx = GetIndustryGfx(tile);
409  const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
410  const Industry *ind = Industry::GetByTile(tile);
411 
412  /* Starting point for acceptance */
414  int8 cargo_acceptance[lengthof(itspec->acceptance)];
415  MemCpyT(accepts_cargo, itspec->accepts_cargo, lengthof(accepts_cargo));
416  MemCpyT(cargo_acceptance, itspec->acceptance, lengthof(cargo_acceptance));
417 
419  /* Copy all accepted cargoes from industry itself */
420  for (uint i = 0; i < lengthof(ind->accepts_cargo); i++) {
421  CargoID *pos = std::find(accepts_cargo, endof(accepts_cargo), ind->accepts_cargo[i]);
422  if (pos == endof(accepts_cargo)) {
423  /* Not found, insert */
424  pos = std::find(accepts_cargo, endof(accepts_cargo), CT_INVALID);
425  if (pos == endof(accepts_cargo)) continue; // nowhere to place, give up on this one
426  *pos = ind->accepts_cargo[i];
427  }
428  cargo_acceptance[pos - accepts_cargo] += 8;
429  }
430  }
431 
433  /* Try callback for accepts list, if success override all existing accepts */
434  uint16 res = GetIndustryTileCallback(CBID_INDTILE_ACCEPT_CARGO, 0, 0, gfx, Industry::GetByTile(tile), tile);
435  if (res != CALLBACK_FAILED) {
436  MemSetT(accepts_cargo, CT_INVALID, lengthof(accepts_cargo));
437  for (uint i = 0; i < 3; i++) accepts_cargo[i] = GetCargoTranslation(GB(res, i * 5, 5), itspec->grf_prop.grffile);
438  }
439  }
440 
442  /* Try callback for acceptance list, if success override all existing acceptance */
443  uint16 res = GetIndustryTileCallback(CBID_INDTILE_CARGO_ACCEPTANCE, 0, 0, gfx, Industry::GetByTile(tile), tile);
444  if (res != CALLBACK_FAILED) {
445  MemSetT(cargo_acceptance, 0, lengthof(cargo_acceptance));
446  for (uint i = 0; i < 3; i++) cargo_acceptance[i] = GB(res, i * 4, 4);
447  }
448  }
449 
450  for (byte i = 0; i < lengthof(itspec->accepts_cargo); i++) {
451  CargoID a = accepts_cargo[i];
452  if (a == CT_INVALID || cargo_acceptance[i] <= 0) continue; // work only with valid cargoes
453 
454  /* Add accepted cargo */
455  acceptance[a] += cargo_acceptance[i];
456 
457  /* Maybe set 'always accepted' bit (if it's not set already) */
458  if (HasBit(*always_accepted, a)) continue;
459 
460  bool accepts = false;
461  for (uint cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
462  /* Test whether the industry itself accepts the cargo type */
463  if (ind->accepts_cargo[cargo_index] == a) {
464  accepts = true;
465  break;
466  }
467  }
468 
469  if (accepts) continue;
470 
471  /* If the industry itself doesn't accept this cargo, set 'always accepted' bit */
472  SetBit(*always_accepted, a);
473  }
474 }
475 
476 static void GetTileDesc_Industry(TileIndex tile, TileDesc *td)
477 {
478  const Industry *i = Industry::GetByTile(tile);
479  const IndustrySpec *is = GetIndustrySpec(i->type);
480 
481  td->owner[0] = i->owner;
482  td->str = is->name;
483  if (!IsIndustryCompleted(tile)) {
484  SetDParamX(td->dparam, 0, td->str);
485  td->str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
486  }
487 
488  if (is->grf_prop.grffile != nullptr) {
489  td->grf = GetGRFConfig(is->grf_prop.grffile->grfid)->GetName();
490  }
491 }
492 
493 static CommandCost ClearTile_Industry(TileIndex tile, DoCommandFlag flags)
494 {
495  Industry *i = Industry::GetByTile(tile);
496  const IndustrySpec *indspec = GetIndustrySpec(i->type);
497 
498  /* water can destroy industries
499  * in editor you can bulldoze industries
500  * with magic_bulldozer cheat you can destroy industries
501  * (area around OILRIG is water, so water shouldn't flood it
502  */
503  if ((_current_company != OWNER_WATER && _game_mode != GM_EDITOR &&
505  ((flags & DC_AUTO) != 0) ||
507  ((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) ||
508  HasBit(GetIndustryTileSpec(GetIndustryGfx(tile))->slopes_refused, 5)))) {
509  SetDParam(1, indspec->name);
510  return_cmd_error(flags & DC_AUTO ? STR_ERROR_GENERIC_OBJECT_IN_THE_WAY : INVALID_STRING_ID);
511  }
512 
513  if (flags & DC_EXEC) {
514  AI::BroadcastNewEvent(new ScriptEventIndustryClose(i->index));
515  Game::NewEvent(new ScriptEventIndustryClose(i->index));
516  delete i;
517  }
519 }
520 
527 {
528  Industry *i = Industry::GetByTile(tile);
529  const IndustrySpec *indspec = GetIndustrySpec(i->type);
530  bool moved_cargo = false;
531 
532  for (uint j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
533  uint cw = min(i->produced_cargo_waiting[j], 255);
534  if (cw > indspec->minimal_cargo && i->produced_cargo[j] != CT_INVALID) {
535  i->produced_cargo_waiting[j] -= cw;
536 
537  /* fluctuating economy? */
538  if (EconomyIsInRecession()) cw = (cw + 1) / 2;
539 
540  i->this_month_production[j] += cw;
541 
542  uint am = MoveGoodsToStation(i->produced_cargo[j], cw, ST_INDUSTRY, i->index, &i->stations_near);
543  i->this_month_transported[j] += am;
544 
545  moved_cargo |= (am != 0);
546  }
547  }
548 
549  return moved_cargo;
550 }
551 
552 
553 static void AnimateTile_Industry(TileIndex tile)
554 {
555  IndustryGfx gfx = GetIndustryGfx(tile);
556 
557  if (GetIndustryTileSpec(gfx)->animation.status != ANIM_STATUS_NO_ANIMATION) {
558  AnimateNewIndustryTile(tile);
559  return;
560  }
561 
562  switch (gfx) {
563  case GFX_SUGAR_MINE_SIEVE:
564  if ((_tick_counter & 1) == 0) {
565  byte m = GetAnimationFrame(tile) + 1;
566 
568  switch (m & 7) {
569  case 2: SndPlayTileFx(SND_2D_RIP_2, tile); break;
570  case 6: SndPlayTileFx(SND_29_RIP, tile); break;
571  }
572  }
573 
574  if (m >= 96) {
575  m = 0;
576  DeleteAnimatedTile(tile);
577  }
578  SetAnimationFrame(tile, m);
579 
580  MarkTileDirtyByTile(tile);
581  }
582  break;
583 
584  case GFX_TOFFEE_QUARY:
585  if ((_tick_counter & 3) == 0) {
586  byte m = GetAnimationFrame(tile);
587 
588  if (_industry_anim_offs_toffee[m] == 0xFF && _settings_client.sound.ambient) {
589  SndPlayTileFx(SND_30_CARTOON_SOUND, tile);
590  }
591 
592  if (++m >= 70) {
593  m = 0;
594  DeleteAnimatedTile(tile);
595  }
596  SetAnimationFrame(tile, m);
597 
598  MarkTileDirtyByTile(tile);
599  }
600  break;
601 
602  case GFX_BUBBLE_CATCHER:
603  if ((_tick_counter & 1) == 0) {
604  byte m = GetAnimationFrame(tile);
605 
606  if (++m >= 40) {
607  m = 0;
608  DeleteAnimatedTile(tile);
609  }
610  SetAnimationFrame(tile, m);
611 
612  MarkTileDirtyByTile(tile);
613  }
614  break;
615 
616  /* Sparks on a coal plant */
617  case GFX_POWERPLANT_SPARKS:
618  if ((_tick_counter & 3) == 0) {
619  byte m = GetAnimationFrame(tile);
620  if (m == 6) {
621  SetAnimationFrame(tile, 0);
622  DeleteAnimatedTile(tile);
623  } else {
624  SetAnimationFrame(tile, m + 1);
625  MarkTileDirtyByTile(tile);
626  }
627  }
628  break;
629 
630  case GFX_TOY_FACTORY:
631  if ((_tick_counter & 1) == 0) {
632  byte m = GetAnimationFrame(tile) + 1;
633 
634  switch (m) {
635  case 1: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2C_MACHINERY, tile); break;
636  case 23: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2B_COMEDY_HIT, tile); break;
637  case 28: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2A_EXTRACT_AND_POP, tile); break;
638  default:
639  if (m >= 50) {
640  int n = GetIndustryAnimationLoop(tile) + 1;
641  m = 0;
642  if (n >= 8) {
643  n = 0;
644  DeleteAnimatedTile(tile);
645  }
646  SetIndustryAnimationLoop(tile, n);
647  }
648  }
649 
650  SetAnimationFrame(tile, m);
651  MarkTileDirtyByTile(tile);
652  }
653  break;
654 
655  case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
656  case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
657  case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
658  case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
659  if ((_tick_counter & 3) == 0) {
660  IndustryGfx gfx = GetIndustryGfx(tile);
661 
662  gfx = (gfx < 155) ? gfx + 1 : 148;
663  SetIndustryGfx(tile, gfx);
664  MarkTileDirtyByTile(tile);
665  }
666  break;
667 
668  case GFX_OILWELL_ANIMATED_1:
669  case GFX_OILWELL_ANIMATED_2:
670  case GFX_OILWELL_ANIMATED_3:
671  if ((_tick_counter & 7) == 0) {
672  bool b = Chance16(1, 7);
673  IndustryGfx gfx = GetIndustryGfx(tile);
674 
675  byte m = GetAnimationFrame(tile) + 1;
676  if (m == 4 && (m = 0, ++gfx) == GFX_OILWELL_ANIMATED_3 + 1 && (gfx = GFX_OILWELL_ANIMATED_1, b)) {
677  SetIndustryGfx(tile, GFX_OILWELL_NOT_ANIMATED);
679  DeleteAnimatedTile(tile);
680  } else {
681  SetAnimationFrame(tile, m);
682  SetIndustryGfx(tile, gfx);
683  MarkTileDirtyByTile(tile);
684  }
685  }
686  break;
687 
688  case GFX_COAL_MINE_TOWER_ANIMATED:
689  case GFX_COPPER_MINE_TOWER_ANIMATED:
690  case GFX_GOLD_MINE_TOWER_ANIMATED: {
691  int state = _tick_counter & 0x7FF;
692 
693  if ((state -= 0x400) < 0) return;
694 
695  if (state < 0x1A0) {
696  if (state < 0x20 || state >= 0x180) {
697  byte m = GetAnimationFrame(tile);
698  if (!(m & 0x40)) {
699  SetAnimationFrame(tile, m | 0x40);
700  if (_settings_client.sound.ambient) SndPlayTileFx(SND_0B_MINING_MACHINERY, tile);
701  }
702  if (state & 7) return;
703  } else {
704  if (state & 3) return;
705  }
706  byte m = (GetAnimationFrame(tile) + 1) | 0x40;
707  if (m > 0xC2) m = 0xC0;
708  SetAnimationFrame(tile, m);
709  MarkTileDirtyByTile(tile);
710  } else if (state >= 0x200 && state < 0x3A0) {
711  int i = (state < 0x220 || state >= 0x380) ? 7 : 3;
712  if (state & i) return;
713 
714  byte m = (GetAnimationFrame(tile) & 0xBF) - 1;
715  if (m < 0x80) m = 0x82;
716  SetAnimationFrame(tile, m);
717  MarkTileDirtyByTile(tile);
718  }
719  break;
720  }
721  }
722 }
723 
724 static void CreateChimneySmoke(TileIndex tile)
725 {
726  uint x = TileX(tile) * TILE_SIZE;
727  uint y = TileY(tile) * TILE_SIZE;
728  int z = GetTileMaxPixelZ(tile);
729 
730  CreateEffectVehicle(x + 15, y + 14, z + 59, EV_CHIMNEY_SMOKE);
731 }
732 
733 static void MakeIndustryTileBigger(TileIndex tile)
734 {
735  byte cnt = GetIndustryConstructionCounter(tile) + 1;
736  if (cnt != 4) {
738  return;
739  }
740 
741  byte stage = GetIndustryConstructionStage(tile) + 1;
743  SetIndustryConstructionStage(tile, stage);
744  StartStopIndustryTileAnimation(tile, IAT_CONSTRUCTION_STATE_CHANGE);
745  if (stage == INDUSTRY_COMPLETED) SetIndustryCompleted(tile);
746 
747  MarkTileDirtyByTile(tile);
748 
749  if (!IsIndustryCompleted(tile)) return;
750 
751  IndustryGfx gfx = GetIndustryGfx(tile);
752  if (gfx >= NEW_INDUSTRYTILEOFFSET) {
753  /* New industries are already animated on construction. */
754  return;
755  }
756 
757  switch (gfx) {
758  case GFX_POWERPLANT_CHIMNEY:
759  CreateChimneySmoke(tile);
760  break;
761 
762  case GFX_OILRIG_1: {
763  /* Do not require an industry tile to be after the first two GFX_OILRIG_1
764  * tiles (like the default oil rig). Do a proper check to ensure the
765  * tiles belong to the same industry and based on that build the oil rig's
766  * station. */
767  TileIndex other = tile + TileDiffXY(0, 1);
768 
769  if (IsTileType(other, MP_INDUSTRY) &&
770  GetIndustryGfx(other) == GFX_OILRIG_1 &&
771  GetIndustryIndex(tile) == GetIndustryIndex(other)) {
772  BuildOilRig(tile);
773  }
774  break;
775  }
776 
777  case GFX_TOY_FACTORY:
778  case GFX_BUBBLE_CATCHER:
779  case GFX_TOFFEE_QUARY:
780  SetAnimationFrame(tile, 0);
781  SetIndustryAnimationLoop(tile, 0);
782  break;
783 
784  case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
785  case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
786  case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
787  case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
788  AddAnimatedTile(tile);
789  break;
790  }
791 }
792 
793 static void TileLoopIndustry_BubbleGenerator(TileIndex tile)
794 {
795  static const int8 _bubble_spawn_location[3][4] = {
796  { 11, 0, -4, -14 },
797  { -4, -10, -4, 1 },
798  { 49, 59, 60, 65 },
799  };
800 
801  if (_settings_client.sound.ambient) SndPlayTileFx(SND_2E_EXTRACT_AND_POP, tile);
802 
803  int dir = Random() & 3;
804 
806  TileX(tile) * TILE_SIZE + _bubble_spawn_location[0][dir],
807  TileY(tile) * TILE_SIZE + _bubble_spawn_location[1][dir],
808  _bubble_spawn_location[2][dir],
809  EV_BUBBLE
810  );
811 
812  if (v != nullptr) v->animation_substate = dir;
813 }
814 
815 static void TileLoop_Industry(TileIndex tile)
816 {
817  if (IsTileOnWater(tile)) TileLoop_Water(tile);
818 
819  /* Normally this doesn't happen, but if an industry NewGRF is removed
820  * an industry that was previously build on water can now be flooded.
821  * If this happens the tile is no longer an industry tile after
822  * returning from TileLoop_Water. */
823  if (!IsTileType(tile, MP_INDUSTRY)) return;
824 
826 
827  if (!IsIndustryCompleted(tile)) {
828  MakeIndustryTileBigger(tile);
829  return;
830  }
831 
832  if (_game_mode == GM_EDITOR) return;
833 
834  if (TransportIndustryGoods(tile) && !StartStopIndustryTileAnimation(Industry::GetByTile(tile), IAT_INDUSTRY_DISTRIBUTES_CARGO)) {
835  uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production;
836 
837  if (newgfx != INDUSTRYTILE_NOANIM) {
839  SetIndustryCompleted(tile);
840  SetIndustryGfx(tile, newgfx);
841  MarkTileDirtyByTile(tile);
842  return;
843  }
844  }
845 
846  if (StartStopIndustryTileAnimation(tile, IAT_TILELOOP)) return;
847 
848  IndustryGfx newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_next;
849  if (newgfx != INDUSTRYTILE_NOANIM) {
851  SetIndustryGfx(tile, newgfx);
852  MarkTileDirtyByTile(tile);
853  return;
854  }
855 
856  IndustryGfx gfx = GetIndustryGfx(tile);
857  switch (gfx) {
858  case GFX_COAL_MINE_TOWER_NOT_ANIMATED:
859  case GFX_COPPER_MINE_TOWER_NOT_ANIMATED:
860  case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:
861  if (!(_tick_counter & 0x400) && Chance16(1, 2)) {
862  switch (gfx) {
863  case GFX_COAL_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COAL_MINE_TOWER_ANIMATED; break;
864  case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_ANIMATED; break;
865  case GFX_GOLD_MINE_TOWER_NOT_ANIMATED: gfx = GFX_GOLD_MINE_TOWER_ANIMATED; break;
866  }
867  SetIndustryGfx(tile, gfx);
868  SetAnimationFrame(tile, 0x80);
869  AddAnimatedTile(tile);
870  }
871  break;
872 
873  case GFX_OILWELL_NOT_ANIMATED:
874  if (Chance16(1, 6)) {
875  SetIndustryGfx(tile, GFX_OILWELL_ANIMATED_1);
876  SetAnimationFrame(tile, 0);
877  AddAnimatedTile(tile);
878  }
879  break;
880 
881  case GFX_COAL_MINE_TOWER_ANIMATED:
882  case GFX_COPPER_MINE_TOWER_ANIMATED:
883  case GFX_GOLD_MINE_TOWER_ANIMATED:
884  if (!(_tick_counter & 0x400)) {
885  switch (gfx) {
886  case GFX_COAL_MINE_TOWER_ANIMATED: gfx = GFX_COAL_MINE_TOWER_NOT_ANIMATED; break;
887  case GFX_COPPER_MINE_TOWER_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_NOT_ANIMATED; break;
888  case GFX_GOLD_MINE_TOWER_ANIMATED: gfx = GFX_GOLD_MINE_TOWER_NOT_ANIMATED; break;
889  }
890  SetIndustryGfx(tile, gfx);
891  SetIndustryCompleted(tile);
893  DeleteAnimatedTile(tile);
894  }
895  break;
896 
897  case GFX_POWERPLANT_SPARKS:
898  if (Chance16(1, 3)) {
899  if (_settings_client.sound.ambient) SndPlayTileFx(SND_0C_ELECTRIC_SPARK, tile);
900  AddAnimatedTile(tile);
901  }
902  break;
903 
904  case GFX_COPPER_MINE_CHIMNEY:
906  break;
907 
908 
909  case GFX_TOY_FACTORY: {
910  Industry *i = Industry::GetByTile(tile);
911  if (i->was_cargo_delivered) {
912  i->was_cargo_delivered = false;
913  SetIndustryAnimationLoop(tile, 0);
914  AddAnimatedTile(tile);
915  }
916  }
917  break;
918 
919  case GFX_BUBBLE_GENERATOR:
920  TileLoopIndustry_BubbleGenerator(tile);
921  break;
922 
923  case GFX_TOFFEE_QUARY:
924  AddAnimatedTile(tile);
925  break;
926 
927  case GFX_SUGAR_MINE_SIEVE:
928  if (Chance16(1, 3)) AddAnimatedTile(tile);
929  break;
930  }
931 }
932 
933 static bool ClickTile_Industry(TileIndex tile)
934 {
935  ShowIndustryViewWindow(GetIndustryIndex(tile));
936  return true;
937 }
938 
939 static TrackStatus GetTileTrackStatus_Industry(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
940 {
941  return 0;
942 }
943 
944 static void ChangeTileOwner_Industry(TileIndex tile, Owner old_owner, Owner new_owner)
945 {
946  /* If the founder merges, the industry was created by the merged company */
947  Industry *i = Industry::GetByTile(tile);
948  if (i->founder == old_owner) i->founder = (new_owner == INVALID_OWNER) ? OWNER_NONE : new_owner;
949 }
950 
957 {
958  /* Check for industry tile */
959  if (!IsTileType(tile, MP_INDUSTRY)) return false;
960 
961  const Industry *ind = Industry::GetByTile(tile);
962 
963  /* Check for organic industry (i.e. not processing or extractive) */
964  if ((GetIndustrySpec(ind->type)->life_type & INDUSTRYLIFE_ORGANIC) == 0) return false;
965 
966  /* Check for wood production */
967  for (uint i = 0; i < lengthof(ind->produced_cargo); i++) {
968  /* The industry produces wood. */
969  if (ind->produced_cargo[i] != CT_INVALID && CargoSpec::Get(ind->produced_cargo[i])->label == 'WOOD') return true;
970  }
971 
972  return false;
973 }
974 
975 static const byte _plantfarmfield_type[] = {1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
976 
984 static bool IsSuitableForFarmField(TileIndex tile, bool allow_fields)
985 {
986  switch (GetTileType(tile)) {
987  case MP_CLEAR: return !IsClearGround(tile, CLEAR_SNOW) && !IsClearGround(tile, CLEAR_DESERT) && (allow_fields || !IsClearGround(tile, CLEAR_FIELDS));
988  case MP_TREES: return GetTreeGround(tile) != TREE_GROUND_SHORE;
989  default: return false;
990  }
991 }
992 
1000 static void SetupFarmFieldFence(TileIndex tile, int size, byte type, DiagDirection side)
1001 {
1002  TileIndexDiff diff = (DiagDirToAxis(side) == AXIS_Y ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
1003 
1004  do {
1005  tile = TILE_MASK(tile);
1006 
1007  if (IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS)) {
1008  byte or_ = type;
1009 
1010  if (or_ == 1 && Chance16(1, 7)) or_ = 2;
1011 
1012  SetFence(tile, side, or_);
1013  }
1014 
1015  tile += diff;
1016  } while (--size);
1017 }
1018 
1019 static void PlantFarmField(TileIndex tile, IndustryID industry)
1020 {
1021  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
1022  if (GetTileZ(tile) + 2 >= GetSnowLine()) return;
1023  }
1024 
1025  /* determine field size */
1026  uint32 r = (Random() & 0x303) + 0x404;
1027  if (_settings_game.game_creation.landscape == LT_ARCTIC) r += 0x404;
1028  uint size_x = GB(r, 0, 8);
1029  uint size_y = GB(r, 8, 8);
1030 
1031  TileArea ta(tile - TileDiffXY(min(TileX(tile), size_x / 2), min(TileY(tile), size_y / 2)), size_x, size_y);
1032  ta.ClampToMap();
1033 
1034  if (ta.w == 0 || ta.h == 0) return;
1035 
1036  /* check the amount of bad tiles */
1037  int count = 0;
1038  TILE_AREA_LOOP(cur_tile, ta) {
1039  assert(cur_tile < MapSize());
1040  count += IsSuitableForFarmField(cur_tile, false);
1041  }
1042  if (count * 2 < ta.w * ta.h) return;
1043 
1044  /* determine type of field */
1045  r = Random();
1046  uint counter = GB(r, 5, 3);
1047  uint field_type = GB(r, 8, 8) * 9 >> 8;
1048 
1049  /* make field */
1050  TILE_AREA_LOOP(cur_tile, ta) {
1051  assert(cur_tile < MapSize());
1052  if (IsSuitableForFarmField(cur_tile, true)) {
1053  MakeField(cur_tile, field_type, industry);
1054  SetClearCounter(cur_tile, counter);
1055  MarkTileDirtyByTile(cur_tile);
1056  }
1057  }
1058 
1059  int type = 3;
1060  if (_settings_game.game_creation.landscape != LT_ARCTIC && _settings_game.game_creation.landscape != LT_TROPIC) {
1061  type = _plantfarmfield_type[Random() & 0xF];
1062  }
1063 
1064  SetupFarmFieldFence(ta.tile, ta.h, type, DIAGDIR_NE);
1065  SetupFarmFieldFence(ta.tile, ta.w, type, DIAGDIR_NW);
1066  SetupFarmFieldFence(ta.tile + TileDiffXY(ta.w - 1, 0), ta.h, type, DIAGDIR_SW);
1067  SetupFarmFieldFence(ta.tile + TileDiffXY(0, ta.h - 1), ta.w, type, DIAGDIR_SE);
1068 }
1069 
1070 void PlantRandomFarmField(const Industry *i)
1071 {
1072  int x = i->location.w / 2 + Random() % 31 - 16;
1073  int y = i->location.h / 2 + Random() % 31 - 16;
1074 
1075  TileIndex tile = TileAddWrap(i->location.tile, x, y);
1076 
1077  if (tile != INVALID_TILE) PlantFarmField(tile, i->index);
1078 }
1079 
1086 static bool SearchLumberMillTrees(TileIndex tile, void *user_data)
1087 {
1088  if (IsTileType(tile, MP_TREES) && GetTreeGrowth(tile) > 2) {
1089  /* found a tree */
1090 
1091  Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
1092 
1093  _industry_sound_ctr = 1;
1094  _industry_sound_tile = tile;
1095  if (_settings_client.sound.ambient) SndPlayTileFx(SND_38_CHAINSAW, tile);
1096 
1097  DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
1098 
1099  cur_company.Restore();
1100  return true;
1101  }
1102  return false;
1103 }
1104 
1110 {
1111  /* We only want to cut trees if all tiles are completed. */
1112  TILE_AREA_LOOP(tile_cur, i->location) {
1113  if (i->TileBelongsToIndustry(tile_cur)) {
1114  if (!IsIndustryCompleted(tile_cur)) return;
1115  }
1116  }
1117 
1118  TileIndex tile = i->location.tile;
1119  if (CircularTileSearch(&tile, 40, SearchLumberMillTrees, nullptr)) { // 40x40 tiles to search.
1120  i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + 45); // Found a tree, add according value to waiting cargo.
1121  }
1122 }
1123 
1124 static void ProduceIndustryGoods(Industry *i)
1125 {
1126  const IndustrySpec *indsp = GetIndustrySpec(i->type);
1127 
1128  /* play a sound? */
1129  if ((i->counter & 0x3F) == 0) {
1130  uint32 r;
1131  if (Chance16R(1, 14, r) && indsp->number_of_sounds != 0 && _settings_client.sound.ambient) {
1132  for (size_t j = 0; j < lengthof(i->last_month_production); j++) {
1133  if (i->last_month_production[j] > 0) {
1134  /* Play sound since last month had production */
1135  SndPlayTileFx(
1136  (SoundFx)(indsp->random_sounds[((r >> 16) * indsp->number_of_sounds) >> 16]),
1137  i->location.tile);
1138  break;
1139  }
1140  }
1141  }
1142  }
1143 
1144  i->counter--;
1145 
1146  /* produce some cargo */
1147  if ((i->counter % INDUSTRY_PRODUCE_TICKS) == 0) {
1149 
1150  IndustryBehaviour indbehav = indsp->behaviour;
1151  for (size_t j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
1152  i->produced_cargo_waiting[j] = min(0xffff, i->produced_cargo_waiting[j] + i->production_rate[j]);
1153  }
1154 
1155  if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
1156  uint16 cb_res = CALLBACK_FAILED;
1158  cb_res = GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 0, i, i->type, i->location.tile);
1159  }
1160 
1161  bool plant;
1162  if (cb_res != CALLBACK_FAILED) {
1164  } else {
1165  plant = Chance16(1, 8);
1166  }
1167 
1168  if (plant) PlantRandomFarmField(i);
1169  }
1170  if ((indbehav & INDUSTRYBEH_CUT_TREES) != 0) {
1171  uint16 cb_res = CALLBACK_FAILED;
1173  cb_res = GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 1, i, i->type, i->location.tile);
1174  }
1175 
1176  bool cut;
1177  if (cb_res != CALLBACK_FAILED) {
1179  } else {
1180  cut = ((i->counter % INDUSTRY_CUT_TREE_TICKS) == 0);
1181  }
1182 
1183  if (cut) ChopLumberMillTrees(i);
1184  }
1185 
1187  StartStopIndustryTileAnimation(i, IAT_INDUSTRY_TICK);
1188  }
1189 }
1190 
1191 void OnTick_Industry()
1192 {
1193  if (_industry_sound_ctr != 0) {
1194  _industry_sound_ctr++;
1195 
1196  if (_industry_sound_ctr == 75) {
1197  if (_settings_client.sound.ambient) SndPlayTileFx(SND_37_BALLOON_SQUEAK, _industry_sound_tile);
1198  } else if (_industry_sound_ctr == 160) {
1199  _industry_sound_ctr = 0;
1200  if (_settings_client.sound.ambient) SndPlayTileFx(SND_36_CARTOON_CRASH, _industry_sound_tile);
1201  }
1202  }
1203 
1204  if (_game_mode == GM_EDITOR) return;
1205 
1206  for (Industry *i : Industry::Iterate()) {
1207  ProduceIndustryGoods(i);
1208  }
1209 }
1210 
1217 {
1218  return CommandCost();
1219 }
1220 
1227 {
1228  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
1229  if (GetTileZ(tile) < HighestSnowLine() + 2) {
1230  return_cmd_error(STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED);
1231  }
1232  }
1233  return CommandCost();
1234 }
1235 
1243 static bool CheckScaledDistanceFromEdge(TileIndex tile, uint maxdist)
1244 {
1245  uint maxdist_x = maxdist;
1246  uint maxdist_y = maxdist;
1247 
1248  if (MapSizeX() > 256) maxdist_x *= MapSizeX() / 256;
1249  if (MapSizeY() > 256) maxdist_y *= MapSizeY() / 256;
1250 
1251  if (DistanceFromEdgeDir(tile, DIAGDIR_NE) < maxdist_x) return true;
1252  if (DistanceFromEdgeDir(tile, DIAGDIR_NW) < maxdist_y) return true;
1253  if (DistanceFromEdgeDir(tile, DIAGDIR_SW) < maxdist_x) return true;
1254  if (DistanceFromEdgeDir(tile, DIAGDIR_SE) < maxdist_y) return true;
1255 
1256  return false;
1257 }
1258 
1265 {
1266  if (_game_mode == GM_EDITOR) return CommandCost();
1267 
1269 
1270  return_cmd_error(STR_ERROR_CAN_ONLY_BE_POSITIONED);
1271 }
1272 
1273 extern bool _ignore_restrictions;
1274 
1281 {
1282  if (_game_mode == GM_EDITOR && _ignore_restrictions) return CommandCost();
1283 
1284  if (TileHeight(tile) == 0 &&
1286 
1287  return_cmd_error(STR_ERROR_CAN_ONLY_BE_POSITIONED);
1288 }
1289 
1296 {
1297  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
1298  if (GetTileZ(tile) + 2 >= HighestSnowLine()) {
1299  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1300  }
1301  }
1302  return CommandCost();
1303 }
1304 
1311 {
1312  if (GetTropicZone(tile) == TROPICZONE_DESERT) {
1313  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1314  }
1315  return CommandCost();
1316 }
1317 
1324 {
1325  if (GetTropicZone(tile) != TROPICZONE_DESERT) {
1326  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT);
1327  }
1328  return CommandCost();
1329 }
1330 
1337 {
1338  if (GetTropicZone(tile) != TROPICZONE_RAINFOREST) {
1339  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST);
1340  }
1341  return CommandCost();
1342 }
1343 
1350 {
1351  if (GetTileZ(tile) > 4) {
1352  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_LOW_AREAS);
1353  }
1354  return CommandCost();
1355 }
1356 
1363 
1375 };
1376 
1388 {
1389  *t = ClosestTownFromTile(tile, UINT_MAX);
1390 
1392 
1393  for (const Industry *i : Industry::Iterate()) {
1394  if (i->type == (byte)type && i->town == *t) {
1395  *t = nullptr;
1396  return_cmd_error(STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN);
1397  }
1398  }
1399 
1400  return CommandCost();
1401 }
1402 
1403 bool IsSlopeRefused(Slope current, Slope refused)
1404 {
1405  if (IsSteepSlope(current)) return true;
1406  if (current != SLOPE_FLAT) {
1407  if (IsSteepSlope(refused)) return true;
1408 
1409  Slope t = ComplementSlope(current);
1410 
1411  if ((refused & SLOPE_W) && (t & SLOPE_NW)) return true;
1412  if ((refused & SLOPE_S) && (t & SLOPE_NE)) return true;
1413  if ((refused & SLOPE_E) && (t & SLOPE_SW)) return true;
1414  if ((refused & SLOPE_N) && (t & SLOPE_SE)) return true;
1415  }
1416 
1417  return false;
1418 }
1419 
1432 static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileLayout &layout, size_t layout_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool *custom_shape_check = nullptr)
1433 {
1434  bool refused_slope = false;
1435  bool custom_shape = false;
1436 
1437  for (const IndustryTileLayoutTile &it : layout) {
1438  IndustryGfx gfx = GetTranslatedIndustryTileID(it.gfx);
1439  TileIndex cur_tile = TileAddWrap(tile, it.ti.x, it.ti.y);
1440 
1441  if (!IsValidTile(cur_tile)) {
1442  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1443  }
1444 
1445  if (gfx == GFX_WATERTILE_SPECIALCHECK) {
1446  if (!IsWaterTile(cur_tile) ||
1447  !IsTileFlat(cur_tile)) {
1448  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1449  }
1450  } else {
1451  CommandCost ret = EnsureNoVehicleOnGround(cur_tile);
1452  if (ret.Failed()) return ret;
1453  if (IsBridgeAbove(cur_tile)) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1454 
1455  const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
1456 
1457  IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
1458 
1459  /* Perform land/water check if not disabled */
1460  if (!HasBit(its->slopes_refused, 5) && ((HasTileWaterClass(cur_tile) && IsTileOnWater(cur_tile)) == !(ind_behav & INDUSTRYBEH_BUILT_ONWATER))) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1461 
1463  custom_shape = true;
1464  CommandCost ret = PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, layout_index, initial_random_bits, founder, creation_type);
1465  if (ret.Failed()) return ret;
1466  } else {
1467  Slope tileh = GetTileSlope(cur_tile);
1468  refused_slope |= IsSlopeRefused(tileh, its->slopes_refused);
1469  }
1470 
1471  if ((ind_behav & (INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE)) || // Tile must be a house
1472  ((ind_behav & INDUSTRYBEH_ONLY_NEARTOWN) && IsTileType(cur_tile, MP_HOUSE))) { // Tile is allowed to be a house (and it is a house)
1473  if (!IsTileType(cur_tile, MP_HOUSE)) {
1474  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS);
1475  }
1476 
1477  /* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */
1478  Backup<CompanyID> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
1479  CommandCost ret = DoCommand(cur_tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR);
1480  cur_company.Restore();
1481 
1482  if (ret.Failed()) return ret;
1483  } else {
1484  /* Clear the tiles, but do not affect town ratings */
1486 
1487  if (ret.Failed()) return ret;
1488  }
1489  }
1490  }
1491 
1492  if (custom_shape_check != nullptr) *custom_shape_check = custom_shape;
1493 
1494  /* It is almost impossible to have a fully flat land in TG, so what we
1495  * do is that we check if we can make the land flat later on. See
1496  * CheckIfCanLevelIndustryPlatform(). */
1497  if (!refused_slope || (_settings_game.game_creation.land_generator == LG_TERRAGENESIS && _generating_world && !custom_shape && !_ignore_restrictions)) {
1498  return CommandCost();
1499  }
1500  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1501 }
1502 
1511 {
1512  if ((GetIndustrySpec(type)->behaviour & INDUSTRYBEH_TOWN1200_MORE) && t->cache.population < 1200) {
1513  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200);
1514  }
1515 
1516  if ((GetIndustrySpec(type)->behaviour & INDUSTRYBEH_ONLY_NEARTOWN) && DistanceMax(t->xy, tile) > 9) {
1517  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_NEAR_TOWN_CENTER);
1518  }
1519 
1520  return CommandCost();
1521 }
1522 
1523 static bool CheckCanTerraformSurroundingTiles(TileIndex tile, uint height, int internal)
1524 {
1525  /* Check if we don't leave the map */
1526  if (TileX(tile) == 0 || TileY(tile) == 0 || GetTileType(tile) == MP_VOID) return false;
1527 
1528  TileArea ta(tile - TileDiffXY(1, 1), 2, 2);
1529  TILE_AREA_LOOP(tile_walk, ta) {
1530  uint curh = TileHeight(tile_walk);
1531  /* Is the tile clear? */
1532  if ((GetTileType(tile_walk) != MP_CLEAR) && (GetTileType(tile_walk) != MP_TREES)) return false;
1533 
1534  /* Don't allow too big of a change if this is the sub-tile check */
1535  if (internal != 0 && Delta(curh, height) > 1) return false;
1536 
1537  /* Different height, so the surrounding tiles of this tile
1538  * has to be correct too (in level, or almost in level)
1539  * else you get a chain-reaction of terraforming. */
1540  if (internal == 0 && curh != height) {
1541  if (TileX(tile_walk) == 0 || TileY(tile_walk) == 0 || !CheckCanTerraformSurroundingTiles(tile_walk + TileDiffXY(-1, -1), height, internal + 1)) {
1542  return false;
1543  }
1544  }
1545  }
1546 
1547  return true;
1548 }
1549 
1555 {
1556  int max_x = 0;
1557  int max_y = 0;
1558 
1559  /* Finds dimensions of largest variant of this industry */
1560  for (const IndustryTileLayoutTile &it : layout) {
1561  if (it.gfx == GFX_WATERTILE_SPECIALCHECK) continue; // watercheck tiles don't count for footprint size
1562  if (it.ti.x > max_x) max_x = it.ti.x;
1563  if (it.ti.y > max_y) max_y = it.ti.y;
1564  }
1565 
1566  /* Remember level height */
1567  uint h = TileHeight(tile);
1568 
1569  if (TileX(tile) <= _settings_game.construction.industry_platform + 1U || TileY(tile) <= _settings_game.construction.industry_platform + 1U) return false;
1570  /* Check that all tiles in area and surrounding are clear
1571  * this determines that there are no obstructing items */
1572 
1573  /* TileArea::Expand is not used here as we need to abort
1574  * instead of clamping if the bounds cannot expanded. */
1577 
1578  if (TileX(ta.tile) + ta.w >= MapMaxX() || TileY(ta.tile) + ta.h >= MapMaxY()) return false;
1579 
1580  /* _current_company is OWNER_NONE for randomly generated industries and in editor, or the company who funded or prospected the industry.
1581  * Perform terraforming as OWNER_TOWN to disable autoslope and town ratings. */
1582  Backup<CompanyID> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
1583 
1584  TILE_AREA_LOOP(tile_walk, ta) {
1585  uint curh = TileHeight(tile_walk);
1586  if (curh != h) {
1587  /* This tile needs terraforming. Check if we can do that without
1588  * damaging the surroundings too much. */
1589  if (!CheckCanTerraformSurroundingTiles(tile_walk, h, 0)) {
1590  cur_company.Restore();
1591  return false;
1592  }
1593  /* This is not 100% correct check, but the best we can do without modifying the map.
1594  * What is missing, is if the difference in height is more than 1.. */
1595  if (DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND).Failed()) {
1596  cur_company.Restore();
1597  return false;
1598  }
1599  }
1600  }
1601 
1602  if (flags & DC_EXEC) {
1603  /* Terraform the land under the industry */
1604  TILE_AREA_LOOP(tile_walk, ta) {
1605  uint curh = TileHeight(tile_walk);
1606  while (curh != h) {
1607  /* We give the terraforming for free here, because we can't calculate
1608  * exact cost in the test-round, and as we all know, that will cause
1609  * a nice assert if they don't match ;) */
1610  DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND);
1611  curh += (curh > h) ? -1 : 1;
1612  }
1613  }
1614  }
1615 
1616  cur_company.Restore();
1617  return true;
1618 }
1619 
1620 
1628 {
1629  const IndustrySpec *indspec = GetIndustrySpec(type);
1630 
1631  /* On a large map with many industries, it may be faster to check an area. */
1632  static const int dmax = 14;
1633  if (Industry::GetNumItems() > (size_t) (dmax * dmax * 2)) {
1634  const Industry* i = nullptr;
1635  TileArea tile_area = TileArea(tile, 1, 1).Expand(dmax);
1636  TILE_AREA_LOOP(atile, tile_area) {
1637  if (GetTileType(atile) == MP_INDUSTRY) {
1638  const Industry *i2 = Industry::GetByTile(atile);
1639  if (i == i2) continue;
1640  i = i2;
1641  if (DistanceMax(tile, i->location.tile) > (uint)dmax) continue;
1642  if (i->type == indspec->conflicting[0] ||
1643  i->type == indspec->conflicting[1] ||
1644  i->type == indspec->conflicting[2]) {
1645  return_cmd_error(STR_ERROR_INDUSTRY_TOO_CLOSE);
1646  }
1647  }
1648  }
1649  return CommandCost();
1650  }
1651 
1652  for (const Industry *i : Industry::Iterate()) {
1653  /* Within 14 tiles from another industry is considered close */
1654  if (DistanceMax(tile, i->location.tile) > 14) continue;
1655 
1656  /* check if there are any conflicting industry types around */
1657  if (i->type == indspec->conflicting[0] ||
1658  i->type == indspec->conflicting[1] ||
1659  i->type == indspec->conflicting[2]) {
1660  return_cmd_error(STR_ERROR_INDUSTRY_TOO_CLOSE);
1661  }
1662  }
1663  return CommandCost();
1664 }
1665 
1670 static void AdvertiseIndustryOpening(const Industry *ind)
1671 {
1672  const IndustrySpec *ind_spc = GetIndustrySpec(ind->type);
1673  SetDParam(0, ind_spc->name);
1674  if (ind_spc->new_industry_text > STR_LAST_STRINGID) {
1675  SetDParam(1, STR_TOWN_NAME);
1676  SetDParam(2, ind->town->index);
1677  } else {
1678  SetDParam(1, ind->town->index);
1679  }
1680  AddIndustryNewsItem(ind_spc->new_industry_text, NT_INDUSTRY_OPEN, ind->index);
1681  AI::BroadcastNewEvent(new ScriptEventIndustryOpen(ind->index));
1682  Game::NewEvent(new ScriptEventIndustryOpen(ind->index));
1683 }
1684 
1691 {
1693  /* Industry has a neutral station. Use it and ignore any other nearby stations. */
1694  ind->stations_near.insert(ind->neutral_station);
1695  ind->neutral_station->industries_near.clear();
1696  ind->neutral_station->industries_near.insert(ind);
1697  return;
1698  }
1699 
1700  /* Get our list of nearby stations. */
1701  FindStationsAroundTiles(ind->location, &ind->stations_near, false);
1702 
1703  /* Test if industry can accept cargo */
1704  uint cargo_index;
1705  for (cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
1706  if (ind->accepts_cargo[cargo_index] != CT_INVALID) break;
1707  }
1708  if (cargo_index >= lengthof(ind->accepts_cargo)) return;
1709 
1710  /* Cargo is accepted, add industry to nearby stations nearby industry list. */
1711  for (Station *st : ind->stations_near) {
1712  st->industries_near.insert(ind);
1713  }
1714 }
1715 
1727 static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, const IndustryTileLayout &layout, size_t layout_index, Town *t, Owner founder, uint16 initial_random_bits)
1728 {
1729  const IndustrySpec *indspec = GetIndustrySpec(type);
1730 
1731  i->location = TileArea(tile, 1, 1);
1732  i->type = type;
1734 
1735  MemCpyT(i->produced_cargo, indspec->produced_cargo, lengthof(i->produced_cargo));
1736  MemCpyT(i->production_rate, indspec->production_rate, lengthof(i->production_rate));
1738 
1746 
1747  /* don't use smooth economy for industries using production related callbacks */
1748  if (indspec->UsesSmoothEconomy()) {
1749  for (size_t ci = 0; ci < lengthof(i->production_rate); ci++) {
1750  i->production_rate[ci] = min((RandomRange(256) + 128) * i->production_rate[ci] >> 8, 255);
1751  }
1752  }
1753 
1754  i->town = t;
1755  i->owner = OWNER_NONE;
1756 
1757  uint16 r = Random();
1758  i->random_colour = GB(r, 0, 4);
1759  i->counter = GB(r, 4, 12);
1760  i->random = initial_random_bits;
1761  i->was_cargo_delivered = false;
1763  i->founder = founder;
1764 
1765  i->construction_date = _date;
1766  i->construction_type = (_game_mode == GM_EDITOR) ? ICT_SCENARIO_EDITOR :
1768 
1769  /* Adding 1 here makes it conform to specs of var44 of varaction2 for industries
1770  * 0 = created prior of newindustries
1771  * else, chosen layout + 1 */
1772  i->selected_layout = (byte)(layout_index + 1);
1773 
1775 
1776  /* Call callbacks after the regular fields got initialised. */
1777 
1779  uint16 res = GetIndustryCallback(CBID_INDUSTRY_PROD_CHANGE_BUILD, 0, Random(), i, type, INVALID_TILE);
1780  if (res != CALLBACK_FAILED) {
1781  if (res < PRODLEVEL_MINIMUM || res > PRODLEVEL_MAXIMUM) {
1783  } else {
1784  i->prod_level = res;
1786  }
1787  }
1788  }
1789 
1790  if (_generating_world) {
1793  for (size_t ci = 0; ci < lengthof(i->last_month_production); ci++) {
1794  i->last_month_production[ci] = i->produced_cargo_waiting[ci] * 8;
1795  i->produced_cargo_waiting[ci] = 0;
1796  }
1797  }
1798 
1799  for (size_t ci = 0; ci < lengthof(i->last_month_production); ci++) {
1800  i->last_month_production[ci] += i->production_rate[ci] * 8;
1801  }
1802  }
1803 
1804  if (HasBit(indspec->callback_mask, CBM_IND_DECIDE_COLOUR)) {
1805  uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE);
1806  if (res != CALLBACK_FAILED) {
1807  if (GB(res, 4, 11) != 0) ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_DECIDE_COLOUR, res);
1808  i->random_colour = GB(res, 0, 4);
1809  }
1810  }
1811 
1813  /* Clear all input cargo types */
1814  for (uint j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID;
1815  /* Query actual types */
1816  uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? lengthof(i->accepts_cargo) : 3;
1817  for (uint j = 0; j < maxcargoes; j++) {
1819  if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
1820  if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) {
1822  break;
1823  }
1824  CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
1825  if (std::find(indspec->accepts_cargo, endof(indspec->accepts_cargo), cargo) == endof(indspec->accepts_cargo)) {
1826  /* Cargo not in spec, error in NewGRF */
1828  break;
1829  }
1830  if (std::find(i->accepts_cargo, i->accepts_cargo + j, cargo) != i->accepts_cargo + j) {
1831  /* Duplicate cargo */
1833  break;
1834  }
1835  i->accepts_cargo[j] = cargo;
1836  }
1837  }
1838 
1840  /* Clear all output cargo types */
1841  for (uint j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID;
1842  /* Query actual types */
1843  uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? lengthof(i->produced_cargo) : 2;
1844  for (uint j = 0; j < maxcargoes; j++) {
1846  if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
1847  if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) {
1849  break;
1850  }
1851  CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
1852  if (std::find(indspec->produced_cargo, endof(indspec->produced_cargo), cargo) == endof(indspec->produced_cargo)) {
1853  /* Cargo not in spec, error in NewGRF */
1855  break;
1856  }
1857  if (std::find(i->produced_cargo, i->produced_cargo + j, cargo) != i->produced_cargo + j) {
1858  /* Duplicate cargo */
1860  break;
1861  }
1862  i->produced_cargo[j] = cargo;
1863  }
1864  }
1865 
1866  /* Plant the tiles */
1867 
1868  for (const IndustryTileLayoutTile &it : layout) {
1869  TileIndex cur_tile = tile + ToTileIndexDiff(it.ti);
1870 
1871  if (it.gfx != GFX_WATERTILE_SPECIALCHECK) {
1872  i->location.Add(cur_tile);
1873 
1874  WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID);
1875 
1877 
1878  MakeIndustry(cur_tile, i->index, it.gfx, Random(), wc);
1879 
1880  if (_generating_world) {
1881  SetIndustryConstructionCounter(cur_tile, 3);
1882  SetIndustryConstructionStage(cur_tile, 2);
1883  }
1884 
1885  /* it->gfx is stored in the map. But the translated ID cur_gfx is the interesting one */
1886  IndustryGfx cur_gfx = GetTranslatedIndustryTileID(it.gfx);
1887  const IndustryTileSpec *its = GetIndustryTileSpec(cur_gfx);
1889  }
1890  }
1891 
1893  for (uint j = 0; j != 50; j++) PlantRandomFarmField(i);
1894  }
1896 
1898 }
1899 
1916 static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCommandFlag flags, const IndustrySpec *indspec, size_t layout_index, uint32 random_var8f, uint16 random_initial_bits, Owner founder, IndustryAvailabilityCallType creation_type, Industry **ip)
1917 {
1918  assert(layout_index < indspec->layouts.size());
1919  const IndustryTileLayout &layout = indspec->layouts[layout_index];
1920  bool custom_shape_check = false;
1921 
1922  *ip = nullptr;
1923 
1924  std::vector<ClearedObjectArea> object_areas(_cleared_object_areas);
1925  CommandCost ret = CheckIfIndustryTilesAreFree(tile, layout, layout_index, type, random_initial_bits, founder, creation_type, &custom_shape_check);
1926  _cleared_object_areas = object_areas;
1927  if (ret.Failed()) return ret;
1928 
1929  if (HasBit(GetIndustrySpec(type)->callback_mask, CBM_IND_LOCATION)) {
1930  ret = CheckIfCallBackAllowsCreation(tile, type, layout_index, random_var8f, random_initial_bits, founder, creation_type);
1931  } else {
1932  ret = _check_new_industry_procs[indspec->check_proc](tile);
1933  }
1934  if (ret.Failed()) return ret;
1935 
1937  !_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER, layout, type)) {
1938  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1939  }
1940 
1941  ret = CheckIfFarEnoughFromConflictingIndustry(tile, type);
1942  if (ret.Failed()) return ret;
1943 
1944  Town *t = nullptr;
1945  ret = FindTownForIndustry(tile, type, &t);
1946  if (ret.Failed()) return ret;
1947  assert(t != nullptr);
1948 
1949  ret = CheckIfIndustryIsAllowed(tile, type, t);
1950  if (ret.Failed()) return ret;
1951 
1952  if (!Industry::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_INDUSTRIES);
1953 
1954  if (flags & DC_EXEC) {
1955  *ip = new Industry(tile);
1956  if (!custom_shape_check) CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER | DC_EXEC, layout, type);
1957  DoCreateNewIndustry(*ip, tile, type, layout, layout_index, t, founder, random_initial_bits);
1958  }
1959 
1960  return CommandCost();
1961 }
1962 
1975 CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1976 {
1977  IndustryType it = GB(p1, 0, 8);
1978  if (it >= NUM_INDUSTRYTYPES) return CMD_ERROR;
1979 
1980  const IndustrySpec *indspec = GetIndustrySpec(it);
1981 
1982  /* Check if the to-be built/founded industry is available for this climate. */
1983  if (!indspec->enabled || indspec->layouts.empty()) return CMD_ERROR;
1984 
1985  /* If the setting for raw-material industries is not on, you cannot build raw-material industries.
1986  * Raw material industries are industries that do not accept cargo (at least for now) */
1987  if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 0 && indspec->IsRawIndustry()) {
1988  return CMD_ERROR;
1989  }
1990 
1991  if (_game_mode != GM_EDITOR && GetIndustryProbabilityCallback(it, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, 1) == 0) {
1992  return CMD_ERROR;
1993  }
1994 
1995  Randomizer randomizer;
1996  randomizer.SetSeed(p2);
1997  uint16 random_initial_bits = GB(p2, 0, 16);
1998  uint32 random_var8f = randomizer.Next();
1999  size_t num_layouts = indspec->layouts.size();
2000  CommandCost ret = CommandCost(STR_ERROR_SITE_UNSUITABLE);
2001  const bool deity_prospect = _current_company == OWNER_DEITY && !HasBit(p1, 16);
2002 
2003  Industry *ind = nullptr;
2004  if (deity_prospect || (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry())) {
2005  if (flags & DC_EXEC) {
2006  /* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */
2007  Backup<CompanyID> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
2008  /* Prospecting has a chance to fail, however we cannot guarantee that something can
2009  * be built on the map, so the chance gets lower when the map is fuller, but there
2010  * is nothing we can really do about that. */
2011  if (deity_prospect || Random() <= indspec->prospecting_chance) {
2012  for (int i = 0; i < 5000; i++) {
2013  /* We should not have more than one Random() in a function call
2014  * because parameter evaluation order is not guaranteed in the c++ standard
2015  */
2016  tile = RandomTile();
2017  /* Start with a random layout */
2018  size_t layout = RandomRange((uint32)num_layouts);
2019  /* Check now each layout, starting with the random one */
2020  for (size_t j = 0; j < num_layouts; j++) {
2021  layout = (layout + 1) % num_layouts;
2022  ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, cur_company.GetOriginalValue(), _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_PROSPECTCREATION, &ind);
2023  if (ret.Succeeded()) break;
2024  }
2025  if (ret.Succeeded()) break;
2026  }
2027  }
2028  cur_company.Restore();
2029  }
2030  } else {
2031  size_t layout = GB(p1, 8, 8);
2032  if (layout >= num_layouts) return CMD_ERROR;
2033 
2034  /* Check subsequently each layout, starting with the given layout in p1 */
2035  for (size_t i = 0; i < num_layouts; i++) {
2036  layout = (layout + 1) % num_layouts;
2037  ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, _current_company, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, &ind);
2038  if (ret.Succeeded()) break;
2039  }
2040 
2041  /* If it still failed, there's no suitable layout to build here, return the error */
2042  if (ret.Failed()) return ret;
2043  }
2044 
2045  if ((flags & DC_EXEC) && ind != nullptr && _game_mode != GM_EDITOR) {
2047  }
2048 
2049  return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
2050 }
2051 
2052 
2060 static Industry *CreateNewIndustry(TileIndex tile, IndustryType type, IndustryAvailabilityCallType creation_type)
2061 {
2062  const IndustrySpec *indspec = GetIndustrySpec(type);
2063 
2064  uint32 seed = Random();
2065  uint32 seed2 = Random();
2066  Industry *i = nullptr;
2067  size_t layout_index = RandomRange((uint32)indspec->layouts.size());
2068  CommandCost ret = CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, layout_index, seed, GB(seed2, 0, 16), OWNER_NONE, creation_type, &i);
2069  assert(i != nullptr || ret.Failed());
2070  return i;
2071 }
2072 
2079 static uint32 GetScaledIndustryGenerationProbability(IndustryType it, bool *force_at_least_one)
2080 {
2081  const IndustrySpec *ind_spc = GetIndustrySpec(it);
2082  uint32 chance = ind_spc->appear_creation[_settings_game.game_creation.landscape] * 16; // * 16 to increase precision
2083  if (!ind_spc->enabled || ind_spc->layouts.empty() ||
2084  (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) ||
2085  (chance = GetIndustryProbabilityCallback(it, IACT_MAPGENERATION, chance)) == 0) {
2086  *force_at_least_one = false;
2087  return 0;
2088  } else {
2089  /* We want industries appearing at coast to appear less often on bigger maps, as length of coast increases slower than map area.
2090  * For simplicity we scale in both cases, though scaling the probabilities of all industries has no effect. */
2091  chance = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? ScaleByMapSize1D(chance) : ScaleByMapSize(chance);
2092 
2093  *force_at_least_one = (chance > 0) && !(ind_spc->behaviour & INDUSTRYBEH_NOBUILT_MAPCREATION) && (_game_mode != GM_EDITOR);
2094  return chance;
2095  }
2096 }
2097 
2104 static uint16 GetIndustryGamePlayProbability(IndustryType it, byte *min_number)
2105 {
2107  *min_number = 0;
2108  return 0;
2109  }
2110 
2111  const IndustrySpec *ind_spc = GetIndustrySpec(it);
2112  byte chance = ind_spc->appear_ingame[_settings_game.game_creation.landscape];
2113  if (!ind_spc->enabled || ind_spc->layouts.empty() ||
2114  ((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && _cur_year > 1950) ||
2115  ((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && _cur_year < 1960) ||
2116  (chance = GetIndustryProbabilityCallback(it, IACT_RANDOMCREATION, chance)) == 0) {
2117  *min_number = 0;
2118  return 0;
2119  }
2120  *min_number = (ind_spc->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) ? 1 : 0;
2121  return chance;
2122 }
2123 
2129 {
2130  /* Number of industries on a 256x256 map. */
2131  static const uint16 numof_industry_table[] = {
2132  0, // none
2133  0, // minimal
2134  10, // very low
2135  25, // low
2136  55, // normal
2137  80, // high
2138  };
2139 
2140  assert(lengthof(numof_industry_table) == ID_END);
2141  uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.industry_density : (uint)ID_VERY_LOW;
2142  return min(IndustryPool::MAX_SIZE, ScaleByMapSize(numof_industry_table[difficulty]));
2143 }
2144 
2153 static Industry *PlaceIndustry(IndustryType type, IndustryAvailabilityCallType creation_type, bool try_hard)
2154 {
2155  uint tries = try_hard ? 10000u : 2000u;
2156  for (; tries > 0; tries--) {
2157  Industry *ind = CreateNewIndustry(RandomTile(), type, creation_type);
2158  if (ind != nullptr) return ind;
2159  }
2160  return nullptr;
2161 }
2162 
2168 static void PlaceInitialIndustry(IndustryType type, bool try_hard)
2169 {
2170  Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2171 
2173  PlaceIndustry(type, IACT_MAPGENERATION, try_hard);
2174 
2175  cur_company.Restore();
2176 }
2177 
2183 {
2184  int total = 0;
2185  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) total += Industry::GetIndustryTypeCount(it);
2186  return total;
2187 }
2188 
2189 
2192 {
2193  this->probability = 0;
2194  this->min_number = 0;
2195  this->target_count = 0;
2196  this->max_wait = 1;
2197  this->wait_count = 0;
2198 }
2199 
2202 {
2203  this->wanted_inds = GetCurrentTotalNumberOfIndustries() << 16;
2204 
2205  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2206  this->builddata[it].Reset();
2207  }
2208 }
2209 
2212 {
2213  static const int NEWINDS_PER_MONTH = 0x38000 / (10 * 12); // lower 16 bits is a float fraction, 3.5 industries per decade, divided by 10 * 12 months.
2214  if (_settings_game.difficulty.industry_density == ID_FUND_ONLY) return; // 'no industries' setting.
2215 
2216  /* To prevent running out of unused industries for the player to connect,
2217  * add a fraction of new industries each month, but only if the manager can keep up. */
2218  uint max_behind = 1 + min(99u, ScaleByMapSize(3)); // At most 2 industries for small maps, and 100 at the biggest map (about 6 months industry build attempts).
2219  if (GetCurrentTotalNumberOfIndustries() + max_behind >= (this->wanted_inds >> 16)) {
2220  this->wanted_inds += ScaleByMapSize(NEWINDS_PER_MONTH);
2221  }
2222 }
2223 
2229 {
2230  if (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) return; // No industries in the game.
2231 
2232  uint32 industry_probs[NUM_INDUSTRYTYPES];
2233  bool force_at_least_one[NUM_INDUSTRYTYPES];
2234  uint32 total_prob = 0;
2235  uint num_forced = 0;
2236 
2237  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2238  industry_probs[it] = GetScaledIndustryGenerationProbability(it, force_at_least_one + it);
2239  total_prob += industry_probs[it];
2240  if (force_at_least_one[it]) num_forced++;
2241  }
2242 
2243  uint total_amount = GetNumberOfIndustries();
2244  if (total_prob == 0 || total_amount < num_forced) {
2245  /* Only place the forced ones */
2246  total_amount = num_forced;
2247  }
2248 
2250 
2251  /* Try to build one industry per type independent of any probabilities */
2252  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2253  if (force_at_least_one[it]) {
2254  assert(total_amount > 0);
2255  total_amount--;
2256  PlaceInitialIndustry(it, true);
2257  }
2258  }
2259 
2260  /* Add the remaining industries according to their probabilities */
2261  for (uint i = 0; i < total_amount; i++) {
2262  uint32 r = RandomRange(total_prob);
2263  IndustryType it = 0;
2264  while (r >= industry_probs[it]) {
2265  r -= industry_probs[it];
2266  it++;
2267  assert(it < NUM_INDUSTRYTYPES);
2268  }
2269  assert(industry_probs[it] > 0);
2270  PlaceInitialIndustry(it, false);
2271  }
2272  _industry_builder.Reset();
2273 }
2274 
2280 {
2281  for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
2282  if (i->produced_cargo[j] != CT_INVALID) {
2283  byte pct = 0;
2284  if (i->this_month_production[j] != 0) {
2286  pct = min(i->this_month_transported[j] * 256 / i->this_month_production[j], 255);
2287  }
2288  i->last_month_pct_transported[j] = pct;
2289 
2291  i->this_month_production[j] = 0;
2292 
2294  i->this_month_transported[j] = 0;
2295  }
2296  }
2297 }
2298 
2304 {
2305  const IndustrySpec *indspec = GetIndustrySpec(this->type);
2306  assert(!indspec->UsesSmoothEconomy());
2307 
2308  /* Rates are rounded up, so e.g. oilrig always produces some passengers */
2309  for (size_t i = 0; i < lengthof(this->production_rate); i++) {
2310  this->production_rate[i] = min(CeilDiv(indspec->production_rate[i] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF);
2311  }
2312 }
2313 
2314 
2321 {
2322  byte min_number;
2323  uint32 probability = GetIndustryGamePlayProbability(it, &min_number);
2324  bool changed = min_number != this->min_number || probability != this->probability;
2325  this->min_number = min_number;
2326  this->probability = probability;
2327  return changed;
2328 }
2329 
2332 {
2333  bool changed = false;
2334  uint num_planned = 0; // Number of industries planned in the industry build data.
2335  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2336  changed |= this->builddata[it].GetIndustryTypeData(it);
2337  num_planned += this->builddata[it].target_count;
2338  }
2339  uint total_amount = this->wanted_inds >> 16; // Desired total number of industries.
2340  changed |= num_planned != total_amount;
2341  if (!changed) return; // All industries are still the same, no need to re-randomize.
2342 
2343  /* Initialize the target counts. */
2344  uint force_build = 0; // Number of industries that should always be available.
2345  uint32 total_prob = 0; // Sum of probabilities.
2346  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2347  IndustryTypeBuildData *ibd = this->builddata + it;
2348  force_build += ibd->min_number;
2349  ibd->target_count = ibd->min_number;
2350  total_prob += ibd->probability;
2351  }
2352 
2353  if (total_prob == 0) return; // No buildable industries.
2354 
2355  /* Subtract forced industries from the number of industries available for construction. */
2356  total_amount = (total_amount <= force_build) ? 0 : total_amount - force_build;
2357 
2358  /* Assign number of industries that should be aimed for, by using the probability as a weight. */
2359  while (total_amount > 0) {
2360  uint32 r = RandomRange(total_prob);
2361  IndustryType it = 0;
2362  while (r >= this->builddata[it].probability) {
2363  r -= this->builddata[it].probability;
2364  it++;
2365  assert(it < NUM_INDUSTRYTYPES);
2366  }
2367  assert(this->builddata[it].probability > 0);
2368  this->builddata[it].target_count++;
2369  total_amount--;
2370  }
2371 }
2372 
2377 {
2378  this->SetupTargetCount();
2379 
2380  int missing = 0; // Number of industries that need to be build.
2381  uint count = 0; // Number of industry types eligible for build.
2382  uint32 total_prob = 0; // Sum of probabilities.
2383  IndustryType forced_build = NUM_INDUSTRYTYPES; // Industry type that should be forcibly build.
2384  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2385  int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
2386  missing += difference;
2387  if (this->builddata[it].wait_count > 0) continue; // This type may not be built now.
2388  if (difference > 0) {
2389  if (Industry::GetIndustryTypeCount(it) == 0 && this->builddata[it].min_number > 0) {
2390  /* An industry that should exist at least once, is not available. Force it, trying the most needed one first. */
2391  if (forced_build == NUM_INDUSTRYTYPES ||
2392  difference > this->builddata[forced_build].target_count - Industry::GetIndustryTypeCount(forced_build)) {
2393  forced_build = it;
2394  }
2395  }
2396  total_prob += difference;
2397  count++;
2398  }
2399  }
2400 
2401  if (EconomyIsInRecession() || (forced_build == NUM_INDUSTRYTYPES && (missing <= 0 || total_prob == 0))) count = 0; // Skip creation of an industry.
2402 
2403  if (count >= 1) {
2404  /* If not forced, pick a weighted random industry to build.
2405  * For the case that count == 1, there is no need to draw a random number. */
2406  IndustryType it;
2407  if (forced_build != NUM_INDUSTRYTYPES) {
2408  it = forced_build;
2409  } else {
2410  /* Non-forced, select an industry type to build (weighted random). */
2411  uint32 r = 0; // Initialized to silence the compiler.
2412  if (count > 1) r = RandomRange(total_prob);
2413  for (it = 0; it < NUM_INDUSTRYTYPES; it++) {
2414  if (this->builddata[it].wait_count > 0) continue; // Type may not be built now.
2415  int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
2416  if (difference <= 0) continue; // Too many of this kind.
2417  if (count == 1) break;
2418  if (r < (uint)difference) break;
2419  r -= difference;
2420  }
2421  assert(it < NUM_INDUSTRYTYPES && this->builddata[it].target_count > Industry::GetIndustryTypeCount(it));
2422  }
2423 
2424  /* Try to create the industry. */
2425  const Industry *ind = PlaceIndustry(it, IACT_RANDOMCREATION, false);
2426  if (ind == nullptr) {
2427  this->builddata[it].wait_count = this->builddata[it].max_wait + 1; // Compensate for decrementing below.
2428  this->builddata[it].max_wait = min(1000, this->builddata[it].max_wait + 2);
2429  } else {
2431  this->builddata[it].max_wait = max(this->builddata[it].max_wait / 2, 1); // Reduce waiting time of the industry type.
2432  }
2433  }
2434 
2435  /* Decrement wait counters. */
2436  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2437  if (this->builddata[it].wait_count > 0) this->builddata[it].wait_count--;
2438  }
2439 }
2440 
2449 static bool CheckIndustryCloseDownProtection(IndustryType type)
2450 {
2451  const IndustrySpec *indspec = GetIndustrySpec(type);
2452 
2453  /* oil wells (or the industries with that flag set) are always allowed to closedown */
2454  if ((indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE) return false;
2455  return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) == 0 && Industry::GetIndustryTypeCount(type) <= 1;
2456 }
2457 
2467 static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accepts, bool *c_produces)
2468 {
2469  if (cargo == CT_INVALID) return;
2470 
2471  /* Check for acceptance of cargo */
2472  for (byte j = 0; j < lengthof(ind->accepts_cargo); j++) {
2473  if (cargo == ind->accepts_cargo[j] && !IndustryTemporarilyRefusesCargo(ind, cargo)) {
2474  *c_accepts = true;
2475  break;
2476  }
2477  }
2478 
2479  /* Check for produced cargo */
2480  for (byte j = 0; j < lengthof(ind->produced_cargo); j++) {
2481  if (cargo == ind->produced_cargo[j]) {
2482  *c_produces = true;
2483  break;
2484  }
2485  }
2486 }
2487 
2502 {
2503  if (ind->stations_near.size() == 0) return 0; // No stations found at all => nobody services
2504 
2505  int result = 0;
2506  for (const Vehicle *v : Vehicle::Iterate()) {
2507  /* Is it worthwhile to try this vehicle? */
2508  if (v->owner != _local_company && result != 0) continue;
2509 
2510  /* Check whether it accepts the right kind of cargo */
2511  bool c_accepts = false;
2512  bool c_produces = false;
2513  if (v->type == VEH_TRAIN && v->IsFrontEngine()) {
2514  for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
2515  CanCargoServiceIndustry(u->cargo_type, ind, &c_accepts, &c_produces);
2516  }
2517  } else if (v->type == VEH_ROAD || v->type == VEH_SHIP || v->type == VEH_AIRCRAFT) {
2518  CanCargoServiceIndustry(v->cargo_type, ind, &c_accepts, &c_produces);
2519  } else {
2520  continue;
2521  }
2522  if (!c_accepts && !c_produces) continue; // Wrong cargo
2523 
2524  /* Check orders of the vehicle.
2525  * We cannot check the first of shared orders only, since the first vehicle in such a chain
2526  * may have a different cargo type.
2527  */
2528  const Order *o;
2529  FOR_VEHICLE_ORDERS(v, o) {
2530  if (o->IsType(OT_GOTO_STATION) && !(o->GetUnloadType() & OUFB_TRANSFER)) {
2531  /* Vehicle visits a station to load or unload */
2532  Station *st = Station::Get(o->GetDestination());
2533  assert(st != nullptr);
2534 
2535  /* Same cargo produced by industry is dropped here => not serviced by vehicle v */
2536  if ((o->GetUnloadType() & OUFB_UNLOAD) && !c_accepts) break;
2537 
2538  if (ind->stations_near.find(st) != ind->stations_near.end()) {
2539  if (v->owner == _local_company) return 2; // Company services industry
2540  result = 1; // Competitor services industry
2541  }
2542  }
2543  }
2544  }
2545  return result;
2546 }
2547 
2556 {
2557  NewsType nt;
2558 
2559  switch (WhoCanServiceIndustry(ind)) {
2560  case 0: nt = NT_INDUSTRY_NOBODY; break;
2561  case 1: nt = NT_INDUSTRY_OTHER; break;
2562  case 2: nt = NT_INDUSTRY_COMPANY; break;
2563  default: NOT_REACHED();
2564  }
2565  SetDParam(2, abs(percent));
2566  SetDParam(0, CargoSpec::Get(type)->name);
2567  SetDParam(1, ind->index);
2568  AddIndustryNewsItem(
2569  percent >= 0 ? STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH : STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH,
2570  nt,
2571  ind->index
2572  );
2573 }
2574 
2575 static const uint PERCENT_TRANSPORTED_60 = 153;
2576 static const uint PERCENT_TRANSPORTED_80 = 204;
2577 
2583 static void ChangeIndustryProduction(Industry *i, bool monthly)
2584 {
2585  StringID str = STR_NULL;
2586  bool closeit = false;
2587  const IndustrySpec *indspec = GetIndustrySpec(i->type);
2588  bool standard = false;
2589  bool suppress_message = false;
2590  bool recalculate_multipliers = false;
2591  /* don't use smooth economy for industries using production related callbacks */
2592  bool smooth_economy = indspec->UsesSmoothEconomy();
2593  byte div = 0;
2594  byte mul = 0;
2595  int8 increment = 0;
2596 
2597  bool callback_enabled = HasBit(indspec->callback_mask, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE);
2598  if (callback_enabled) {
2600  if (res != CALLBACK_FAILED) { // failed callback means "do nothing"
2601  suppress_message = HasBit(res, 7);
2602  /* Get the custom message if any */
2603  if (HasBit(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16));
2604  res = GB(res, 0, 4);
2605  switch (res) {
2606  default: NOT_REACHED();
2607  case 0x0: break; // Do nothing, but show the custom message if any
2608  case 0x1: div = 1; break; // Halve industry production. If production reaches the quarter of the default, the industry is closed instead.
2609  case 0x2: mul = 1; break; // Double industry production if it hasn't reached eight times of the original yet.
2610  case 0x3: closeit = true; break; // The industry announces imminent closure, and is physically removed from the map next month.
2611  case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one.
2612  case 0x5: case 0x6: case 0x7: // Divide production by 4, 8, 16
2613  case 0x8: div = res - 0x3; break; // Divide production by 32
2614  case 0x9: case 0xA: case 0xB: // Multiply production by 4, 8, 16
2615  case 0xC: mul = res - 0x7; break; // Multiply production by 32
2616  case 0xD: // decrement production
2617  case 0xE: // increment production
2618  increment = res == 0x0D ? -1 : 1;
2619  break;
2620  case 0xF: // Set production to third byte of register 0x100
2622  recalculate_multipliers = true;
2623  break;
2624  }
2625  }
2626  } else {
2627  if (monthly != smooth_economy) return;
2628  if (indspec->life_type == INDUSTRYLIFE_BLACK_HOLE) return;
2629  }
2630 
2631  if (standard || (!callback_enabled && (indspec->life_type & (INDUSTRYLIFE_ORGANIC | INDUSTRYLIFE_EXTRACTIVE)) != 0)) {
2632  /* decrease or increase */
2633  bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE;
2634 
2635  if (smooth_economy) {
2636  closeit = true;
2637  for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
2638  if (i->produced_cargo[j] == CT_INVALID) continue;
2639  uint32 r = Random();
2640  int old_prod, new_prod, percent;
2641  /* If over 60% is transported, mult is 1, else mult is -1. */
2642  int mult = (i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_60) ? 1 : -1;
2643 
2644  new_prod = old_prod = i->production_rate[j];
2645 
2646  /* For industries with only_decrease flags (temperate terrain Oil Wells),
2647  * the multiplier will always be -1 so they will only decrease. */
2648  if (only_decrease) {
2649  mult = -1;
2650  /* For normal industries, if over 60% is transported, 33% chance for decrease.
2651  * Bonus for very high station ratings (over 80%): 16% chance for decrease. */
2652  } else if (Chance16I(1, ((i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_80) ? 6 : 3), r)) {
2653  mult *= -1;
2654  }
2655 
2656  /* 4.5% chance for 3-23% (or 1 unit for very low productions) production change,
2657  * determined by mult value. If mult = 1 prod. increases, else (-1) it decreases. */
2658  if (Chance16I(1, 22, r >> 16)) {
2659  new_prod += mult * (max(((RandomRange(50) + 10) * old_prod) >> 8, 1U));
2660  }
2661 
2662  /* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
2663  new_prod = Clamp(new_prod, 1, 255);
2664 
2665  if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1) {
2666  new_prod = Clamp(new_prod, 0, 16);
2667  }
2668 
2669  /* Do not stop closing the industry when it has the lowest possible production rate */
2670  if (new_prod == old_prod && old_prod > 1) {
2671  closeit = false;
2672  continue;
2673  }
2674 
2675  percent = (old_prod == 0) ? 100 : (new_prod * 100 / old_prod - 100);
2676  i->production_rate[j] = new_prod;
2677 
2678  /* Close the industry when it has the lowest possible production rate */
2679  if (new_prod > 1) closeit = false;
2680 
2681  if (abs(percent) >= 10) {
2683  }
2684  }
2685  } else {
2686  if (only_decrease || Chance16(1, 3)) {
2687  /* If more than 60% transported, 66% chance of increase, else 33% chance of increase */
2688  if (!only_decrease && (i->last_month_pct_transported[0] > PERCENT_TRANSPORTED_60) != Chance16(1, 3)) {
2689  mul = 1; // Increase production
2690  } else {
2691  div = 1; // Decrease production
2692  }
2693  }
2694  }
2695  }
2696 
2697  if (!callback_enabled && (indspec->life_type & INDUSTRYLIFE_PROCESSING)) {
2698  if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, smooth_economy ? 180 : 2)) {
2699  closeit = true;
2700  }
2701  }
2702 
2703  /* Increase if needed */
2704  while (mul-- != 0 && i->prod_level < PRODLEVEL_MAXIMUM) {
2706  recalculate_multipliers = true;
2707  if (str == STR_NULL) str = indspec->production_up_text;
2708  }
2709 
2710  /* Decrease if needed */
2711  while (div-- != 0 && !closeit) {
2712  if (i->prod_level == PRODLEVEL_MINIMUM) {
2713  closeit = true;
2714  } else {
2715  i->prod_level = max(i->prod_level / 2, (int)PRODLEVEL_MINIMUM); // typecast to int required to please MSVC
2716  recalculate_multipliers = true;
2717  if (str == STR_NULL) str = indspec->production_down_text;
2718  }
2719  }
2720 
2721  /* Increase or Decreasing the production level if needed */
2722  if (increment != 0) {
2723  if (increment < 0 && i->prod_level == PRODLEVEL_MINIMUM) {
2724  closeit = true;
2725  } else {
2727  recalculate_multipliers = true;
2728  }
2729  }
2730 
2731  /* Recalculate production_rate
2732  * For non-smooth economy these should always be synchronized with prod_level */
2733  if (recalculate_multipliers) i->RecomputeProductionMultipliers();
2734 
2735  /* Close if needed and allowed */
2736  if (closeit && !CheckIndustryCloseDownProtection(i->type)) {
2739  str = indspec->closure_text;
2740  }
2741 
2742  if (!suppress_message && str != STR_NULL) {
2743  NewsType nt;
2744  /* Compute news category */
2745  if (closeit) {
2746  nt = NT_INDUSTRY_CLOSE;
2747  AI::BroadcastNewEvent(new ScriptEventIndustryClose(i->index));
2748  Game::NewEvent(new ScriptEventIndustryClose(i->index));
2749  } else {
2750  switch (WhoCanServiceIndustry(i)) {
2751  case 0: nt = NT_INDUSTRY_NOBODY; break;
2752  case 1: nt = NT_INDUSTRY_OTHER; break;
2753  case 2: nt = NT_INDUSTRY_COMPANY; break;
2754  default: NOT_REACHED();
2755  }
2756  }
2757  /* Set parameters of news string */
2758  if (str > STR_LAST_STRINGID) {
2759  SetDParam(0, STR_TOWN_NAME);
2760  SetDParam(1, i->town->index);
2761  SetDParam(2, indspec->name);
2762  } else if (closeit) {
2763  SetDParam(0, STR_FORMAT_INDUSTRY_NAME);
2764  SetDParam(1, i->town->index);
2765  SetDParam(2, indspec->name);
2766  } else {
2767  SetDParam(0, i->index);
2768  }
2769  /* and report the news to the user */
2770  if (closeit) {
2771  AddTileNewsItem(str, nt, i->location.tile + TileDiffXY(1, 1));
2772  } else {
2773  AddIndustryNewsItem(str, nt, i->index);
2774  }
2775  }
2776 }
2777 
2786 {
2788 
2789  /* Bits 16-31 of industry_construction_counter contain the number of industries to change/create today,
2790  * the lower 16 bit are a fractional part that might accumulate over several days until it
2791  * is sufficient for an industry. */
2792  uint16 change_loop = _economy.industry_daily_change_counter >> 16;
2793 
2794  /* Reset the active part of the counter, just keeping the "fractional part" */
2795  _economy.industry_daily_change_counter &= 0xFFFF;
2796 
2797  if (change_loop == 0) {
2798  return; // Nothing to do? get out
2799  }
2800 
2801  Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2802 
2803  /* perform the required industry changes for the day */
2804 
2805  uint perc = 3; // Between 3% and 9% chance of creating a new industry.
2806  if ((_industry_builder.wanted_inds >> 16) > GetCurrentTotalNumberOfIndustries()) {
2807  perc = min(9u, perc + (_industry_builder.wanted_inds >> 16) - GetCurrentTotalNumberOfIndustries());
2808  }
2809  for (uint16 j = 0; j < change_loop; j++) {
2810  if (Chance16(perc, 100)) {
2811  _industry_builder.TryBuildNewIndustry();
2812  } else {
2814  if (i != nullptr) {
2815  ChangeIndustryProduction(i, false);
2817  }
2818  }
2819  }
2820 
2821  cur_company.Restore();
2822 
2823  /* production-change */
2825 }
2826 
2827 void IndustryMonthlyLoop()
2828 {
2829  Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2830 
2831  _industry_builder.MonthlyLoop();
2832 
2833  for (Industry *i : Industry::Iterate()) {
2835  if (i->prod_level == PRODLEVEL_CLOSURE) {
2836  delete i;
2837  } else {
2838  ChangeIndustryProduction(i, true);
2840  }
2841  }
2842 
2843  cur_company.Restore();
2844 
2845  /* production-change */
2847 }
2848 
2849 
2850 void InitializeIndustries()
2851 {
2853  _industry_sound_tile = 0;
2854 
2855  _industry_builder.Reset();
2856 }
2857 
2860 {
2861  int count = 0;
2862  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2863  if (Industry::GetIndustryTypeCount(it) > 0) continue; // Types of existing industries can be skipped.
2864 
2865  bool force_at_least_one;
2866  uint32 chance = GetScaledIndustryGenerationProbability(it, &force_at_least_one);
2867  if (chance == 0 || !force_at_least_one) continue; // Types that are not available can be skipped.
2868 
2869  const IndustrySpec *is = GetIndustrySpec(it);
2870  SetDParam(0, is->name);
2871  ShowErrorMessage(STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES, STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION, WL_WARNING);
2872 
2873  count++;
2874  if (count >= 3) break; // Don't swamp the user with errors.
2875  }
2876 }
2877 
2883 {
2884  return (this->life_type & (INDUSTRYLIFE_EXTRACTIVE | INDUSTRYLIFE_ORGANIC)) != 0;
2885 }
2886 
2892 {
2893  /* Lumber mills are neither raw nor processing */
2894  return (this->life_type & INDUSTRYLIFE_PROCESSING) != 0 &&
2895  (this->behaviour & INDUSTRYBEH_CUT_TREES) == 0;
2896 }
2897 
2903 {
2904  /* Building raw industries like secondary uses different price base */
2905  return (_price[(_settings_game.construction.raw_industry_construction == 1 && this->IsRawIndustry()) ?
2906  PR_BUILD_INDUSTRY_RAW : PR_BUILD_INDUSTRY] * this->cost_multiplier) >> 8;
2907 }
2908 
2916 {
2917  return (_price[PR_CLEAR_INDUSTRY] * this->removal_cost_multiplier) >> 8;
2918 }
2919 
2925 {
2927  !(HasBit(this->callback_mask, CBM_IND_PRODUCTION_256_TICKS) || HasBit(this->callback_mask, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks
2928  !(HasBit(this->callback_mask, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(this->callback_mask, CBM_IND_PRODUCTION_CHANGE) || HasBit(this->callback_mask, CBM_IND_PROD_CHANGE_BUILD)); // production change callbacks
2929 }
2930 
2931 IndustrySpec::~IndustrySpec()
2932 {
2933  if (HasBit(this->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
2934  free(this->random_sounds);
2935  }
2936 }
2937 
2938 static CommandCost TerraformTile_Industry(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
2939 {
2940  if (AutoslopeEnabled()) {
2941  /* We imitate here TTDP's behaviour:
2942  * - Both new and old slope must not be steep.
2943  * - TileMaxZ must not be changed.
2944  * - Allow autoslope by default.
2945  * - Disallow autoslope if callback succeeds and returns non-zero.
2946  */
2947  Slope tileh_old = GetTileSlope(tile);
2948  /* TileMaxZ must not be changed. Slopes must not be steep. */
2949  if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
2950  const IndustryGfx gfx = GetIndustryGfx(tile);
2951  const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
2952 
2953  /* Call callback 3C 'disable autosloping for industry tiles'. */
2954  if (HasBit(itspec->callback_mask, CBM_INDT_AUTOSLOPE)) {
2955  /* If the callback fails, allow autoslope. */
2956  uint16 res = GetIndustryTileCallback(CBID_INDTILE_AUTOSLOPE, 0, 0, gfx, Industry::GetByTile(tile), tile);
2957  if (res == CALLBACK_FAILED || !ConvertBooleanCallback(itspec->grf_prop.grffile, CBID_INDTILE_AUTOSLOPE, res)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2958  } else {
2959  /* allow autoslope */
2960  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2961  }
2962  }
2963  }
2964  return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
2965 }
2966 
2967 extern const TileTypeProcs _tile_type_industry_procs = {
2968  DrawTile_Industry, // draw_tile_proc
2969  GetSlopePixelZ_Industry, // get_slope_z_proc
2970  ClearTile_Industry, // clear_tile_proc
2971  AddAcceptedCargo_Industry, // add_accepted_cargo_proc
2972  GetTileDesc_Industry, // get_tile_desc_proc
2973  GetTileTrackStatus_Industry, // get_tile_track_status_proc
2974  ClickTile_Industry, // click_tile_proc
2975  AnimateTile_Industry, // animate_tile_proc
2976  TileLoop_Industry, // tile_loop_proc
2977  ChangeTileOwner_Industry, // change_tile_owner_proc
2978  nullptr, // add_produced_cargo_proc
2979  nullptr, // vehicle_enter_tile_proc
2980  GetFoundation_Industry, // get_foundation_proc
2981  TerraformTile_Industry, // terraform_tile_proc
2982 };
2983 
2984 bool IndustryCompare::operator() (const Industry *lhs, const Industry *rhs) const
2985 {
2986  return lhs->index < rhs->index;
2987 }
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
16 accepted cargoes.
Definition: industrytype.h:120
static void ResetIndustryCounts()
Resets industry counts.
Definition: industry.h:155
customize the cargoes the industry produces
Functions related to OTTD&#39;s strings.
static TileType GetTileType(TileIndex tile)
Get the tiletype of a given tile.
Definition: tile_map.h:96
static void SetIndustryGfx(TileIndex t, IndustryGfx gfx)
Set the industry graphics ID for the given industry tile.
Definition: industry_map.h:149
Owner
Enum for all companies/owners.
Definition: company_type.h:18
don&#39;t allow building on structures
Definition: command_type.h:345
Closing of industries.
Definition: news_type.h:27
initialise production level on construction
Functions/types related to NewGRF debugging.
the north corner of the tile is raised
Definition: slope_type.h:53
do not change town rating
Definition: command_type.h:354
static CommandCost CheckNewIndustry_Lumbermill(TileIndex tile)
Check the conditions of CHECK_LUMBERMILL (Industry should be in the rain forest). ...
#define RandomTile()
Get a valid random tile.
Definition: map_func.h:435
static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCommandFlag flags, const IndustrySpec *indspec, size_t layout_index, uint32 random_var8f, uint16 random_initial_bits, Owner founder, IndustryAvailabilityCallType creation_type, Industry **ip)
Helper function for Build/Fund an industry.
void ClampToMap()
Clamp the tile area to map borders.
Definition: tilearea.cpp:142
byte image_2
image offset 2
Definition: industry_land.h:21
static uint MapSizeX()
Get the size of the map along the X.
Definition: map_func.h:72
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:79
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition: game_core.cpp:141
Trigger whenever the construction state changes.
bool enabled
entity still available (by default true).newgrf can disable it, though
Definition: industrytype.h:139
byte production_rate[INDUSTRY_NUM_OUTPUTS]
production rate for each cargo
Definition: industry.h:47
void SetupTargetCount()
Decide how many industries of each type are needed.
static TropicZone GetTropicZone(TileIndex tile)
Get the tropic zone.
Definition: tile_map.h:238
Rainforest tile.
Definition: tile_type.h:72
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
static void SetAnimationFrame(TileIndex t, byte frame)
Set a new animation frame.
Definition: tile_map.h:262
static uint MapSizeY()
Get the size of the map along the Y.
Definition: map_func.h:82
void ClearDockingTilesCheckingNeighbours(TileIndex tile)
Clear docking tile status from tiles around a removed dock, if the tile has no neighbours which would...
Tile information, used while rendering the tile.
Definition: tile_cmd.h:42
south and east corner are raised
Definition: slope_type.h:57
Generate industries.
Definition: genworld.h:73
static const int INDUSTRY_CUT_TREE_TICKS
cycle duration for lumber mill&#39;s extra action
Definition: date_type.h:38
uint8 raw_industry_construction
type of (raw) industry construction (none, "normal", prospecting)
static CommandCost CheckNewIndustry_Farm(TileIndex tile)
Check the conditions of CHECK_FARM (Industry should be below snow-line in arctic).
Trigger when cargo is distributed.
the west corner of the tile is raised
Definition: slope_type.h:50
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3215
void TileLoop_Water(TileIndex tile)
Let a water tile floods its diagonal adjoining tiles called from tunnelbridge_cmd, and by TileLoop_Industry() and TileLoop_Track()
Definition: water_cmd.cpp:1206
byte landscape
the landscape we&#39;re currently in
static bool Chance16I(const uint a, const uint b, const uint32 r)
Checks if a given randomize-number is below a given probability.
void AddAnimatedTile(TileIndex tile)
Add the given tile to the animated tile table (if it does not exist on that table yet)...
Tile is desert.
Definition: tile_type.h:71
byte land_generator
the landscape generator
An invalid owner.
Definition: company_type.h:29
while editing a scenario
Definition: industrytype.h:57
Money GetRemovalCost() const
Get the cost for removing this industry Take note that the cost will always be zero for non-grf indus...
Part of an industry.
Definition: tile_type.h:49
EconomySettings economy
settings to change the economy
byte image_3
image offset 3
Definition: industry_land.h:22
byte image_1
image offset 1
Definition: industry_land.h:20
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
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition: vehicle.cpp:537
below this level, the industry is set to be closing
Definition: industry.h:32
void DeleteIndustryNews(IndustryID iid)
Remove news regarding given industry.
Definition: news_gui.cpp:933
int32 TileIndexDiff
An offset value between to tiles.
Definition: map_func.h:154
Train vehicle type.
Definition: vehicle_type.h:24
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:291
static void ReportNewsProductionChangeIndustry(Industry *ind, CargoID type, int percent)
Report news that industry production has changed significantly.
Trigger in the periodic tile loop.
Functions related to dates.
static WaterClass GetWaterClass(TileIndex t)
Get the water class at a tile.
Definition: water_map.h:106
const char * grf
newGRF used for the tile contents
Definition: tile_cmd.h:61
static bool IsSuitableForFarmField(TileIndex tile, bool allow_fields)
Check whether the tile can be replaced by a farm field.
Northwest.
static CommandCost CheckNewIndustry_BubbleGen(TileIndex tile)
Check the conditions of CHECK_BUBBLEGEN (Industry should be in low land).
Town * town
Nearest town.
Definition: industry.h:42
uint32 prospecting_chance
Chance prospecting succeeds.
Definition: industrytype.h:110
static byte GetAnimationFrame(TileIndex t)
Get the current animation frame.
Definition: tile_map.h:250
from the Fund/build using prospecting
Industries at sea should be positioned near edge of the map.
Definition: industrytype.h:48
Free the dynamically allocated sounds table.
Definition: industrytype.h:24
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
terraform a tile
Definition: command_type.h:186
static const IndustryGfx INVALID_INDUSTRYTILE
one above amount is considered invalid
Definition: industry_type.h:34
Number of industry density settings.
Definition: settings_type.h:49
CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit)
Translate a GRF-local cargo slot/bitnum into a CargoID.
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition: command_func.h:23
Ship vehicle type.
Definition: vehicle_type.h:26
Customize the input cargo types of a newly build industry.
Slope tileh
Slope of the tile.
Definition: tile_cmd.h:45
uint32 GetIndustryProbabilityCallback(IndustryType type, IndustryAvailabilityCallType creation_type, uint32 default_prob)
Check with callback CBID_INDUSTRY_PROBABILITY whether the industry can be built.
static IndustryGfx GetIndustryGfx(TileIndex t)
Get the industry graphics ID for the given industry tile.
Definition: industry_map.h:137
byte selected_layout
Which tile layout was used when creating the industry.
Definition: industry.h:70
static uint ScaleByMapSize(uint n)
Scales the given value by the map size, where the given value is for a 256 by 256 map...
Definition: map_func.h:122
uint8 construction_type
Way the industry was constructed (.
Definition: industry.h:68
no flag is set
Definition: command_type.h:343
A town owns the tile, or a town is expanding.
Definition: company_type.h:24
from the Fund/build window
default level set when the industry is created
Definition: industry.h:33
Other industry production changes.
Definition: news_type.h:31
IndustryLifeType life_type
This is also known as Industry production flag, in newgrf specs.
Definition: industrytype.h:122
periodically plants fields around itself (temp and arctic farms)
Definition: industrytype.h:63
Called monthly on production changes, so it can be adjusted more frequently.
do not increase production (oil wells) in the temperate climate
Definition: industrytype.h:70
OrthogonalTileArea & Expand(int rad)
Expand a tile area by rad tiles in each direction, keeping within map bounds.
Definition: tilearea.cpp:123
Functions related to vehicles.
uint16 callback_mask
Bitmask of industry callbacks that have to be called.
Definition: industrytype.h:137
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:205
static CommandCost CheckNewIndustry_Water(TileIndex tile)
Check the conditions of CHECK_WATER (Industry should be in the desert).
Vehicle data structure.
Definition: vehicle_base.h:210
static int GetSlopeMaxZ(Slope s)
Returns the height of the highest corner of a slope relative to TileZ (= minimal height) ...
Definition: slope_func.h:160
byte animation_substate
Sub state to time the change of the graphics/behaviour.
Opening of industries.
Definition: news_type.h:26
signal set to actually close the industry
Definition: industry.h:31
Defines the internal data of a functional industry.
Definition: industry.h:40
during random map creation
Definition: industrytype.h:56
demolish a tile
Definition: command_type.h:180
Tile description for the &#39;land area information&#39; tool.
Definition: tile_cmd.h:51
DifficultySettings difficulty
settings related to the difficulty
static void BroadcastNewEvent(ScriptEvent *event, CompanyID skip_company=MAX_COMPANIES)
Broadcast a new event to all active AIs.
Definition: ai_core.cpp:259
bool ambient
Play ambient, industry and town sounds.
Tindex index
Index of this pool item.
Definition: pool_type.hpp:189
the east corner of the tile is raised
Definition: slope_type.h:52
int8 acceptance[INDUSTRY_NUM_INPUTS]
Level of acceptance per cargo type (signed, may be negative!)
Definition: industrytype.h:157
Like factories.
Definition: industrytype.h:32
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
A special vehicle is one of the following:
static bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition: slope_func.h:36
Date last_cargo_accepted_at[INDUSTRY_NUM_INPUTS]
Last day each cargo type was accepted by this industry.
Definition: industry.h:69
static byte GetIndustryAnimationLoop(TileIndex tile)
Get the animation loop number.
Definition: industry_map.h:199
check industry construction on given area
Other expenses.
Definition: economy_type.h:161
Map accessors for tree tiles.
Functions related to world/map generation.
byte was_cargo_delivered
flag that indicate this has been the closest industry chosen for cargo delivery by a station...
Definition: industry.h:61
Construction costs.
Definition: economy_type.h:149
static void ResetIndustryConstructionStage(TileIndex tile)
Reset the construction stage counter of the industry, as well as the completion bit.
Definition: industry_map.h:187
uint16 random
Random value used for randomisation of all kinds of things.
Definition: industry.h:72
south and west corner are raised
Definition: slope_type.h:56
Common return value for all commands.
Definition: command_type.h:23
static Industry * GetRandom()
Return a random valid industry.
static CommandCost CheckNewIndustry_Plantation(TileIndex tile)
Check the conditions of CHECK_PLANTATION (Industry should NOT be in the desert).
static const int INDUSTRY_COMPLETED
final stage of industry construction.
Definition: industry_type.h:36
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:24
static void InvalidateAllFrom(SourceType src_type, SourceID src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
std::vector< IndustryTileLayout > layouts
List of possible tile layouts for the industry.
Definition: industrytype.h:107
control special effects
static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileLayout &layout, size_t layout_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool *custom_shape_check=nullptr)
Are the tiles of the industry free?
static bool IsClearGround(TileIndex t, ClearGround ct)
Set the type of clear tile.
Definition: clear_map.h:71
uint8 status
Status; 0: no looping, 1: looping, 0xFF: no animation.
is always built near towns (toy shop)
Definition: industrytype.h:68
EffectVehicle * CreateEffectVehicleAbove(int x, int y, int z, EffectVehicleType type)
Create an effect vehicle above a particular location.
the industry is running at full speed
Definition: industry.h:34
uint32 population
Current population of people.
Definition: town.h:45
Year _cur_year
Current year, starting at 0.
Definition: date.cpp:24
uint16 w
The width of the area.
Definition: tilearea_type.h:18
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition: tile_map.cpp:100
static IndustryID GetIndustryIndexOfField(TileIndex t)
Get the industry (farm) that made the field.
Definition: clear_map.h:195
void DeleteSubsidyWith(SourceType type, SourceID index)
Delete the subsidies associated with a given cargo source type and id.
Definition: subsidy.cpp:148
a flat tile
Definition: slope_type.h:49
int z
Height.
Definition: tile_cmd.h:47
Tables with default industry layouts and behaviours.
StationSettings station
settings related to station management
static const uint TILE_SIZE
Tile size in world coordinates.
Definition: tile_type.h:13
StringID production_down_text
Message appearing when the industry&#39;s production is decreasing.
Definition: industrytype.h:130
uint32 industry_daily_increment
The value which will increment industry_daily_change_counter. Computed value. NOSAVE.
Definition: economy_type.h:26
byte random_colour
randomized colour of the industry, for display purpose
Definition: industry.h:59
Industry directory; Window numbers:
Definition: window_type.h:259
static uint32 RandomRange(uint32 limit)
Pick a random number between 0 and limit - 1, inclusive.
Definition: random_func.hpp:81
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
Definition: landscape.cpp:470
Owner owner[4]
Name of the owner(s)
Definition: tile_cmd.h:53
StringID name
Displayed name of the industry.
Definition: industrytype.h:126
IndustryBuildData _industry_builder
In-game manager of industries.
StationList stations_near
NOSAVE: List of nearby stations.
Definition: industry.h:64
bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type)
Check whether an industry temporarily refuses to accept a certain cargo.
IndustryTileSpecialFlags special_flags
Bitmask of extra flags used by the tile.
Definition: industrytype.h:169
can only be built in towns (arctic/tropic banks, water tower)
Definition: industrytype.h:67
north and east corner are raised
Definition: slope_type.h:58
static uint ClampU(const uint a, const uint min, const uint max)
Clamp an unsigned integer between an interval.
Definition: math_func.hpp:182
Do not force one instance of this type to appear on map generation.
Definition: industrytype.h:80
not really a tile, but rather a very special check
Definition: industry_map.h:54
static bool IsIndustryCompleted(TileIndex t)
Is this industry tile fully built?
Definition: industry_map.h:75
static uint GetTreeGrowth(TileIndex t)
Returns the tree growth status.
Definition: tree_map.h:181
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:21
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
Functions related to (drawing on) viewports.
void ResetIndustries()
This function initialize the spec arrays of both industry and industry tiles.
Bubble of bubble generator (industry).
static IndustryGfx GetTranslatedIndustryTileID(IndustryGfx gfx)
Do industry gfx ID translation for NewGRFs.
Definition: industrytype.h:193
Data for managing the number and type of industries in the game.
Definition: industry.h:186
Invalid cargo type.
Definition: cargo_type.h:68
decides allowance of autosloping
Slope GetTileSlope(TileIndex tile, int *h)
Return the slope of a given tile inside the map.
Definition: tile_map.cpp:59
static const size_t MAX_SIZE
Make template parameter accessible from outside.
Definition: pool_type.hpp:86
static bool IsValidTile(TileIndex tile)
Checks if a tile is valid.
Definition: tile_map.h:161
Slope slopes_refused
slope pattern on which this tile cannot be built
Definition: industrytype.h:158
static bool IsBridgeAbove(TileIndex t)
checks if a bridge is set above the ground of this tile
Definition: bridge_map.h:45
const uint8 * random_sounds
array of random sounds.
Definition: industrytype.h:135
uint8 industry_platform
the amount of flat land around an industry
Base for all objects.
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
uint16 this_month_production[INDUSTRY_NUM_OUTPUTS]
stats of this month&#39;s production per cargo
Definition: industry.h:50
void FindStationsAroundTiles(const TileArea &location, StationList *const stations, bool use_nearby)
Find all stations around a rectangular producer (industry, house, headquarter, ...)
Tile animation!
Trigger every tick.
static Slope ComplementSlope(Slope s)
Return the complement of a slope.
Definition: slope_func.h:76
void IndustryDailyLoop()
Daily handler for the industry changes Taking the original map size of 256*256, the number of random ...
Some methods of Pool are placed here in order to reduce compilation time and binary size...
uint x
X position of the tile in unit coordinates.
Definition: tile_cmd.h:43
static uint32 GetRegister(uint i)
Gets the value of a so-called newgrf "register".
The tile has no ownership.
Definition: company_type.h:25
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition: tilearea_type.h:96
Foundation
Enumeration for Foundations.
Definition: slope_type.h:93
Types related to cheating.
TileIndex xy
town center tile
Definition: town.h:54
Customize the output cargo types of a newly build industry.
Other information.
Definition: error.h:22
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
static void MakeField(TileIndex t, uint field_type, IndustryID industry)
Make a (farm) field tile.
Definition: clear_map.h:280
Southeast.
can only be built after 1960 (oil rigs)
Definition: industrytype.h:72
TileIndex tile
Tile index.
Definition: tile_cmd.h:46
Functions related to errors.
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
Shorthand for calling the long DoCommand with a container.
Definition: command.cpp:441
The y axis.
bool IsRawIndustry() const
Is an industry with the spec a raw industry?
void Add(TileIndex to_add)
Add a single tile to a tile area; enlarge if needed.
Definition: tilearea.cpp:43
during random map generation
PersistentStorage * psa
Persistent storage for NewGRF industries.
Definition: industry.h:74
bool serve_neutral_industries
company stations can serve industries with attached neutral stations
The tile is leveled up to a flat slope.
Definition: slope_type.h:95
static size_t GetPoolSize()
Returns first unused index.
Definition: pool_type.hpp:312
SoundSettings sound
sound effect settings
Like power plants and banks.
Definition: industrytype.h:29
static void ChangeIndustryProduction(Industry *i, bool monthly)
Change industry production or do closure.
uint16 this_month_transported[INDUSTRY_NUM_OUTPUTS]
stats of this month&#39;s transport per cargo
Definition: industry.h:51
controls random production change
IndustryList industries_near
Cached list of industries near the station that can accept cargo,.
Definition: station_base.h:482
either by user or random creation process
Definition: industrytype.h:55
WaterClass
classes of water (for WATER_TILE_CLEAR water tile type).
Definition: water_map.h:47
static void SetupFarmFieldFence(TileIndex tile, int size, byte type, DiagDirection side)
Build farm field fence.
void TryBuildNewIndustry()
Try to create a random industry, during gameplay.
bool IsProcessingIndustry() const
Is an industry with the spec a processing industry?
static byte GetIndustryConstructionStage(TileIndex tile)
Returns the industry construction stage of the specified tile.
Definition: industry_map.h:100
uint DistanceMax(TileIndex t0, TileIndex t1)
Gets the biggest distance component (x or y) between the two given tiles.
Definition: map.cpp:189
Year last_prod_year
last year of production
Definition: industry.h:60
bool multiple_industry_per_town
allow many industries of the same type per town
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition: order_base.h:61
decides if default foundations need to be drawn
bool ConvertBooleanCallback(const GRFFile *grffile, uint16 cbid, uint16 cb_res)
Converts a callback result into a boolean.
static void SetIndustryConstructionCounter(TileIndex tile, byte value)
Sets this industry tile&#39;s construction counter value.
Definition: industry_map.h:174
Called to determine if industry can alter the ground below industry tile.
DoCommandFlag
List of flags for a command.
Definition: command_type.h:342
Called to determine the type (if any) of foundation to draw for industry tile.
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:78
bool Succeeded() const
Did this command succeed?
Definition: command_type.h:150
const IndustrySpec * GetIndustrySpec(IndustryType thistype)
Accessor for array _industry_specs.
void DeleteAnimatedTile(TileIndex tile)
Removes the given tile from the animated tile table.
#define TILE_AREA_LOOP(var, ta)
A loop which iterates over the tiles of a TileArea.
Definition of base types and functions in a cross-platform compatible way.
Tile always accepts all cargoes the associated industry accepts.
Definition: industrytype.h:90
static void SetIndustryAnimationLoop(TileIndex tile, byte count)
Set the animation loop number.
Definition: industry_map.h:211
static void AdvertiseIndustryOpening(const Industry *ind)
Advertise about a new industry opening.
bool UsesSmoothEconomy() const
Determines whether this industrytype uses smooth economy or whether it uses standard/newgrf productio...
CommandCost CheckNewIndustryProc(TileIndex tile)
Industrytype check function signature.
#define TILE_ADDXY(tile, x, y)
Adds a given offset to a tile.
Definition: map_func.h:258
void TriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger)
Trigger a random trigger for a single industry tile.
A number of safeguards to prevent using unsafe methods.
bool value
tells if the bool cheat is active or not
Definition: cheat_type.h:18
bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data)
Function performing a search around a center tile and going outward, thus in circle.
Definition: map.cpp:258
IndustryType GetIndustryType(TileIndex tile)
Retrieve the type for this industry.
IndustryType type
type of industry.
Definition: industry.h:57
static PaletteID GroundSpritePaletteTransform(SpriteID image, PaletteID pal, PaletteID default_pal)
Applies PALETTE_MODIFIER_COLOUR to a palette entry of a ground sprite.
Definition: sprite.h:168
static const IndustryGfx NEW_INDUSTRYTILEOFFSET
original number of tiles
Definition: industry_type.h:32
StringID new_industry_text
Message appearing when the industry is built.
Definition: industrytype.h:127
uint y
Y position of the tile in unit coordinates.
Definition: tile_cmd.h:44
static uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Definition: math_func.hpp:314
End marker of the industry check procedures.
Definition: industrytype.h:49
StringID MapGRFStringID(uint32 grfid, StringID str)
Used when setting an object&#39;s property to map to the GRF&#39;s strings while taking in consideration the ...
Definition: newgrf.cpp:547
static CommandCost CheckNewIndustry_OilRig(TileIndex tile)
Check the conditions of CHECK_OIL_RIG (Industries at sea should be positioned near edge of the map)...
byte anim_production
Animation frame to start when goods are produced.
Definition: industrytype.h:159
decides amount of cargo acceptance
CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, size_t layout_index, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type)
Check the slope of a tile of a new industry.
CargoLabel label
Unique label of the cargo type.
Definition: cargotype.h:57
TileArea location
Location of the industry.
Definition: industry.h:41
static int WhoCanServiceIndustry(Industry *ind)
Compute who can service the industry.
uint16 last_month_production[INDUSTRY_NUM_OUTPUTS]
total units produced per cargo in the last full month
Definition: industry.h:53
const T & GetOriginalValue() const
Returns the backupped value.
Definition: backup_type.hpp:72
static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, const IndustryTileLayout &layout, int type)
This function tries to flatten out the land below an industry, without damaging the surroundings too ...
Represents the covered area of e.g.
Definition: tilearea_type.h:16
CargoID produced_cargo[INDUSTRY_NUM_OUTPUTS]
16 production cargo slots
Definition: industry.h:44
static const IndustryGfx NUM_INDUSTRYTILES
total number of industry tiles, new and old
Definition: industry_type.h:33
don&#39;t allow building on water
Definition: command_type.h:347
Owner owner
owner of the industry. Which SHOULD always be (imho) OWNER_NONE
Definition: industry.h:58
Defines the data structure for constructing industry.
Definition: industrytype.h:106
TerraGenesis Perlin landscape generator.
Definition: genworld.h:21
This structure is the same for both Industries and Houses.
Definition: sprite.h:67
static uint16 GetIndustryTypeCount(IndustryType type)
Get the count of industries for this type.
Definition: industry.h:148
Smoke at copper mine.
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
Definition: viewport.cpp:1938
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:171
Industry should be positioned near edge of the map.
Definition: industrytype.h:42
void CheckIndustries()
Verify whether the generated industries are complete, and warn the user if not.
customize the cargoes the industry requires
Money GetConstructionCost() const
Get the cost for constructing this industry.
Base class for all effect vehicles.
const IndustryTileSpec * GetIndustryTileSpec(IndustryGfx gfx)
Accessor for array _industry_tile_specs.
void SetSeed(uint32 seed)
(Re)set the state of the random number generator.
Definition: random_func.cpp:55
static const DrawBuildingsTileStruct _industry_draw_tile_data[NEW_INDUSTRYTILEOFFSET *4]
Structure for industry tiles drawing.
Definition: industry_land.h:51
static const uint8 ANIM_STATUS_NO_ANIMATION
There is no animation.
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
16 input cargo slots
Definition: industry.h:49
IndustryAvailabilityCallType
From where has callback CBID_INDUSTRY_PROBABILITY been called.
static void PlaceInitialIndustry(IndustryType type, bool try_hard)
Try to build a industry on the map.
Industry view; Window numbers:
Definition: window_type.h:356
uint16 incoming_cargo_waiting[INDUSTRY_NUM_INPUTS]
incoming cargo waiting to be processed
Definition: industry.h:46
static CommandCost CheckIfFarEnoughFromConflictingIndustry(TileIndex tile, int type)
Check that the new industry is far enough from conflicting industries.
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:40
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
byte appear_ingame[NUM_LANDSCAPE]
Probability of appearance in game.
Definition: industrytype.h:132
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:140
static bool IsWaterTile(TileIndex t)
Is it a water tile with plain water?
Definition: water_map.h:184
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:40
#define MAX_UVALUE(type)
The largest value that can be entered in a variable.
Definition: stdafx.h:469
static Foundation FlatteningFoundation(Slope s)
Returns the foundation needed to flatten a slope.
Definition: slope_func.h:369
static bool EconomyIsInRecession()
Is the economy in recession?
Definition: economy_func.h:47
decides accepted types
cuts trees and produce first output cargo from them (lumber mill)
Definition: industrytype.h:64
Data for managing the number of industries of a single industry type.
Definition: industry.h:171
uint DistanceFromEdgeDir(TileIndex tile, DiagDirection dir)
Gets the distance to the edge of the map in given direction.
Definition: map.cpp:234
bool GetIndustryTypeData(IndustryType it)
Set the probability and min_number fields for the industry type it for a running game.
Functions related to autoslope.
Functions related to sound.
The game does not build industries.
Definition: settings_type.h:42
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:16
static bool AutoslopeEnabled()
Tests if autoslope is enabled for _current_company.
Definition: autoslope.h:44
NewGRF handling of industry tiles.
bool Failed() const
Did this command fail?
Definition: command_type.h:159
const struct SpriteGroup * spritegroup[Tcnt]
pointer to the different sprites of the entity
static bool Chance16R(const uint a, const uint b, uint32 &r)
Flips a coin with a given probability and saves the randomize-number in a variable.
Called to determine the colour of an industry.
CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
Build/Fund an industry.
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
Definition: viewport.cpp:659
Transfer all cargo onto the platform.
Definition: order_type.h:55
static uint GetNumberOfIndustries()
Get wanted number of industries on the map.
#define return_cmd_error(errcode)
Returns from a function with a specific StringID as error.
Definition: command_func.h:33
controls monthly random production change
static void IncIndustryTypeCount(IndustryType type)
Increment the count of industries for this type.
Definition: industry.h:126
Base class for all pools.
Definition: pool_type.hpp:82
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:137
void Reset()
Reset the entry.
static void MemCpyT(T *destination, const T *source, size_t num=1)
Type-safe version of memcpy().
Definition: mem_func.hpp:23
OrderUnloadFlags GetUnloadType() const
How must the consist be unloaded?
Definition: order_base.h:129
TileIndex TileAddWrap(TileIndex tile, int addx, int addy)
This function checks if we add addx/addy to tile, if we do wrap around the edges. ...
Definition: map.cpp:114
Called to determine which cargoes an industry should accept.
static bool Chance16(const uint a, const uint b)
Flips a coin with given probability.
uint8 callback_mask
Bitmask of industry tile callbacks that have to be called.
Definition: industrytype.h:167
bool IsTileForestIndustry(TileIndex tile)
Check whether the tile is a forest.
TileIndex tile
The base tile of the area.
Definition: tilearea_type.h:17
uint16 _tick_counter
Ever incrementing (and sometimes wrapping) tick counter for setting off various events.
Definition: date.cpp:28
uint64 dparam[2]
Parameters of the str string.
Definition: tile_cmd.h:62
static uint ScaleByMapSize1D(uint n)
Scales the given value by the maps circumference, where the given value is for a 256 by 256 map...
Definition: map_func.h:136
EffectVehicle * CreateEffectVehicle(int x, int y, int z, EffectVehicleType type)
Create an effect vehicle at a particular location.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don&#39;t get linker errors.
Definition: pool_func.hpp:224
static uint16 GetIndustryGamePlayProbability(IndustryType it, byte *min_number)
Compute the probability for constructing a new industry during game play.
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1162
static Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
static TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between to tiles from a TileIndexDiffC struct.
Definition: map_func.h:230
execute the given command
Definition: command_type.h:344
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
Definition: pool_type.hpp:270
static void PostDestructor(size_t index)
Invalidating some stuff after removing item from the pool.
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
Cargo accepted by this tile.
Definition: industrytype.h:156
The tile/execution is done by "water".
Definition: company_type.h:26
void GenerateIndustries()
This function will create random industries during game creation.
static const DrawIndustryCoordinates _coal_plant_sparks[]
Movement of the sparks , only used for Power Station.
void TriggerIndustry(Industry *ind, IndustryTileTrigger trigger)
Trigger a random trigger for all industry tiles.
std::vector< IndustryTileLayoutTile > IndustryTileLayout
A complete tile layout for an industry is a list of tiles.
Definition: industrytype.h:101
Tile got trees.
Definition: tile_type.h:45
GRFConfig * GetGRFConfig(uint32 grfid, uint32 mask)
Retrieve a NewGRF from the current config by its grfid.
static uint MapSize()
Get the size of the map.
Definition: map_func.h:92
void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res)
Record that a NewGRF returned an unknown/invalid callback result.
Class for storing amounts of cargo.
Definition: cargo_type.h:81
bool _generating_world
Whether we are generating the map or not.
Definition: genworld.cpp:60
uint16 produced_cargo_waiting[INDUSTRY_NUM_OUTPUTS]
amount of cargo produced per cargo
Definition: industry.h:45
byte oil_refinery_limit
distance oil refineries allowed from map edge
DestinationID GetDestination() const
Gets the destination of this order.
Definition: order_base.h:94
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:340
during creation of random ingame industry
is built on water (oil rig)
Definition: industrytype.h:65
byte minimal_cargo
minimum amount of cargo transported to the stations.
Definition: industrytype.h:119
Invisible tiles at the SW and SE border.
Definition: tile_type.h:48
byte appear_creation[NUM_LANDSCAPE]
Probability of appearance during map creation.
Definition: industrytype.h:133
Production changes of industry serviced by local company.
Definition: news_type.h:29
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:17
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition: tile_map.cpp:141
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition: cargotype.h:117
Set of callback functions for performing tile operations of a given tile type.
Definition: tile_cmd.h:145
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
Map accessors for &#39;clear&#39; tiles.
AnimationInfo animation
Information about the animation (is it looping, how many loops etc)
Definition: industrytype.h:168
Cargo support for NewGRFs.
void ReleaseDisastersTargetingIndustry(IndustryID i)
Marks all disasters targeting this industry in such a way they won&#39;t call Industry::Get(v->dest_tile)...
static size_t GetNumItems()
Returns number of valid items in the pool.
Definition: pool_type.hpp:321
static Industry * CreateNewIndustry(TileIndex tile, IndustryType type, IndustryAvailabilityCallType creation_type)
Create a new industry of random layout.
Vehicle * Next() const
Get the next vehicle of this vehicle.
Definition: vehicle_base.h:579
void RecomputeProductionMultipliers()
Recompute production_rate for current prod_level.
static TreeGround GetTreeGround(TileIndex t)
Returns the groundtype for tree tiles.
Definition: tree_map.h:88
north and west corner are raised
Definition: slope_type.h:55
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
static IndustryID GetIndustryIndex(TileIndex t)
Get the industry ID of the given tile.
Definition: industry_map.h:63
StringID closure_text
Message appearing when the industry closes.
Definition: industrytype.h:128
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:215
Cheat magic_bulldozer
dynamite industries, objects
Definition: cheat_type.h:27
static void SetIndustryCompleted(TileIndex tile)
Set if the industry that owns the tile as under construction or not.
Definition: industry_map.h:88
byte anim_next
Next frame in an animation.
Definition: industrytype.h:160
static PaletteID SpriteLayoutPaletteTransform(SpriteID image, PaletteID pal, PaletteID default_pal)
Applies PALETTE_MODIFIER_TRANSPARENT and PALETTE_MODIFIER_COLOUR to a palette entry of a sprite layou...
Definition: sprite.h:149
static T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:81
Allow produced/accepted cargoes callbacks to supply more than 2 and 3 types.
Definition: industrytype.h:82
The tile has no foundation, the slope remains unchanged.
Definition: slope_type.h:94
TransportType
Available types of transport.
static uint GB(const T x, const uint8 s, const uint8 n)
Fetch n bits from x, started at bit s.
int x
coordinate x of the first image offset
Definition: industry_land.h:19
static bool IsOilRig(TileIndex t)
Is tile t part of an oilrig?
Definition: station_map.h:274
Slope
Enumeration for the slope-type.
Definition: slope_type.h:48
uint32 Next()
Generate the next pseudo random number.
Definition: random_func.cpp:31
A tile of a station.
Definition: tile_type.h:46
0-3
Definition: clear_map.h:24
Called to query the cargo acceptance of the industry tile.
TownCache cache
Container for all cacheable data.
Definition: town.h:56
static Industry * PlaceIndustry(IndustryType type, IndustryAvailabilityCallType creation_type, bool try_hard)
Try to place the industry in the game.
static uint MapMaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
Definition: map_func.h:111
#define endof(x)
Get the end element of an fixed size array.
Definition: stdafx.h:384
static void DecIndustryTypeCount(IndustryType type)
Decrement the count of industries for this type.
Definition: industry.h:137
call production callback when cargo arrives at the industry
Town data structure.
Definition: town.h:53
uint32 industry_daily_change_counter
Bits 31-16 are number of industry to be performed, 15-0 are fractional collected daily.
Definition: economy_type.h:25
static const IndustryType NEW_INDUSTRYOFFSET
original number of industry types
Definition: industry_type.h:25
static CommandCost CheckNewIndustry_OilRefinery(TileIndex tile)
Check the conditions of CHECK_REFINERY (Industry should be positioned near edge of the map)...
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 bool CheckScaledDistanceFromEdge(TileIndex tile, uint maxdist)
Check if a tile is within a distance from map edges, scaled by map dimensions independently.
This is used to gather some data about animation drawing in the industry code Image_1-2-3 are in fact...
Definition: industry_land.h:18
static uint GetCurrentTotalNumberOfIndustries()
Get total number of industries existing in the game.
Functions related to OTTD&#39;s landscape.
Station * neutral_station
Associated neutral station.
Definition: industry.h:43
Base functions for all Games.
static uint32 GetScaledIndustryGenerationProbability(IndustryType it, bool *force_at_least_one)
Compute the appearance probability for an industry during map creation.
Functions related to commands.
IndustryBehaviour
Various industry behaviours mostly to represent original TTD specialities.
Definition: industrytype.h:61
uint32 probability
Relative probability of building this industry.
Definition: industry.h:172
static void SetIndustryIndexOfField(TileIndex t, IndustryID i)
Set the industry (farm) that made the field.
Definition: clear_map.h:207
static uint16 counts[NUM_INDUSTRYTYPES]
Number of industries per type ingame.
Definition: industry.h:161
Owner founder
Founder of the industry.
Definition: industry.h:66
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:45
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite for the current tile.
Definition: viewport.cpp:575
IndustryType conflicting[3]
Industries this industry cannot be close to.
Definition: industrytype.h:111
byte GetSnowLine()
Get the current snow line, either variable or static.
Definition: landscape.cpp:644
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:280
static CommandCost FindTownForIndustry(TileIndex tile, int type, Town **t)
Find a town for the industry, while checking for multiple industries in the same town.
static uint TileHeight(TileIndex tile)
Returns the height of a tile.
Definition: tile_map.h:29
static CommandCost CheckNewIndustry_Forest(TileIndex tile)
Check the conditions of CHECK_FOREST (Industry should be build above snow-line in arctic climate)...
uint32 wanted_inds
Number of wanted industries (bits 31-16), and a fraction (bits 15-0).
Definition: industry.h:188
Fields are planted around when built (all farms)
Definition: industrytype.h:69
Smoke of power plant (industry).
uint16 last_month_transported[INDUSTRY_NUM_OUTPUTS]
total units transported per cargo in the last full month
Definition: industry.h:54
Allow closing down the last instance of this type.
Definition: industrytype.h:81
ConstructionSettings construction
construction of things in-game
static const StringID INVALID_STRING_ID
Constant representing an invalid string (16bit in case it is used in savegames)
Definition: strings_type.h:17
static TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition: map_func.h:179
Base of all industries.
const char * GetName() const
Get the name of this grf.
Aircraft vehicle type.
Definition: vehicle_type.h:27
void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent, const SubSprite *sub, bool scale)
Add a child sprite to a parent sprite.
Definition: viewport.cpp:815
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:129
static CommandCost CheckIfIndustryIsAllowed(TileIndex tile, int type, const Town *t)
Is the industry allowed to be built at this place for the town?
void ResetOverride()
Resets the override, which is used while initializing game.
const struct GRFFile * grffile
grf file that introduced this entity
uint8 number_of_sounds
Number of sounds available in the sounds array.
Definition: industrytype.h:134
void MonthlyLoop()
Monthly update of industry build data.
StringID str
Description of the tile.
Definition: tile_cmd.h:52
byte min_number
Smallest number of industries that should exist (either 0 or 1).
Definition: industry.h:173
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
static bool HasTileWaterClass(TileIndex t)
Checks whether the tile has an waterclass associated.
Definition: water_map.h:95
StringID production_up_text
Message appearing when the industry&#39;s production is increasing.
Definition: industrytype.h:129
static bool SearchLumberMillTrees(TileIndex tile, void *user_data)
Search callback function for ChopLumberMillTrees.
void Restore()
Restore the variable.
DiagDirection
Enumeration for diagonal directions.
Base functions for all AIs.
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:83
static void SetClearCounter(TileIndex t, uint c)
Sets the counter used to advance to the next clear density/field type.
Definition: clear_map.h:144
Base of the town class.
byte check_proc
Index to a procedure to check for conflicting circumstances.
Definition: industrytype.h:112
Definition of one tile in an industry tile layout.
Definition: industrytype.h:95
static void SetFence(TileIndex t, DiagDirection side, uint h)
Sets the type of fence (and whether there is one) for the given border.
Definition: clear_map.h:240
Northeast, upper right on your monitor.
bool TileBelongsToIndustry(TileIndex tile) const
Check if a given tile belongs to this industry.
Definition: industry.h:86
GameCreationSettings game_creation
settings used during the creation of a game (map)
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition: tile_type.h:41
A house by a town.
Definition: tile_type.h:44
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
static uint MapMaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition: map_func.h:102
static bool IsInvisibilitySet(TransparencyOption to)
Check if the invisibility option bit is set and if we aren&#39;t in the game menu (there&#39;s never transpar...
Definition: transparency.h:59
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition: industry.h:113
Very few industries at game start.
Definition: settings_type.h:44
uint16 target_count
Desired number of industries of this type.
Definition: industry.h:174
Window functions not directly related to making/drawing windows.
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
Set the total of a stage of the world generation.
static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accepts, bool *c_produces)
Can given cargo type be accepted or produced by the industry?
bool smooth_economy
smooth economy
Functions related to water (management)
Force unloading all cargo onto the platform, possibly not getting paid.
Definition: order_type.h:54
Structure to encapsulate the pseudo random number generators.
Definition: random_func.hpp:21
town rating does not disallow you from building
Definition: command_type.h:349
byte industry_density
The industry density.
Definition: settings_type.h:56
static bool IsTileOnWater(TileIndex t)
Tests if the tile was built on water.
Definition: water_map.h:130
Production changes of industry serviced by competitor(s)
Definition: news_type.h:30
can only be built in towns larger than 1200 inhabitants (temperate bank)
Definition: industrytype.h:66
static void ChopLumberMillTrees(Industry *i)
Perform a circular search around the Lumber Mill in order to find trees to cut.
byte last_month_pct_transported[INDUSTRY_NUM_OUTPUTS]
percentage transported per cargo in the last full month
Definition: industry.h:52
static CheckNewIndustryProc *const _check_new_industry_procs[CHECK_END]
Check functions for different types of industry.
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:23
Called to determine industry special effects.
static void SetDParamX(uint64 *s, uint n, uint64 v)
Set a string parameter v at index n in a given array s.
Definition: strings_func.h:189
NewsType
Type of news.
Definition: news_type.h:21
Functions related to news.
The tile of the industry has been triggered during the tileloop.
Like forests.
Definition: industrytype.h:31
industries
Definition: transparency.h:26
Base classes/functions for stations.
call production callback every 256 ticks
Called when industry is built to set initial production level.
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
static Station * Get(size_t index)
Gets station with given index.
Date _date
Current date in days (day counter)
Definition: date.cpp:26
static T Delta(const T a, const T b)
Returns the (absolute) difference between two (scalar) variables.
Definition: math_func.hpp:230
uint16 h
The height of the area.
Definition: tilearea_type.h:19
static void MakeIndustry(TileIndex t, IndustryID index, IndustryGfx gfx, uint8 random, WaterClass wc)
Make the given tile an industry tile.
Definition: industry_map.h:278
static const int INDUSTRY_PRODUCE_TICKS
cycle duration for industry production
Definition: date_type.h:36
can only be built before 1950 (oil wells)
Definition: industrytype.h:71
the south corner of the tile is raised
Definition: slope_type.h:51
static const IndustryGfx INDUSTRYTILE_NOANIM
flag to mark industry tiles as having no animation
Definition: industry_type.h:31
static bool TransportIndustryGoods(TileIndex tile)
Move produced cargo from industry to nearby stations.
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:44
static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, const IndustryTileLayout &layout, size_t layout_index, Town *t, Owner founder, uint16 initial_random_bits)
Put an industry on the map.
The object is owned by a superuser / goal script.
Definition: company_type.h:27
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
static void UpdateIndustryStatistics(Industry *i)
Monthly update of industry statistics.
SoundFx
Sound effects from baseset.
Definition: sound_type.h:37
Class for backupping variables and making sure they are restored later.
Station data structure.
Definition: station_base.h:450
Functions related to effect vehicles.
static bool IsTransparencySet(TransparencyOption to)
Check if the transparency option bit is set and if we aren&#39;t in the game menu (there&#39;s never transpar...
Definition: transparency.h:48
#define TILE_MASK(x)
&#39;Wraps&#39; the given tile to it is within the map.
Definition: map_func.h:26
Functions related to subsidies.
Used for industry tiles on land (also for oilrig if newgrf says so).
Definition: water_map.h:51
Road vehicle type.
Definition: vehicle_type.h:25
static bool CheckIndustryCloseDownProtection(IndustryType type)
Protects an industry from closure if the appropriate flags and conditions are met INDUSTRYBEH_CANCLOS...
static void SetIndustryConstructionStage(TileIndex tile, byte value)
Sets the industry construction stage of the specified tile.
Definition: industry_map.h:112
Called on production changes, so it can be adjusted.
static byte GetIndustryConstructionCounter(TileIndex tile)
Returns this industry tile&#39;s construction counter value.
Definition: industry_map.h:162
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
Definition: window.cpp:3316
byte HighestSnowLine()
Get the highest possible snow line height, either variable or static.
Definition: landscape.cpp:658
Source/destination is an industry.
Definition: cargo_type.h:147
The industry has been triggered via its tick.
static CommandCost CheckNewIndustry_NULL(TileIndex tile)
Check the conditions of CHECK_NOTHING (Always succeeds).
bool anim_state
When true, the tile has to be drawn using the animation state instead of the construction state...
Definition: industrytype.h:165
give a custom colour to newly build industries
Southwest.
static void MemSetT(T *ptr, byte value, size_t num=1)
Type-safe version of memset().
Definition: mem_func.hpp:49
Cheats _cheats
All the cheats.
Definition: cheat.cpp:16
static void PopulateStationsNearby(Industry *ind)
Populate an industry&#39;s list of nearby stations, and if it accepts any cargo, also add the industry to...
uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile)
Perform an industry callback.
static int GetTileMaxPixelZ(TileIndex tile)
Get top height of the tile.
Definition: tile_map.h:304
void Reset()
Completely reset the industry build data.
decides slope suitability
Information about the behaviour of the default industry tiles.
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
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:24