OpenTTD
industry_cmd.cpp
Go to the documentation of this file.
1 /* $Id$ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #include "stdafx.h"
13 #include "clear_map.h"
14 #include "industry.h"
15 #include "station_base.h"
16 #include "landscape.h"
17 #include "viewport_func.h"
18 #include "command_func.h"
19 #include "town.h"
20 #include "news_func.h"
21 #include "cheat_type.h"
22 #include "genworld.h"
23 #include "tree_map.h"
24 #include "newgrf_cargo.h"
25 #include "newgrf_debug.h"
26 #include "newgrf_industrytiles.h"
27 #include "autoslope.h"
28 #include "water.h"
29 #include "strings_func.h"
30 #include "window_func.h"
31 #include "date_func.h"
32 #include "vehicle_func.h"
33 #include "sound_func.h"
34 #include "animated_tile_func.h"
35 #include "effectvehicle_func.h"
36 #include "effectvehicle_base.h"
37 #include "ai/ai.hpp"
38 #include "core/pool_func.hpp"
39 #include "subsidy_func.h"
40 #include "core/backup_type.hpp"
41 #include "object_base.h"
42 #include "game/game.hpp"
43 #include "error.h"
44 
45 #include "table/strings.h"
46 #include "table/industry_land.h"
47 #include "table/build_industry.h"
48 
49 #include "safeguards.h"
50 
51 IndustryPool _industry_pool("Industry");
53 
54 void ShowIndustryViewWindow(int industry);
55 void BuildOilRig(TileIndex tile);
56 
57 static byte _industry_sound_ctr;
58 static TileIndex _industry_sound_tile;
59 
61 
62 IndustrySpec _industry_specs[NUM_INDUSTRYTYPES];
63 IndustryTileSpec _industry_tile_specs[NUM_INDUSTRYTILES];
65 
73 {
74  for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) {
75  /* Reset the spec to default */
76  if (i < lengthof(_origin_industry_specs)) {
77  _industry_specs[i] = _origin_industry_specs[i];
78  } else {
79  _industry_specs[i] = IndustrySpec{};
80  }
81 
82  /* Enable only the current climate industries */
83  _industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET &&
84  HasBit(_origin_industry_specs[i].climate_availability, _settings_game.game_creation.landscape);
85  }
86 
87  memset(&_industry_tile_specs, 0, sizeof(_industry_tile_specs));
88  memcpy(&_industry_tile_specs, &_origin_industry_tile_specs, sizeof(_origin_industry_tile_specs));
89 
90  /* Reset any overrides that have been set. */
91  _industile_mngr.ResetOverride();
92  _industry_mngr.ResetOverride();
93 }
94 
103 IndustryType GetIndustryType(TileIndex tile)
104 {
105  assert(IsTileType(tile, MP_INDUSTRY));
106 
107  const Industry *ind = Industry::GetByTile(tile);
108  assert(ind != nullptr);
109  return ind->type;
110 }
111 
120 const IndustrySpec *GetIndustrySpec(IndustryType thistype)
121 {
122  assert(thistype < NUM_INDUSTRYTYPES);
123  return &_industry_specs[thistype];
124 }
125 
134 const IndustryTileSpec *GetIndustryTileSpec(IndustryGfx gfx)
135 {
136  assert(gfx < INVALID_INDUSTRYTILE);
137  return &_industry_tile_specs[gfx];
138 }
139 
140 Industry::~Industry()
141 {
142  if (CleaningPool()) return;
143 
144  /* Industry can also be destroyed when not fully initialized.
145  * This means that we do not have to clear tiles either.
146  * Also we must not decrement industry counts in that case. */
147  if (this->location.w == 0) return;
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 (this->neutral_station != nullptr) {
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  Industry *i;
1207  FOR_ALL_INDUSTRIES(i) {
1208  ProduceIndustryGoods(i);
1209  }
1210 }
1211 
1218 {
1219  return CommandCost();
1220 }
1221 
1228 {
1229  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
1230  if (GetTileZ(tile) < HighestSnowLine() + 2) {
1231  return_cmd_error(STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED);
1232  }
1233  }
1234  return CommandCost();
1235 }
1236 
1244 static bool CheckScaledDistanceFromEdge(TileIndex tile, uint maxdist)
1245 {
1246  uint maxdist_x = maxdist;
1247  uint maxdist_y = maxdist;
1248 
1249  if (MapSizeX() > 256) maxdist_x *= MapSizeX() / 256;
1250  if (MapSizeY() > 256) maxdist_y *= MapSizeY() / 256;
1251 
1252  if (DistanceFromEdgeDir(tile, DIAGDIR_NE) < maxdist_x) return true;
1253  if (DistanceFromEdgeDir(tile, DIAGDIR_NW) < maxdist_y) return true;
1254  if (DistanceFromEdgeDir(tile, DIAGDIR_SW) < maxdist_x) return true;
1255  if (DistanceFromEdgeDir(tile, DIAGDIR_SE) < maxdist_y) return true;
1256 
1257  return false;
1258 }
1259 
1266 {
1267  if (_game_mode == GM_EDITOR) return CommandCost();
1268 
1270 
1271  return_cmd_error(STR_ERROR_CAN_ONLY_BE_POSITIONED);
1272 }
1273 
1274 extern bool _ignore_restrictions;
1275 
1282 {
1283  if (_game_mode == GM_EDITOR && _ignore_restrictions) return CommandCost();
1284 
1285  if (TileHeight(tile) == 0 &&
1287 
1288  return_cmd_error(STR_ERROR_CAN_ONLY_BE_POSITIONED);
1289 }
1290 
1297 {
1298  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
1299  if (GetTileZ(tile) + 2 >= HighestSnowLine()) {
1300  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1301  }
1302  }
1303  return CommandCost();
1304 }
1305 
1312 {
1313  if (GetTropicZone(tile) == TROPICZONE_DESERT) {
1314  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1315  }
1316  return CommandCost();
1317 }
1318 
1325 {
1326  if (GetTropicZone(tile) != TROPICZONE_DESERT) {
1327  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT);
1328  }
1329  return CommandCost();
1330 }
1331 
1338 {
1339  if (GetTropicZone(tile) != TROPICZONE_RAINFOREST) {
1340  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST);
1341  }
1342  return CommandCost();
1343 }
1344 
1351 {
1352  if (GetTileZ(tile) > 4) {
1353  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_LOW_AREAS);
1354  }
1355  return CommandCost();
1356 }
1357 
1364 
1376 };
1377 
1389 {
1390  *t = ClosestTownFromTile(tile, UINT_MAX);
1391 
1393 
1394  const Industry *i;
1395  FOR_ALL_INDUSTRIES(i) {
1396  if (i->type == (byte)type && i->town == *t) {
1397  *t = nullptr;
1398  return_cmd_error(STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN);
1399  }
1400  }
1401 
1402  return CommandCost();
1403 }
1404 
1405 bool IsSlopeRefused(Slope current, Slope refused)
1406 {
1407  if (IsSteepSlope(current)) return true;
1408  if (current != SLOPE_FLAT) {
1409  if (IsSteepSlope(refused)) return true;
1410 
1411  Slope t = ComplementSlope(current);
1412 
1413  if ((refused & SLOPE_W) && (t & SLOPE_NW)) return true;
1414  if ((refused & SLOPE_S) && (t & SLOPE_NE)) return true;
1415  if ((refused & SLOPE_E) && (t & SLOPE_SW)) return true;
1416  if ((refused & SLOPE_N) && (t & SLOPE_SE)) return true;
1417  }
1418 
1419  return false;
1420 }
1421 
1434 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)
1435 {
1436  bool refused_slope = false;
1437  bool custom_shape = false;
1438 
1439  for (const IndustryTileLayoutTile &it : layout) {
1440  IndustryGfx gfx = GetTranslatedIndustryTileID(it.gfx);
1441  TileIndex cur_tile = TileAddWrap(tile, it.ti.x, it.ti.y);
1442 
1443  if (!IsValidTile(cur_tile)) {
1444  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1445  }
1446 
1447  if (gfx == GFX_WATERTILE_SPECIALCHECK) {
1448  if (!IsWaterTile(cur_tile) ||
1449  !IsTileFlat(cur_tile)) {
1450  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1451  }
1452  } else {
1453  CommandCost ret = EnsureNoVehicleOnGround(cur_tile);
1454  if (ret.Failed()) return ret;
1455  if (IsBridgeAbove(cur_tile)) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1456 
1457  const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
1458 
1459  IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
1460 
1461  /* Perform land/water check if not disabled */
1462  if (!HasBit(its->slopes_refused, 5) && ((HasTileWaterClass(cur_tile) && IsTileOnWater(cur_tile)) == !(ind_behav & INDUSTRYBEH_BUILT_ONWATER))) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1463 
1465  custom_shape = true;
1466  CommandCost ret = PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, layout_index, initial_random_bits, founder, creation_type);
1467  if (ret.Failed()) return ret;
1468  } else {
1469  Slope tileh = GetTileSlope(cur_tile);
1470  refused_slope |= IsSlopeRefused(tileh, its->slopes_refused);
1471  }
1472 
1473  if ((ind_behav & (INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE)) || // Tile must be a house
1474  ((ind_behav & INDUSTRYBEH_ONLY_NEARTOWN) && IsTileType(cur_tile, MP_HOUSE))) { // Tile is allowed to be a house (and it is a house)
1475  if (!IsTileType(cur_tile, MP_HOUSE)) {
1476  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS);
1477  }
1478 
1479  /* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */
1480  Backup<CompanyID> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
1481  CommandCost ret = DoCommand(cur_tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR);
1482  cur_company.Restore();
1483 
1484  if (ret.Failed()) return ret;
1485  } else {
1486  /* Clear the tiles, but do not affect town ratings */
1488 
1489  if (ret.Failed()) return ret;
1490  }
1491  }
1492  }
1493 
1494  if (custom_shape_check != nullptr) *custom_shape_check = custom_shape;
1495 
1496  /* It is almost impossible to have a fully flat land in TG, so what we
1497  * do is that we check if we can make the land flat later on. See
1498  * CheckIfCanLevelIndustryPlatform(). */
1499  if (!refused_slope || (_settings_game.game_creation.land_generator == LG_TERRAGENESIS && _generating_world && !custom_shape && !_ignore_restrictions)) {
1500  return CommandCost();
1501  }
1502  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1503 }
1504 
1513 {
1514  if ((GetIndustrySpec(type)->behaviour & INDUSTRYBEH_TOWN1200_MORE) && t->cache.population < 1200) {
1515  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200);
1516  }
1517 
1518  if ((GetIndustrySpec(type)->behaviour & INDUSTRYBEH_ONLY_NEARTOWN) && DistanceMax(t->xy, tile) > 9) {
1519  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_NEAR_TOWN_CENTER);
1520  }
1521 
1522  return CommandCost();
1523 }
1524 
1525 static bool CheckCanTerraformSurroundingTiles(TileIndex tile, uint height, int internal)
1526 {
1527  /* Check if we don't leave the map */
1528  if (TileX(tile) == 0 || TileY(tile) == 0 || GetTileType(tile) == MP_VOID) return false;
1529 
1530  TileArea ta(tile - TileDiffXY(1, 1), 2, 2);
1531  TILE_AREA_LOOP(tile_walk, ta) {
1532  uint curh = TileHeight(tile_walk);
1533  /* Is the tile clear? */
1534  if ((GetTileType(tile_walk) != MP_CLEAR) && (GetTileType(tile_walk) != MP_TREES)) return false;
1535 
1536  /* Don't allow too big of a change if this is the sub-tile check */
1537  if (internal != 0 && Delta(curh, height) > 1) return false;
1538 
1539  /* Different height, so the surrounding tiles of this tile
1540  * has to be correct too (in level, or almost in level)
1541  * else you get a chain-reaction of terraforming. */
1542  if (internal == 0 && curh != height) {
1543  if (TileX(tile_walk) == 0 || TileY(tile_walk) == 0 || !CheckCanTerraformSurroundingTiles(tile_walk + TileDiffXY(-1, -1), height, internal + 1)) {
1544  return false;
1545  }
1546  }
1547  }
1548 
1549  return true;
1550 }
1551 
1557 {
1558  int max_x = 0;
1559  int max_y = 0;
1560 
1561  /* Finds dimensions of largest variant of this industry */
1562  for (const IndustryTileLayoutTile &it : layout) {
1563  if (it.gfx == GFX_WATERTILE_SPECIALCHECK) continue; // watercheck tiles don't count for footprint size
1564  if (it.ti.x > max_x) max_x = it.ti.x;
1565  if (it.ti.y > max_y) max_y = it.ti.y;
1566  }
1567 
1568  /* Remember level height */
1569  uint h = TileHeight(tile);
1570 
1571  if (TileX(tile) <= _settings_game.construction.industry_platform + 1U || TileY(tile) <= _settings_game.construction.industry_platform + 1U) return false;
1572  /* Check that all tiles in area and surrounding are clear
1573  * this determines that there are no obstructing items */
1574 
1575  /* TileArea::Expand is not used here as we need to abort
1576  * instead of clamping if the bounds cannot expanded. */
1579 
1580  if (TileX(ta.tile) + ta.w >= MapMaxX() || TileY(ta.tile) + ta.h >= MapMaxY()) return false;
1581 
1582  /* _current_company is OWNER_NONE for randomly generated industries and in editor, or the company who funded or prospected the industry.
1583  * Perform terraforming as OWNER_TOWN to disable autoslope and town ratings. */
1584  Backup<CompanyID> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
1585 
1586  TILE_AREA_LOOP(tile_walk, ta) {
1587  uint curh = TileHeight(tile_walk);
1588  if (curh != h) {
1589  /* This tile needs terraforming. Check if we can do that without
1590  * damaging the surroundings too much. */
1591  if (!CheckCanTerraformSurroundingTiles(tile_walk, h, 0)) {
1592  cur_company.Restore();
1593  return false;
1594  }
1595  /* This is not 100% correct check, but the best we can do without modifying the map.
1596  * What is missing, is if the difference in height is more than 1.. */
1597  if (DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND).Failed()) {
1598  cur_company.Restore();
1599  return false;
1600  }
1601  }
1602  }
1603 
1604  if (flags & DC_EXEC) {
1605  /* Terraform the land under the industry */
1606  TILE_AREA_LOOP(tile_walk, ta) {
1607  uint curh = TileHeight(tile_walk);
1608  while (curh != h) {
1609  /* We give the terraforming for free here, because we can't calculate
1610  * exact cost in the test-round, and as we all know, that will cause
1611  * a nice assert if they don't match ;) */
1612  DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND);
1613  curh += (curh > h) ? -1 : 1;
1614  }
1615  }
1616  }
1617 
1618  cur_company.Restore();
1619  return true;
1620 }
1621 
1622 
1630 {
1631  const IndustrySpec *indspec = GetIndustrySpec(type);
1632  const Industry *i = nullptr;
1633 
1634  /* On a large map with many industries, it may be faster to check an area. */
1635  static const int dmax = 14;
1636  if (Industry::GetNumItems() > (size_t) (dmax * dmax * 2)) {
1637  TileArea tile_area = TileArea(tile, 1, 1).Expand(dmax);
1638  TILE_AREA_LOOP(atile, tile_area) {
1639  if (GetTileType(atile) == MP_INDUSTRY) {
1640  const Industry *i2 = Industry::GetByTile(atile);
1641  if (i == i2) continue;
1642  i = i2;
1643  if (DistanceMax(tile, i->location.tile) > (uint)dmax) continue;
1644  if (i->type == indspec->conflicting[0] ||
1645  i->type == indspec->conflicting[1] ||
1646  i->type == indspec->conflicting[2]) {
1647  return_cmd_error(STR_ERROR_INDUSTRY_TOO_CLOSE);
1648  }
1649  }
1650  }
1651  return CommandCost();
1652  }
1653 
1654  FOR_ALL_INDUSTRIES(i) {
1655  /* Within 14 tiles from another industry is considered close */
1656  if (DistanceMax(tile, i->location.tile) > 14) continue;
1657 
1658  /* check if there are any conflicting industry types around */
1659  if (i->type == indspec->conflicting[0] ||
1660  i->type == indspec->conflicting[1] ||
1661  i->type == indspec->conflicting[2]) {
1662  return_cmd_error(STR_ERROR_INDUSTRY_TOO_CLOSE);
1663  }
1664  }
1665  return CommandCost();
1666 }
1667 
1672 static void AdvertiseIndustryOpening(const Industry *ind)
1673 {
1674  const IndustrySpec *ind_spc = GetIndustrySpec(ind->type);
1675  SetDParam(0, ind_spc->name);
1676  if (ind_spc->new_industry_text > STR_LAST_STRINGID) {
1677  SetDParam(1, STR_TOWN_NAME);
1678  SetDParam(2, ind->town->index);
1679  } else {
1680  SetDParam(1, ind->town->index);
1681  }
1682  AddIndustryNewsItem(ind_spc->new_industry_text, NT_INDUSTRY_OPEN, ind->index);
1683  AI::BroadcastNewEvent(new ScriptEventIndustryOpen(ind->index));
1684  Game::NewEvent(new ScriptEventIndustryOpen(ind->index));
1685 }
1686 
1693 {
1695  /* Industry has a neutral station. Use it and ignore any other nearby stations. */
1696  ind->stations_near.insert(ind->neutral_station);
1697  ind->neutral_station->industries_near.clear();
1698  ind->neutral_station->industries_near.insert(ind);
1699  return;
1700  }
1701 
1702  /* Get our list of nearby stations. */
1703  FindStationsAroundTiles(ind->location, &ind->stations_near, false);
1704 
1705  /* Test if industry can accept cargo */
1706  uint cargo_index;
1707  for (cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
1708  if (ind->accepts_cargo[cargo_index] != CT_INVALID) break;
1709  }
1710  if (cargo_index >= lengthof(ind->accepts_cargo)) return;
1711 
1712  /* Cargo is accepted, add industry to nearby stations nearby industry list. */
1713  for (Station *st : ind->stations_near) {
1714  st->industries_near.insert(ind);
1715  }
1716 }
1717 
1729 static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, const IndustryTileLayout &layout, size_t layout_index, Town *t, Owner founder, uint16 initial_random_bits)
1730 {
1731  const IndustrySpec *indspec = GetIndustrySpec(type);
1732 
1733  i->location = TileArea(tile, 1, 1);
1734  i->type = type;
1736 
1737  MemCpyT(i->produced_cargo, indspec->produced_cargo, lengthof(i->produced_cargo));
1738  MemCpyT(i->production_rate, indspec->production_rate, lengthof(i->production_rate));
1740 
1748 
1749  /* don't use smooth economy for industries using production related callbacks */
1750  if (indspec->UsesSmoothEconomy()) {
1751  for (size_t ci = 0; ci < lengthof(i->production_rate); ci++) {
1752  i->production_rate[ci] = min((RandomRange(256) + 128) * i->production_rate[ci] >> 8, 255);
1753  }
1754  }
1755 
1756  i->town = t;
1757  i->owner = OWNER_NONE;
1758 
1759  uint16 r = Random();
1760  i->random_colour = GB(r, 0, 4);
1761  i->counter = GB(r, 4, 12);
1762  i->random = initial_random_bits;
1763  i->was_cargo_delivered = false;
1765  i->founder = founder;
1766 
1767  i->construction_date = _date;
1768  i->construction_type = (_game_mode == GM_EDITOR) ? ICT_SCENARIO_EDITOR :
1770 
1771  /* Adding 1 here makes it conform to specs of var44 of varaction2 for industries
1772  * 0 = created prior of newindustries
1773  * else, chosen layout + 1 */
1774  i->selected_layout = (byte)(layout_index + 1);
1775 
1777 
1778  /* Call callbacks after the regular fields got initialised. */
1779 
1781  uint16 res = GetIndustryCallback(CBID_INDUSTRY_PROD_CHANGE_BUILD, 0, Random(), i, type, INVALID_TILE);
1782  if (res != CALLBACK_FAILED) {
1783  if (res < PRODLEVEL_MINIMUM || res > PRODLEVEL_MAXIMUM) {
1785  } else {
1786  i->prod_level = res;
1788  }
1789  }
1790  }
1791 
1792  if (_generating_world) {
1795  for (size_t ci = 0; ci < lengthof(i->last_month_production); ci++) {
1796  i->last_month_production[ci] = i->produced_cargo_waiting[ci] * 8;
1797  i->produced_cargo_waiting[ci] = 0;
1798  }
1799  }
1800 
1801  for (size_t ci = 0; ci < lengthof(i->last_month_production); ci++) {
1802  i->last_month_production[ci] += i->production_rate[ci] * 8;
1803  }
1804  }
1805 
1806  if (HasBit(indspec->callback_mask, CBM_IND_DECIDE_COLOUR)) {
1807  uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE);
1808  if (res != CALLBACK_FAILED) {
1809  if (GB(res, 4, 11) != 0) ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_DECIDE_COLOUR, res);
1810  i->random_colour = GB(res, 0, 4);
1811  }
1812  }
1813 
1815  /* Clear all input cargo types */
1816  for (uint j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID;
1817  /* Query actual types */
1818  uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? lengthof(i->accepts_cargo) : 3;
1819  for (uint j = 0; j < maxcargoes; j++) {
1821  if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
1822  if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) {
1824  break;
1825  }
1826  CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
1827  if (std::find(indspec->accepts_cargo, endof(indspec->accepts_cargo), cargo) == endof(indspec->accepts_cargo)) {
1828  /* Cargo not in spec, error in NewGRF */
1830  break;
1831  }
1832  if (std::find(i->accepts_cargo, i->accepts_cargo + j, cargo) != i->accepts_cargo + j) {
1833  /* Duplicate cargo */
1835  break;
1836  }
1837  i->accepts_cargo[j] = cargo;
1838  }
1839  }
1840 
1842  /* Clear all output cargo types */
1843  for (uint j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID;
1844  /* Query actual types */
1845  uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? lengthof(i->produced_cargo) : 2;
1846  for (uint j = 0; j < maxcargoes; j++) {
1848  if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
1849  if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) {
1851  break;
1852  }
1853  CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
1854  if (std::find(indspec->produced_cargo, endof(indspec->produced_cargo), cargo) == endof(indspec->produced_cargo)) {
1855  /* Cargo not in spec, error in NewGRF */
1857  break;
1858  }
1859  if (std::find(i->produced_cargo, i->produced_cargo + j, cargo) != i->produced_cargo + j) {
1860  /* Duplicate cargo */
1862  break;
1863  }
1864  i->produced_cargo[j] = cargo;
1865  }
1866  }
1867 
1868  /* Plant the tiles */
1869 
1870  for (const IndustryTileLayoutTile &it : layout) {
1871  TileIndex cur_tile = tile + ToTileIndexDiff(it.ti);
1872 
1873  if (it.gfx != GFX_WATERTILE_SPECIALCHECK) {
1874  i->location.Add(cur_tile);
1875 
1876  WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID);
1877 
1879 
1880  MakeIndustry(cur_tile, i->index, it.gfx, Random(), wc);
1881 
1882  if (_generating_world) {
1883  SetIndustryConstructionCounter(cur_tile, 3);
1884  SetIndustryConstructionStage(cur_tile, 2);
1885  }
1886 
1887  /* it->gfx is stored in the map. But the translated ID cur_gfx is the interesting one */
1888  IndustryGfx cur_gfx = GetTranslatedIndustryTileID(it.gfx);
1889  const IndustryTileSpec *its = GetIndustryTileSpec(cur_gfx);
1891  }
1892  }
1893 
1895  for (uint j = 0; j != 50; j++) PlantRandomFarmField(i);
1896  }
1898 
1900 }
1901 
1918 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)
1919 {
1920  assert(layout_index < indspec->layouts.size());
1921  const IndustryTileLayout &layout = indspec->layouts[layout_index];
1922  bool custom_shape_check = false;
1923 
1924  *ip = nullptr;
1925 
1926  std::vector<ClearedObjectArea> object_areas(_cleared_object_areas);
1927  CommandCost ret = CheckIfIndustryTilesAreFree(tile, layout, layout_index, type, random_initial_bits, founder, creation_type, &custom_shape_check);
1928  _cleared_object_areas = object_areas;
1929  if (ret.Failed()) return ret;
1930 
1931  if (HasBit(GetIndustrySpec(type)->callback_mask, CBM_IND_LOCATION)) {
1932  ret = CheckIfCallBackAllowsCreation(tile, type, layout_index, random_var8f, random_initial_bits, founder, creation_type);
1933  } else {
1934  ret = _check_new_industry_procs[indspec->check_proc](tile);
1935  }
1936  if (ret.Failed()) return ret;
1937 
1939  !_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER, layout, type)) {
1940  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1941  }
1942 
1943  ret = CheckIfFarEnoughFromConflictingIndustry(tile, type);
1944  if (ret.Failed()) return ret;
1945 
1946  Town *t = nullptr;
1947  ret = FindTownForIndustry(tile, type, &t);
1948  if (ret.Failed()) return ret;
1949  assert(t != nullptr);
1950 
1951  ret = CheckIfIndustryIsAllowed(tile, type, t);
1952  if (ret.Failed()) return ret;
1953 
1954  if (!Industry::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_INDUSTRIES);
1955 
1956  if (flags & DC_EXEC) {
1957  *ip = new Industry(tile);
1958  if (!custom_shape_check) CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER | DC_EXEC, layout, type);
1959  DoCreateNewIndustry(*ip, tile, type, layout, layout_index, t, founder, random_initial_bits);
1960  }
1961 
1962  return CommandCost();
1963 }
1964 
1977 CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1978 {
1979  IndustryType it = GB(p1, 0, 8);
1980  if (it >= NUM_INDUSTRYTYPES) return CMD_ERROR;
1981 
1982  const IndustrySpec *indspec = GetIndustrySpec(it);
1983 
1984  /* Check if the to-be built/founded industry is available for this climate. */
1985  if (!indspec->enabled || indspec->layouts.empty()) return CMD_ERROR;
1986 
1987  /* If the setting for raw-material industries is not on, you cannot build raw-material industries.
1988  * Raw material industries are industries that do not accept cargo (at least for now) */
1989  if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 0 && indspec->IsRawIndustry()) {
1990  return CMD_ERROR;
1991  }
1992 
1993  if (_game_mode != GM_EDITOR && GetIndustryProbabilityCallback(it, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, 1) == 0) {
1994  return CMD_ERROR;
1995  }
1996 
1997  Randomizer randomizer;
1998  randomizer.SetSeed(p2);
1999  uint16 random_initial_bits = GB(p2, 0, 16);
2000  uint32 random_var8f = randomizer.Next();
2001  size_t num_layouts = indspec->layouts.size();
2002  CommandCost ret = CommandCost(STR_ERROR_SITE_UNSUITABLE);
2003  const bool deity_prospect = _current_company == OWNER_DEITY && !HasBit(p1, 16);
2004 
2005  Industry *ind = nullptr;
2006  if (deity_prospect || (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry())) {
2007  if (flags & DC_EXEC) {
2008  /* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */
2009  Backup<CompanyID> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
2010  /* Prospecting has a chance to fail, however we cannot guarantee that something can
2011  * be built on the map, so the chance gets lower when the map is fuller, but there
2012  * is nothing we can really do about that. */
2013  if (deity_prospect || Random() <= indspec->prospecting_chance) {
2014  for (int i = 0; i < 5000; i++) {
2015  /* We should not have more than one Random() in a function call
2016  * because parameter evaluation order is not guaranteed in the c++ standard
2017  */
2018  tile = RandomTile();
2019  /* Start with a random layout */
2020  size_t layout = RandomRange((uint32)num_layouts);
2021  /* Check now each layout, starting with the random one */
2022  for (size_t j = 0; j < num_layouts; j++) {
2023  layout = (layout + 1) % num_layouts;
2024  ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, cur_company.GetOriginalValue(), _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_PROSPECTCREATION, &ind);
2025  if (ret.Succeeded()) break;
2026  }
2027  if (ret.Succeeded()) break;
2028  }
2029  }
2030  cur_company.Restore();
2031  }
2032  } else {
2033  size_t layout = GB(p1, 8, 8);
2034  if (layout >= num_layouts) return CMD_ERROR;
2035 
2036  /* Check subsequently each layout, starting with the given layout in p1 */
2037  for (size_t i = 0; i < num_layouts; i++) {
2038  layout = (layout + 1) % num_layouts;
2039  ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, _current_company, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, &ind);
2040  if (ret.Succeeded()) break;
2041  }
2042 
2043  /* If it still failed, there's no suitable layout to build here, return the error */
2044  if (ret.Failed()) return ret;
2045  }
2046 
2047  if ((flags & DC_EXEC) && ind != nullptr && _game_mode != GM_EDITOR) {
2049  }
2050 
2051  return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
2052 }
2053 
2054 
2062 static Industry *CreateNewIndustry(TileIndex tile, IndustryType type, IndustryAvailabilityCallType creation_type)
2063 {
2064  const IndustrySpec *indspec = GetIndustrySpec(type);
2065 
2066  uint32 seed = Random();
2067  uint32 seed2 = Random();
2068  Industry *i = nullptr;
2069  size_t layout_index = RandomRange((uint32)indspec->layouts.size());
2070  CommandCost ret = CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, layout_index, seed, GB(seed2, 0, 16), OWNER_NONE, creation_type, &i);
2071  assert(i != nullptr || ret.Failed());
2072  return i;
2073 }
2074 
2081 static uint32 GetScaledIndustryGenerationProbability(IndustryType it, bool *force_at_least_one)
2082 {
2083  const IndustrySpec *ind_spc = GetIndustrySpec(it);
2084  uint32 chance = ind_spc->appear_creation[_settings_game.game_creation.landscape] * 16; // * 16 to increase precision
2085  if (!ind_spc->enabled || ind_spc->layouts.empty() ||
2086  (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) ||
2087  (chance = GetIndustryProbabilityCallback(it, IACT_MAPGENERATION, chance)) == 0) {
2088  *force_at_least_one = false;
2089  return 0;
2090  } else {
2091  /* We want industries appearing at coast to appear less often on bigger maps, as length of coast increases slower than map area.
2092  * For simplicity we scale in both cases, though scaling the probabilities of all industries has no effect. */
2093  chance = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? ScaleByMapSize1D(chance) : ScaleByMapSize(chance);
2094 
2095  *force_at_least_one = (chance > 0) && !(ind_spc->behaviour & INDUSTRYBEH_NOBUILT_MAPCREATION) && (_game_mode != GM_EDITOR);
2096  return chance;
2097  }
2098 }
2099 
2106 static uint16 GetIndustryGamePlayProbability(IndustryType it, byte *min_number)
2107 {
2109  *min_number = 0;
2110  return 0;
2111  }
2112 
2113  const IndustrySpec *ind_spc = GetIndustrySpec(it);
2114  byte chance = ind_spc->appear_ingame[_settings_game.game_creation.landscape];
2115  if (!ind_spc->enabled || ind_spc->layouts.empty() ||
2116  ((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && _cur_year > 1950) ||
2117  ((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && _cur_year < 1960) ||
2118  (chance = GetIndustryProbabilityCallback(it, IACT_RANDOMCREATION, chance)) == 0) {
2119  *min_number = 0;
2120  return 0;
2121  }
2122  *min_number = (ind_spc->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) ? 1 : 0;
2123  return chance;
2124 }
2125 
2131 {
2132  /* Number of industries on a 256x256 map. */
2133  static const uint16 numof_industry_table[] = {
2134  0, // none
2135  0, // minimal
2136  10, // very low
2137  25, // low
2138  55, // normal
2139  80, // high
2140  };
2141 
2142  assert(lengthof(numof_industry_table) == ID_END);
2143  uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.industry_density : (uint)ID_VERY_LOW;
2144  return min(IndustryPool::MAX_SIZE, ScaleByMapSize(numof_industry_table[difficulty]));
2145 }
2146 
2155 static Industry *PlaceIndustry(IndustryType type, IndustryAvailabilityCallType creation_type, bool try_hard)
2156 {
2157  uint tries = try_hard ? 10000u : 2000u;
2158  for (; tries > 0; tries--) {
2159  Industry *ind = CreateNewIndustry(RandomTile(), type, creation_type);
2160  if (ind != nullptr) return ind;
2161  }
2162  return nullptr;
2163 }
2164 
2170 static void PlaceInitialIndustry(IndustryType type, bool try_hard)
2171 {
2172  Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2173 
2175  PlaceIndustry(type, IACT_MAPGENERATION, try_hard);
2176 
2177  cur_company.Restore();
2178 }
2179 
2185 {
2186  int total = 0;
2187  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) total += Industry::GetIndustryTypeCount(it);
2188  return total;
2189 }
2190 
2191 
2194 {
2195  this->probability = 0;
2196  this->min_number = 0;
2197  this->target_count = 0;
2198  this->max_wait = 1;
2199  this->wait_count = 0;
2200 }
2201 
2204 {
2205  this->wanted_inds = GetCurrentTotalNumberOfIndustries() << 16;
2206 
2207  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2208  this->builddata[it].Reset();
2209  }
2210 }
2211 
2214 {
2215  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.
2216  if (_settings_game.difficulty.industry_density == ID_FUND_ONLY) return; // 'no industries' setting.
2217 
2218  /* To prevent running out of unused industries for the player to connect,
2219  * add a fraction of new industries each month, but only if the manager can keep up. */
2220  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).
2221  if (GetCurrentTotalNumberOfIndustries() + max_behind >= (this->wanted_inds >> 16)) {
2222  this->wanted_inds += ScaleByMapSize(NEWINDS_PER_MONTH);
2223  }
2224 }
2225 
2231 {
2232  if (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) return; // No industries in the game.
2233 
2234  uint32 industry_probs[NUM_INDUSTRYTYPES];
2235  bool force_at_least_one[NUM_INDUSTRYTYPES];
2236  uint32 total_prob = 0;
2237  uint num_forced = 0;
2238 
2239  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2240  industry_probs[it] = GetScaledIndustryGenerationProbability(it, force_at_least_one + it);
2241  total_prob += industry_probs[it];
2242  if (force_at_least_one[it]) num_forced++;
2243  }
2244 
2245  uint total_amount = GetNumberOfIndustries();
2246  if (total_prob == 0 || total_amount < num_forced) {
2247  /* Only place the forced ones */
2248  total_amount = num_forced;
2249  }
2250 
2252 
2253  /* Try to build one industry per type independent of any probabilities */
2254  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2255  if (force_at_least_one[it]) {
2256  assert(total_amount > 0);
2257  total_amount--;
2258  PlaceInitialIndustry(it, true);
2259  }
2260  }
2261 
2262  /* Add the remaining industries according to their probabilities */
2263  for (uint i = 0; i < total_amount; i++) {
2264  uint32 r = RandomRange(total_prob);
2265  IndustryType it = 0;
2266  while (r >= industry_probs[it]) {
2267  r -= industry_probs[it];
2268  it++;
2269  assert(it < NUM_INDUSTRYTYPES);
2270  }
2271  assert(industry_probs[it] > 0);
2272  PlaceInitialIndustry(it, false);
2273  }
2274  _industry_builder.Reset();
2275 }
2276 
2282 {
2283  for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
2284  if (i->produced_cargo[j] != CT_INVALID) {
2285  byte pct = 0;
2286  if (i->this_month_production[j] != 0) {
2288  pct = min(i->this_month_transported[j] * 256 / i->this_month_production[j], 255);
2289  }
2290  i->last_month_pct_transported[j] = pct;
2291 
2293  i->this_month_production[j] = 0;
2294 
2296  i->this_month_transported[j] = 0;
2297  }
2298  }
2299 }
2300 
2306 {
2307  const IndustrySpec *indspec = GetIndustrySpec(this->type);
2308  assert(!indspec->UsesSmoothEconomy());
2309 
2310  /* Rates are rounded up, so e.g. oilrig always produces some passengers */
2311  for (size_t i = 0; i < lengthof(this->production_rate); i++) {
2312  this->production_rate[i] = min(CeilDiv(indspec->production_rate[i] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF);
2313  }
2314 }
2315 
2316 
2323 {
2324  byte min_number;
2325  uint32 probability = GetIndustryGamePlayProbability(it, &min_number);
2326  bool changed = min_number != this->min_number || probability != this->probability;
2327  this->min_number = min_number;
2328  this->probability = probability;
2329  return changed;
2330 }
2331 
2334 {
2335  bool changed = false;
2336  uint num_planned = 0; // Number of industries planned in the industry build data.
2337  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2338  changed |= this->builddata[it].GetIndustryTypeData(it);
2339  num_planned += this->builddata[it].target_count;
2340  }
2341  uint total_amount = this->wanted_inds >> 16; // Desired total number of industries.
2342  changed |= num_planned != total_amount;
2343  if (!changed) return; // All industries are still the same, no need to re-randomize.
2344 
2345  /* Initialize the target counts. */
2346  uint force_build = 0; // Number of industries that should always be available.
2347  uint32 total_prob = 0; // Sum of probabilities.
2348  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2349  IndustryTypeBuildData *ibd = this->builddata + it;
2350  force_build += ibd->min_number;
2351  ibd->target_count = ibd->min_number;
2352  total_prob += ibd->probability;
2353  }
2354 
2355  if (total_prob == 0) return; // No buildable industries.
2356 
2357  /* Subtract forced industries from the number of industries available for construction. */
2358  total_amount = (total_amount <= force_build) ? 0 : total_amount - force_build;
2359 
2360  /* Assign number of industries that should be aimed for, by using the probability as a weight. */
2361  while (total_amount > 0) {
2362  uint32 r = RandomRange(total_prob);
2363  IndustryType it = 0;
2364  while (r >= this->builddata[it].probability) {
2365  r -= this->builddata[it].probability;
2366  it++;
2367  assert(it < NUM_INDUSTRYTYPES);
2368  }
2369  assert(this->builddata[it].probability > 0);
2370  this->builddata[it].target_count++;
2371  total_amount--;
2372  }
2373 }
2374 
2379 {
2380  this->SetupTargetCount();
2381 
2382  int missing = 0; // Number of industries that need to be build.
2383  uint count = 0; // Number of industry types eligible for build.
2384  uint32 total_prob = 0; // Sum of probabilities.
2385  IndustryType forced_build = NUM_INDUSTRYTYPES; // Industry type that should be forcibly build.
2386  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2387  int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
2388  missing += difference;
2389  if (this->builddata[it].wait_count > 0) continue; // This type may not be built now.
2390  if (difference > 0) {
2391  if (Industry::GetIndustryTypeCount(it) == 0 && this->builddata[it].min_number > 0) {
2392  /* An industry that should exist at least once, is not available. Force it, trying the most needed one first. */
2393  if (forced_build == NUM_INDUSTRYTYPES ||
2394  difference > this->builddata[forced_build].target_count - Industry::GetIndustryTypeCount(forced_build)) {
2395  forced_build = it;
2396  }
2397  }
2398  total_prob += difference;
2399  count++;
2400  }
2401  }
2402 
2403  if (EconomyIsInRecession() || (forced_build == NUM_INDUSTRYTYPES && (missing <= 0 || total_prob == 0))) count = 0; // Skip creation of an industry.
2404 
2405  if (count >= 1) {
2406  /* If not forced, pick a weighted random industry to build.
2407  * For the case that count == 1, there is no need to draw a random number. */
2408  IndustryType it;
2409  if (forced_build != NUM_INDUSTRYTYPES) {
2410  it = forced_build;
2411  } else {
2412  /* Non-forced, select an industry type to build (weighted random). */
2413  uint32 r = 0; // Initialized to silence the compiler.
2414  if (count > 1) r = RandomRange(total_prob);
2415  for (it = 0; it < NUM_INDUSTRYTYPES; it++) {
2416  if (this->builddata[it].wait_count > 0) continue; // Type may not be built now.
2417  int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
2418  if (difference <= 0) continue; // Too many of this kind.
2419  if (count == 1) break;
2420  if (r < (uint)difference) break;
2421  r -= difference;
2422  }
2423  assert(it < NUM_INDUSTRYTYPES && this->builddata[it].target_count > Industry::GetIndustryTypeCount(it));
2424  }
2425 
2426  /* Try to create the industry. */
2427  const Industry *ind = PlaceIndustry(it, IACT_RANDOMCREATION, false);
2428  if (ind == nullptr) {
2429  this->builddata[it].wait_count = this->builddata[it].max_wait + 1; // Compensate for decrementing below.
2430  this->builddata[it].max_wait = min(1000, this->builddata[it].max_wait + 2);
2431  } else {
2433  this->builddata[it].max_wait = max(this->builddata[it].max_wait / 2, 1); // Reduce waiting time of the industry type.
2434  }
2435  }
2436 
2437  /* Decrement wait counters. */
2438  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2439  if (this->builddata[it].wait_count > 0) this->builddata[it].wait_count--;
2440  }
2441 }
2442 
2451 static bool CheckIndustryCloseDownProtection(IndustryType type)
2452 {
2453  const IndustrySpec *indspec = GetIndustrySpec(type);
2454 
2455  /* oil wells (or the industries with that flag set) are always allowed to closedown */
2456  if ((indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE) return false;
2457  return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) == 0 && Industry::GetIndustryTypeCount(type) <= 1;
2458 }
2459 
2469 static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accepts, bool *c_produces)
2470 {
2471  if (cargo == CT_INVALID) return;
2472 
2473  /* Check for acceptance of cargo */
2474  for (byte j = 0; j < lengthof(ind->accepts_cargo); j++) {
2475  if (cargo == ind->accepts_cargo[j] && !IndustryTemporarilyRefusesCargo(ind, cargo)) {
2476  *c_accepts = true;
2477  break;
2478  }
2479  }
2480 
2481  /* Check for produced cargo */
2482  for (byte j = 0; j < lengthof(ind->produced_cargo); j++) {
2483  if (cargo == ind->produced_cargo[j]) {
2484  *c_produces = true;
2485  break;
2486  }
2487  }
2488 }
2489 
2504 {
2505  if (ind->stations_near.size() == 0) return 0; // No stations found at all => nobody services
2506 
2507  const Vehicle *v;
2508  int result = 0;
2509  FOR_ALL_VEHICLES(v) {
2510  /* Is it worthwhile to try this vehicle? */
2511  if (v->owner != _local_company && result != 0) continue;
2512 
2513  /* Check whether it accepts the right kind of cargo */
2514  bool c_accepts = false;
2515  bool c_produces = false;
2516  if (v->type == VEH_TRAIN && v->IsFrontEngine()) {
2517  for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
2518  CanCargoServiceIndustry(u->cargo_type, ind, &c_accepts, &c_produces);
2519  }
2520  } else if (v->type == VEH_ROAD || v->type == VEH_SHIP || v->type == VEH_AIRCRAFT) {
2521  CanCargoServiceIndustry(v->cargo_type, ind, &c_accepts, &c_produces);
2522  } else {
2523  continue;
2524  }
2525  if (!c_accepts && !c_produces) continue; // Wrong cargo
2526 
2527  /* Check orders of the vehicle.
2528  * We cannot check the first of shared orders only, since the first vehicle in such a chain
2529  * may have a different cargo type.
2530  */
2531  const Order *o;
2532  FOR_VEHICLE_ORDERS(v, o) {
2533  if (o->IsType(OT_GOTO_STATION) && !(o->GetUnloadType() & OUFB_TRANSFER)) {
2534  /* Vehicle visits a station to load or unload */
2535  Station *st = Station::Get(o->GetDestination());
2536  assert(st != nullptr);
2537 
2538  /* Same cargo produced by industry is dropped here => not serviced by vehicle v */
2539  if ((o->GetUnloadType() & OUFB_UNLOAD) && !c_accepts) break;
2540 
2541  if (ind->stations_near.find(st) != ind->stations_near.end()) {
2542  if (v->owner == _local_company) return 2; // Company services industry
2543  result = 1; // Competitor services industry
2544  }
2545  }
2546  }
2547  }
2548  return result;
2549 }
2550 
2559 {
2560  NewsType nt;
2561 
2562  switch (WhoCanServiceIndustry(ind)) {
2563  case 0: nt = NT_INDUSTRY_NOBODY; break;
2564  case 1: nt = NT_INDUSTRY_OTHER; break;
2565  case 2: nt = NT_INDUSTRY_COMPANY; break;
2566  default: NOT_REACHED();
2567  }
2568  SetDParam(2, abs(percent));
2569  SetDParam(0, CargoSpec::Get(type)->name);
2570  SetDParam(1, ind->index);
2571  AddIndustryNewsItem(
2572  percent >= 0 ? STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH : STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH,
2573  nt,
2574  ind->index
2575  );
2576 }
2577 
2578 static const uint PERCENT_TRANSPORTED_60 = 153;
2579 static const uint PERCENT_TRANSPORTED_80 = 204;
2580 
2586 static void ChangeIndustryProduction(Industry *i, bool monthly)
2587 {
2588  StringID str = STR_NULL;
2589  bool closeit = false;
2590  const IndustrySpec *indspec = GetIndustrySpec(i->type);
2591  bool standard = false;
2592  bool suppress_message = false;
2593  bool recalculate_multipliers = false;
2594  /* don't use smooth economy for industries using production related callbacks */
2595  bool smooth_economy = indspec->UsesSmoothEconomy();
2596  byte div = 0;
2597  byte mul = 0;
2598  int8 increment = 0;
2599 
2600  bool callback_enabled = HasBit(indspec->callback_mask, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE);
2601  if (callback_enabled) {
2603  if (res != CALLBACK_FAILED) { // failed callback means "do nothing"
2604  suppress_message = HasBit(res, 7);
2605  /* Get the custom message if any */
2606  if (HasBit(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16));
2607  res = GB(res, 0, 4);
2608  switch (res) {
2609  default: NOT_REACHED();
2610  case 0x0: break; // Do nothing, but show the custom message if any
2611  case 0x1: div = 1; break; // Halve industry production. If production reaches the quarter of the default, the industry is closed instead.
2612  case 0x2: mul = 1; break; // Double industry production if it hasn't reached eight times of the original yet.
2613  case 0x3: closeit = true; break; // The industry announces imminent closure, and is physically removed from the map next month.
2614  case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one.
2615  case 0x5: case 0x6: case 0x7: // Divide production by 4, 8, 16
2616  case 0x8: div = res - 0x3; break; // Divide production by 32
2617  case 0x9: case 0xA: case 0xB: // Multiply production by 4, 8, 16
2618  case 0xC: mul = res - 0x7; break; // Multiply production by 32
2619  case 0xD: // decrement production
2620  case 0xE: // increment production
2621  increment = res == 0x0D ? -1 : 1;
2622  break;
2623  case 0xF: // Set production to third byte of register 0x100
2625  recalculate_multipliers = true;
2626  break;
2627  }
2628  }
2629  } else {
2630  if (monthly != smooth_economy) return;
2631  if (indspec->life_type == INDUSTRYLIFE_BLACK_HOLE) return;
2632  }
2633 
2634  if (standard || (!callback_enabled && (indspec->life_type & (INDUSTRYLIFE_ORGANIC | INDUSTRYLIFE_EXTRACTIVE)) != 0)) {
2635  /* decrease or increase */
2636  bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE;
2637 
2638  if (smooth_economy) {
2639  closeit = true;
2640  for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
2641  if (i->produced_cargo[j] == CT_INVALID) continue;
2642  uint32 r = Random();
2643  int old_prod, new_prod, percent;
2644  /* If over 60% is transported, mult is 1, else mult is -1. */
2645  int mult = (i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_60) ? 1 : -1;
2646 
2647  new_prod = old_prod = i->production_rate[j];
2648 
2649  /* For industries with only_decrease flags (temperate terrain Oil Wells),
2650  * the multiplier will always be -1 so they will only decrease. */
2651  if (only_decrease) {
2652  mult = -1;
2653  /* For normal industries, if over 60% is transported, 33% chance for decrease.
2654  * Bonus for very high station ratings (over 80%): 16% chance for decrease. */
2655  } else if (Chance16I(1, ((i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_80) ? 6 : 3), r)) {
2656  mult *= -1;
2657  }
2658 
2659  /* 4.5% chance for 3-23% (or 1 unit for very low productions) production change,
2660  * determined by mult value. If mult = 1 prod. increases, else (-1) it decreases. */
2661  if (Chance16I(1, 22, r >> 16)) {
2662  new_prod += mult * (max(((RandomRange(50) + 10) * old_prod) >> 8, 1U));
2663  }
2664 
2665  /* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
2666  new_prod = Clamp(new_prod, 1, 255);
2667 
2668  if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1) {
2669  new_prod = Clamp(new_prod, 0, 16);
2670  }
2671 
2672  /* Do not stop closing the industry when it has the lowest possible production rate */
2673  if (new_prod == old_prod && old_prod > 1) {
2674  closeit = false;
2675  continue;
2676  }
2677 
2678  percent = (old_prod == 0) ? 100 : (new_prod * 100 / old_prod - 100);
2679  i->production_rate[j] = new_prod;
2680 
2681  /* Close the industry when it has the lowest possible production rate */
2682  if (new_prod > 1) closeit = false;
2683 
2684  if (abs(percent) >= 10) {
2686  }
2687  }
2688  } else {
2689  if (only_decrease || Chance16(1, 3)) {
2690  /* If more than 60% transported, 66% chance of increase, else 33% chance of increase */
2691  if (!only_decrease && (i->last_month_pct_transported[0] > PERCENT_TRANSPORTED_60) != Chance16(1, 3)) {
2692  mul = 1; // Increase production
2693  } else {
2694  div = 1; // Decrease production
2695  }
2696  }
2697  }
2698  }
2699 
2700  if (!callback_enabled && (indspec->life_type & INDUSTRYLIFE_PROCESSING)) {
2701  if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, smooth_economy ? 180 : 2)) {
2702  closeit = true;
2703  }
2704  }
2705 
2706  /* Increase if needed */
2707  while (mul-- != 0 && i->prod_level < PRODLEVEL_MAXIMUM) {
2709  recalculate_multipliers = true;
2710  if (str == STR_NULL) str = indspec->production_up_text;
2711  }
2712 
2713  /* Decrease if needed */
2714  while (div-- != 0 && !closeit) {
2715  if (i->prod_level == PRODLEVEL_MINIMUM) {
2716  closeit = true;
2717  } else {
2718  i->prod_level = max(i->prod_level / 2, (int)PRODLEVEL_MINIMUM); // typecast to int required to please MSVC
2719  recalculate_multipliers = true;
2720  if (str == STR_NULL) str = indspec->production_down_text;
2721  }
2722  }
2723 
2724  /* Increase or Decreasing the production level if needed */
2725  if (increment != 0) {
2726  if (increment < 0 && i->prod_level == PRODLEVEL_MINIMUM) {
2727  closeit = true;
2728  } else {
2730  recalculate_multipliers = true;
2731  }
2732  }
2733 
2734  /* Recalculate production_rate
2735  * For non-smooth economy these should always be synchronized with prod_level */
2736  if (recalculate_multipliers) i->RecomputeProductionMultipliers();
2737 
2738  /* Close if needed and allowed */
2739  if (closeit && !CheckIndustryCloseDownProtection(i->type)) {
2742  str = indspec->closure_text;
2743  }
2744 
2745  if (!suppress_message && str != STR_NULL) {
2746  NewsType nt;
2747  /* Compute news category */
2748  if (closeit) {
2749  nt = NT_INDUSTRY_CLOSE;
2750  AI::BroadcastNewEvent(new ScriptEventIndustryClose(i->index));
2751  Game::NewEvent(new ScriptEventIndustryClose(i->index));
2752  } else {
2753  switch (WhoCanServiceIndustry(i)) {
2754  case 0: nt = NT_INDUSTRY_NOBODY; break;
2755  case 1: nt = NT_INDUSTRY_OTHER; break;
2756  case 2: nt = NT_INDUSTRY_COMPANY; break;
2757  default: NOT_REACHED();
2758  }
2759  }
2760  /* Set parameters of news string */
2761  if (str > STR_LAST_STRINGID) {
2762  SetDParam(0, STR_TOWN_NAME);
2763  SetDParam(1, i->town->index);
2764  SetDParam(2, indspec->name);
2765  } else if (closeit) {
2766  SetDParam(0, STR_FORMAT_INDUSTRY_NAME);
2767  SetDParam(1, i->town->index);
2768  SetDParam(2, indspec->name);
2769  } else {
2770  SetDParam(0, i->index);
2771  }
2772  /* and report the news to the user */
2773  if (closeit) {
2774  AddTileNewsItem(str, nt, i->location.tile + TileDiffXY(1, 1));
2775  } else {
2776  AddIndustryNewsItem(str, nt, i->index);
2777  }
2778  }
2779 }
2780 
2789 {
2791 
2792  /* Bits 16-31 of industry_construction_counter contain the number of industries to change/create today,
2793  * the lower 16 bit are a fractional part that might accumulate over several days until it
2794  * is sufficient for an industry. */
2795  uint16 change_loop = _economy.industry_daily_change_counter >> 16;
2796 
2797  /* Reset the active part of the counter, just keeping the "fractional part" */
2798  _economy.industry_daily_change_counter &= 0xFFFF;
2799 
2800  if (change_loop == 0) {
2801  return; // Nothing to do? get out
2802  }
2803 
2804  Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2805 
2806  /* perform the required industry changes for the day */
2807 
2808  uint perc = 3; // Between 3% and 9% chance of creating a new industry.
2809  if ((_industry_builder.wanted_inds >> 16) > GetCurrentTotalNumberOfIndustries()) {
2810  perc = min(9u, perc + (_industry_builder.wanted_inds >> 16) - GetCurrentTotalNumberOfIndustries());
2811  }
2812  for (uint16 j = 0; j < change_loop; j++) {
2813  if (Chance16(perc, 100)) {
2814  _industry_builder.TryBuildNewIndustry();
2815  } else {
2817  if (i != nullptr) {
2818  ChangeIndustryProduction(i, false);
2820  }
2821  }
2822  }
2823 
2824  cur_company.Restore();
2825 
2826  /* production-change */
2828 }
2829 
2830 void IndustryMonthlyLoop()
2831 {
2832  Backup<CompanyID> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2833 
2834  _industry_builder.MonthlyLoop();
2835 
2836  Industry *i;
2837  FOR_ALL_INDUSTRIES(i) {
2839  if (i->prod_level == PRODLEVEL_CLOSURE) {
2840  delete i;
2841  } else {
2842  ChangeIndustryProduction(i, true);
2844  }
2845  }
2846 
2847  cur_company.Restore();
2848 
2849  /* production-change */
2851 }
2852 
2853 
2854 void InitializeIndustries()
2855 {
2857  _industry_sound_tile = 0;
2858 
2859  _industry_builder.Reset();
2860 }
2861 
2864 {
2865  int count = 0;
2866  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2867  if (Industry::GetIndustryTypeCount(it) > 0) continue; // Types of existing industries can be skipped.
2868 
2869  bool force_at_least_one;
2870  uint32 chance = GetScaledIndustryGenerationProbability(it, &force_at_least_one);
2871  if (chance == 0 || !force_at_least_one) continue; // Types that are not available can be skipped.
2872 
2873  const IndustrySpec *is = GetIndustrySpec(it);
2874  SetDParam(0, is->name);
2875  ShowErrorMessage(STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES, STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION, WL_WARNING);
2876 
2877  count++;
2878  if (count >= 3) break; // Don't swamp the user with errors.
2879  }
2880 }
2881 
2887 {
2888  return (this->life_type & (INDUSTRYLIFE_EXTRACTIVE | INDUSTRYLIFE_ORGANIC)) != 0;
2889 }
2890 
2896 {
2897  /* Lumber mills are neither raw nor processing */
2898  return (this->life_type & INDUSTRYLIFE_PROCESSING) != 0 &&
2899  (this->behaviour & INDUSTRYBEH_CUT_TREES) == 0;
2900 }
2901 
2907 {
2908  /* Building raw industries like secondary uses different price base */
2909  return (_price[(_settings_game.construction.raw_industry_construction == 1 && this->IsRawIndustry()) ?
2910  PR_BUILD_INDUSTRY_RAW : PR_BUILD_INDUSTRY] * this->cost_multiplier) >> 8;
2911 }
2912 
2920 {
2921  return (_price[PR_CLEAR_INDUSTRY] * this->removal_cost_multiplier) >> 8;
2922 }
2923 
2929 {
2931  !(HasBit(this->callback_mask, CBM_IND_PRODUCTION_256_TICKS) || HasBit(this->callback_mask, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks
2932  !(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
2933 }
2934 
2935 IndustrySpec::~IndustrySpec()
2936 {
2937  if (HasBit(this->cleanup_flag, CLEAN_RANDOMSOUNDS)) {
2938  free(this->random_sounds);
2939  }
2940 }
2941 
2942 static CommandCost TerraformTile_Industry(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
2943 {
2944  if (AutoslopeEnabled()) {
2945  /* We imitate here TTDP's behaviour:
2946  * - Both new and old slope must not be steep.
2947  * - TileMaxZ must not be changed.
2948  * - Allow autoslope by default.
2949  * - Disallow autoslope if callback succeeds and returns non-zero.
2950  */
2951  Slope tileh_old = GetTileSlope(tile);
2952  /* TileMaxZ must not be changed. Slopes must not be steep. */
2953  if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
2954  const IndustryGfx gfx = GetIndustryGfx(tile);
2955  const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
2956 
2957  /* Call callback 3C 'disable autosloping for industry tiles'. */
2958  if (HasBit(itspec->callback_mask, CBM_INDT_AUTOSLOPE)) {
2959  /* If the callback fails, allow autoslope. */
2960  uint16 res = GetIndustryTileCallback(CBID_INDTILE_AUTOSLOPE, 0, 0, gfx, Industry::GetByTile(tile), tile);
2961  if (res == CALLBACK_FAILED || !ConvertBooleanCallback(itspec->grf_prop.grffile, CBID_INDTILE_AUTOSLOPE, res)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2962  } else {
2963  /* allow autoslope */
2964  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2965  }
2966  }
2967  }
2968  return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
2969 }
2970 
2971 extern const TileTypeProcs _tile_type_industry_procs = {
2972  DrawTile_Industry, // draw_tile_proc
2973  GetSlopePixelZ_Industry, // get_slope_z_proc
2974  ClearTile_Industry, // clear_tile_proc
2975  AddAcceptedCargo_Industry, // add_accepted_cargo_proc
2976  GetTileDesc_Industry, // get_tile_desc_proc
2977  GetTileTrackStatus_Industry, // get_tile_track_status_proc
2978  ClickTile_Industry, // click_tile_proc
2979  AnimateTile_Industry, // animate_tile_proc
2980  TileLoop_Industry, // tile_loop_proc
2981  ChangeTileOwner_Industry, // change_tile_owner_proc
2982  nullptr, // add_produced_cargo_proc
2983  nullptr, // vehicle_enter_tile_proc
2984  GetFoundation_Industry, // get_foundation_proc
2985  TerraformTile_Industry, // terraform_tile_proc
2986 };
2987 
2988 bool IndustryCompare::operator() (const Industry *lhs, const Industry *rhs) const
2989 {
2990  return lhs->index < rhs->index;
2991 }
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
16 accepted cargoes.
Definition: industrytype.h:122
static void ResetIndustryCounts()
Resets industry counts.
Definition: industry.h:157
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:98
static void SetIndustryGfx(TileIndex t, IndustryGfx gfx)
Set the industry graphics ID for the given industry tile.
Definition: industry_map.h:151
Owner
Enum for all companies/owners.
Definition: company_type.h:20
don&#39;t allow building on structures
Definition: command_type.h:347
Closing of industries.
Definition: news_type.h:29
initialise production level on construction
Functions/types related to NewGRF debugging.
the north corner of the tile is raised
Definition: slope_type.h:55
do not change town rating
Definition: command_type.h:356
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:437
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:144
byte image_2
image offset 2
Definition: industry_land.h:23
static uint MapSizeX()
Get the size of the map along the X.
Definition: map_func.h:74
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:81
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition: game_core.cpp:143
Trigger whenever the construction state changes.
bool enabled
entity still available (by default true).newgrf can disable it, though
Definition: industrytype.h:141
byte production_rate[INDUSTRY_NUM_OUTPUTS]
production rate for each cargo
Definition: industry.h:49
void SetupTargetCount()
Decide how many industries of each type are needed.
static TropicZone GetTropicZone(TileIndex tile)
Get the tropic zone.
Definition: tile_map.h:240
Rainforest tile.
Definition: tile_type.h:74
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:264
static uint MapSizeY()
Get the size of the map along the Y.
Definition: map_func.h:84
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:44
south and east corner are raised
Definition: slope_type.h:59
Generate industries.
Definition: genworld.h:75
static const int INDUSTRY_CUT_TREE_TICKS
cycle duration for lumber mill&#39;s extra action
Definition: date_type.h:40
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:52
void SetWindowDirty(WindowClass cls, WindowNumber number)
Mark window as dirty (in need of repainting)
Definition: window.cpp:3199
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:1208
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:73
byte land_generator
the landscape generator
An invalid owner.
Definition: company_type.h:31
while editing a scenario
Definition: industrytype.h:59
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:51
EconomySettings economy
settings to change the economy
byte image_3
image offset 3
Definition: industry_land.h:24
byte image_1
image offset 1
Definition: industry_land.h:22
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:57
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition: vehicle.cpp:539
below this level, the industry is set to be closing
Definition: industry.h:34
void DeleteIndustryNews(IndustryID iid)
Remove news regarding given industry.
Definition: news_gui.cpp:886
int32 TileIndexDiff
An offset value between to tiles.
Definition: map_func.h:156
Train vehicle type.
Definition: vehicle_type.h:26
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:246
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:108
const char * grf
newGRF used for the tile contents
Definition: tile_cmd.h:63
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:44
uint32 prospecting_chance
Chance prospecting succeeds.
Definition: industrytype.h:112
static byte GetAnimationFrame(TileIndex t)
Get the current animation frame.
Definition: tile_map.h:252
from the Fund/build using prospecting
Industries at sea should be positioned near edge of the map.
Definition: industrytype.h:50
Free the dynamically allocated sounds table.
Definition: industrytype.h:26
static T SetBit(T &x, const uint8 y)
Set a bit in a variable.
terraform a tile
Definition: command_type.h:188
static const IndustryGfx INVALID_INDUSTRYTILE
one above amount is considered invalid
Definition: industry_type.h:36
Number of industry density settings.
Definition: settings_type.h:51
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:25
Ship vehicle type.
Definition: vehicle_type.h:28
Customize the input cargo types of a newly build industry.
Slope tileh
Slope of the tile.
Definition: tile_cmd.h:47
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:139
byte selected_layout
Which tile layout was used when creating the industry.
Definition: industry.h:72
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:124
uint8 construction_type
Way the industry was constructed (.
Definition: industry.h:70
no flag is set
Definition: command_type.h:345
A town owns the tile, or a town is expanding.
Definition: company_type.h:26
from the Fund/build window
default level set when the industry is created
Definition: industry.h:35
Other industry production changes.
Definition: news_type.h:33
IndustryLifeType life_type
This is also known as Industry production flag, in newgrf specs.
Definition: industrytype.h:124
periodically plants fields around itself (temp and arctic farms)
Definition: industrytype.h:65
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:72
OrthogonalTileArea & Expand(int rad)
Expand a tile area by rad tiles in each direction, keeping within map bounds.
Definition: tilearea.cpp:125
Functions related to vehicles.
uint16 callback_mask
Bitmask of industry callbacks that have to be called.
Definition: industrytype.h:139
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:207
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:212
static int GetSlopeMaxZ(Slope s)
Returns the height of the highest corner of a slope relative to TileZ (= minimal height) ...
Definition: slope_func.h:162
byte animation_substate
Sub state to time the change of the graphics/behaviour.
Opening of industries.
Definition: news_type.h:28
signal set to actually close the industry
Definition: industry.h:33
Defines the internal data of a functional industry.
Definition: industry.h:42
during random map creation
Definition: industrytype.h:58
demolish a tile
Definition: command_type.h:182
Tile description for the &#39;land area information&#39; tool.
Definition: tile_cmd.h:53
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:263
bool ambient
Play ambient, industry and town sounds.
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
the east corner of the tile is raised
Definition: slope_type.h:54
int8 acceptance[INDUSTRY_NUM_INPUTS]
Level of acceptance per cargo type (signed, may be negative!)
Definition: industrytype.h:159
Like factories.
Definition: industrytype.h:34
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:382
A special vehicle is one of the following:
static bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition: slope_func.h:38
Date last_cargo_accepted_at[INDUSTRY_NUM_INPUTS]
Last day each cargo type was accepted by this industry.
Definition: industry.h:71
static byte GetIndustryAnimationLoop(TileIndex tile)
Get the animation loop number.
Definition: industry_map.h:201
check industry construction on given area
Other expenses.
Definition: economy_type.h:163
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:63
Construction costs.
Definition: economy_type.h:151
static void ResetIndustryConstructionStage(TileIndex tile)
Reset the construction stage counter of the industry, as well as the completion bit.
Definition: industry_map.h:189
uint16 random
Random value used for randomisation of all kinds of things.
Definition: industry.h:74
south and west corner are raised
Definition: slope_type.h:58
Common return value for all commands.
Definition: command_type.h:25
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:38
static T max(const T a, const T b)
Returns the maximum of two values.
Definition: math_func.hpp:26
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:109
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:73
uint8 status
Status; 0: no looping, 1: looping, 0xFF: no animation.
is always built near towns (toy shop)
Definition: industrytype.h:70
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:36
uint32 population
Current population of people.
Definition: town.h:47
Year _cur_year
Current year, starting at 0.
Definition: date.cpp:26
uint16 w
The width of the area.
Definition: tilearea_type.h:20
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition: tile_map.cpp:102
static IndustryID GetIndustryIndexOfField(TileIndex t)
Get the industry (farm) that made the field.
Definition: clear_map.h:197
void DeleteSubsidyWith(SourceType type, SourceID index)
Delete the subsidies associated with a given cargo source type and id.
Definition: subsidy.cpp:153
a flat tile
Definition: slope_type.h:51
int z
Height.
Definition: tile_cmd.h:49
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:15
StringID production_down_text
Message appearing when the industry&#39;s production is decreasing.
Definition: industrytype.h:132
uint32 industry_daily_increment
The value which will increment industry_daily_change_counter. Computed value. NOSAVE.
Definition: economy_type.h:28
byte random_colour
randomized colour of the industry, for display purpose
Definition: industry.h:61
Industry directory; Window numbers:
Definition: window_type.h:261
static uint32 RandomRange(uint32 limit)
Pick a random number between 0 and limit - 1, inclusive.
Definition: random_func.hpp:83
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
Definition: landscape.cpp:472
Owner owner[4]
Name of the owner(s)
Definition: tile_cmd.h:55
StringID name
Displayed name of the industry.
Definition: industrytype.h:128
IndustryBuildData _industry_builder
In-game manager of industries.
StationList stations_near
NOSAVE: List of nearby stations.
Definition: industry.h:66
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:171
can only be built in towns (arctic/tropic banks, water tower)
Definition: industrytype.h:69
north and east corner are raised
Definition: slope_type.h:60
static uint ClampU(const uint a, const uint min, const uint max)
Clamp an unsigned integer between an interval.
Definition: math_func.hpp:184
Do not force one instance of this type to appear on map generation.
Definition: industrytype.h:82
not really a tile, but rather a very special check
Definition: industry_map.h:56
static bool IsIndustryCompleted(TileIndex t)
Is this industry tile fully built?
Definition: industry_map.h:77
static uint GetTreeGrowth(TileIndex t)
Returns the tree growth status.
Definition: tree_map.h:183
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:23
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition: tile_map.cpp:123
Date construction_date
Date of the construction of the industry.
Definition: industry.h:69
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:195
Data for managing the number and type of industries in the game.
Definition: industry.h:191
Invalid cargo type.
Definition: cargo_type.h:70
decides allowance of autosloping
Slope GetTileSlope(TileIndex tile, int *h)
Return the slope of a given tile inside the map.
Definition: tile_map.cpp:61
static const size_t MAX_SIZE
Make template parameter accessible from outside.
Definition: pool_type.hpp:87
static bool IsValidTile(TileIndex tile)
Checks if a tile is valid.
Definition: tile_map.h:163
Slope slopes_refused
slope pattern on which this tile cannot be built
Definition: industrytype.h:160
static bool IsBridgeAbove(TileIndex t)
checks if a bridge is set above the ground of this tile
Definition: bridge_map.h:47
const uint8 * random_sounds
array of random sounds.
Definition: industrytype.h:137
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:3499
uint16 this_month_production[INDUSTRY_NUM_OUTPUTS]
stats of this month&#39;s production per cargo
Definition: industry.h:52
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:78
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:45
static uint32 GetRegister(uint i)
Gets the value of a so-called newgrf "register".
The tile has no ownership.
Definition: company_type.h:27
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition: tilearea_type.h:98
Foundation
Enumeration for Foundations.
Definition: slope_type.h:95
Types related to cheating.
TileIndex xy
town center tile
Definition: town.h:56
Customize the output cargo types of a newly build industry.
Other information.
Definition: error.h:24
static bool IsTileType(TileIndex tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:152
static void MakeField(TileIndex t, uint field_type, IndustryID industry)
Make a (farm) field tile.
Definition: clear_map.h:282
Southeast.
can only be built after 1960 (oil rigs)
Definition: industrytype.h:74
TileIndex tile
Tile index.
Definition: tile_cmd.h:48
Functions related to errors.
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
Shorthand for calling the long DoCommand with a container.
Definition: command.cpp:443
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:45
during random map generation
PersistentStorage * psa
Persistent storage for NewGRF industries.
Definition: industry.h:76
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:97
static size_t GetPoolSize()
Returns first unused index.
Definition: pool_type.hpp:267
SoundSettings sound
sound effect settings
Like power plants and banks.
Definition: industrytype.h:31
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:53
controls random production change
IndustryList industries_near
Cached list of industries near the station that can accept cargo,.
Definition: station_base.h:484
either by user or random creation process
Definition: industrytype.h:57
WaterClass
classes of water (for WATER_TILE_CLEAR water tile type).
Definition: water_map.h:49
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:102
uint DistanceMax(TileIndex t0, TileIndex t1)
Gets the biggest distance component (x or y) between the two given tiles.
Definition: map.cpp:191
Year last_prod_year
last year of production
Definition: industry.h:62
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:63
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:176
Called to determine if industry can alter the ground below industry tile.
DoCommandFlag
List of flags for a command.
Definition: command_type.h:344
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:80
bool Succeeded() const
Did this command succeed?
Definition: command_type.h:152
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:92
static void SetIndustryAnimationLoop(TileIndex tile, byte count)
Set the animation loop number.
Definition: industry_map.h:213
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:260
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:20
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:260
IndustryType GetIndustryType(TileIndex tile)
Retrieve the type for this industry.
IndustryType type
type of industry.
Definition: industry.h:59
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:170
static const IndustryGfx NEW_INDUSTRYTILEOFFSET
original number of tiles
Definition: industry_type.h:34
StringID new_industry_text
Message appearing when the industry is built.
Definition: industrytype.h:129
uint y
Y position of the tile in unit coordinates.
Definition: tile_cmd.h:46
static uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Definition: math_func.hpp:316
End marker of the industry check procedures.
Definition: industrytype.h:51
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:549
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:161
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:59
TileArea location
Location of the industry.
Definition: industry.h:43
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:55
CargoID cargo_type
type of cargo this vehicle is carrying
Definition: vehicle_base.h:305
const T & GetOriginalValue() const
Returns the backupped value.
Definition: backup_type.hpp:74
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:18
CargoID produced_cargo[INDUSTRY_NUM_OUTPUTS]
16 production cargo slots
Definition: industry.h:46
static const IndustryGfx NUM_INDUSTRYTILES
total number of industry tiles, new and old
Definition: industry_type.h:35
bool IsFrontEngine() const
Check if the vehicle is a front engine.
Definition: vehicle_base.h:883
don&#39;t allow building on water
Definition: command_type.h:349
Owner owner
owner of the industry. Which SHOULD always be (imho) OWNER_NONE
Definition: industry.h:60
Defines the data structure for constructing industry.
Definition: industrytype.h:108
TerraGenesis Perlin landscape generator.
Definition: genworld.h:23
This structure is the same for both Industries and Houses.
Definition: sprite.h:69
static uint16 GetIndustryTypeCount(IndustryType type)
Get the count of industries for this type.
Definition: industry.h:150
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:1940
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:173
Industry should be positioned near edge of the map.
Definition: industrytype.h:44
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:57
static const DrawBuildingsTileStruct _industry_draw_tile_data[NEW_INDUSTRYTILEOFFSET *4]
Structure for industry tiles drawing.
Definition: industry_land.h:53
static const uint8 ANIM_STATUS_NO_ANIMATION
There is no animation.
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
16 input cargo slots
Definition: industry.h:51
Owner owner
Which company owns the vehicle?
Definition: vehicle_base.h:273
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:358
uint16 incoming_cargo_waiting[INDUSTRY_NUM_INPUTS]
incoming cargo waiting to be processed
Definition: industry.h:48
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:42
IndustryBehaviour behaviour
How this industry will behave, and how others entities can use it.
Definition: industrytype.h:126
byte prod_level
general production level
Definition: industry.h:50
byte appear_ingame[NUM_LANDSCAPE]
Probability of appearance in game.
Definition: industrytype.h:134
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:142
static bool IsWaterTile(TileIndex t)
Is it a water tile with plain water?
Definition: water_map.h:186
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:42
#define MAX_UVALUE(type)
The largest value that can be entered in a variable.
Definition: stdafx.h:471
static Foundation FlatteningFoundation(Slope s)
Returns the foundation needed to flatten a slope.
Definition: slope_func.h:371
static bool EconomyIsInRecession()
Is the economy in recession?
Definition: economy_func.h:49
decides accepted types
cuts trees and produce first output cargo from them (lumber mill)
Definition: industrytype.h:66
Data for managing the number of industries of a single industry type.
Definition: industry.h:176
uint DistanceFromEdgeDir(TileIndex tile, DiagDirection dir)
Gets the distance to the edge of the map in given direction.
Definition: map.cpp:236
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:44
uint32 StringID
Numeric value that represents a string, independent of the selected language.
Definition: strings_type.h:18
static bool AutoslopeEnabled()
Tests if autoslope is enabled for _current_company.
Definition: autoslope.h:46
NewGRF handling of industry tiles.
bool Failed() const
Did this command fail?
Definition: command_type.h:161
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:661
Transfer all cargo onto the platform.
Definition: order_type.h:57
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:35
controls monthly random production change
static void IncIndustryTypeCount(IndustryType type)
Increment the count of industries for this type.
Definition: industry.h:128
Base class for all pools.
Definition: pool_type.hpp:83
static T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition: math_func.hpp:139
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:25
OrderUnloadFlags GetUnloadType() const
How must the consist be unloaded?
Definition: order_base.h:131
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:116
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:169
bool IsTileForestIndustry(TileIndex tile)
Check whether the tile is a forest.
TileIndex tile
The base tile of the area.
Definition: tilearea_type.h:19
uint16 _tick_counter
Ever incrementing (and sometimes wrapping) tick counter for setting off various events.
Definition: date.cpp:30
uint64 dparam[2]
Parameters of the str string.
Definition: tile_cmd.h:64
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:138
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:226
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:1146
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:232
execute the given command
Definition: command_type.h:346
static bool CleaningPool()
Returns current state of pool cleaning - yes or no.
Definition: pool_type.hpp:225
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:158
The tile/execution is done by "water".
Definition: company_type.h:28
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:103
Tile got trees.
Definition: tile_type.h:47
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:94
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:83
bool _generating_world
Whether we are generating the map or not.
Definition: genworld.cpp:62
uint16 produced_cargo_waiting[INDUSTRY_NUM_OUTPUTS]
amount of cargo produced per cargo
Definition: industry.h:47
byte oil_refinery_limit
distance oil refineries allowed from map edge
DestinationID GetDestination() const
Gets the destination of this order.
Definition: order_base.h:96
during creation of random ingame industry
is built on water (oil rig)
Definition: industrytype.h:67
byte minimal_cargo
minimum amount of cargo transported to the stations.
Definition: industrytype.h:121
Invisible tiles at the SW and SE border.
Definition: tile_type.h:50
byte appear_creation[NUM_LANDSCAPE]
Probability of appearance during map creation.
Definition: industrytype.h:135
Production changes of industry serviced by local company.
Definition: news_type.h:31
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:19
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition: tile_map.cpp:143
static CargoSpec * Get(size_t index)
Retrieve cargo details for the given cargo ID.
Definition: cargotype.h:119
Set of callback functions for performing tile operations of a given tile type.
Definition: tile_cmd.h:147
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
Map accessors for &#39;clear&#39; tiles.
AnimationInfo animation
Information about the animation (is it looping, how many loops etc)
Definition: industrytype.h:170
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:276
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:581
void RecomputeProductionMultipliers()
Recompute production_rate for current prod_level.
static TreeGround GetTreeGround(TileIndex t)
Returns the groundtype for tree tiles.
Definition: tree_map.h:90
north and west corner are raised
Definition: slope_type.h:57
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:28
static IndustryID GetIndustryIndex(TileIndex t)
Get the industry ID of the given tile.
Definition: industry_map.h:65
StringID closure_text
Message appearing when the industry closes.
Definition: industrytype.h:130
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:217
Cheat magic_bulldozer
dynamite industries, objects
Definition: cheat_type.h:29
static void SetIndustryCompleted(TileIndex tile)
Set if the industry that owns the tile as under construction or not.
Definition: industry_map.h:90
byte anim_next
Next frame in an animation.
Definition: industrytype.h:162
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:151
static T abs(const T a)
Returns the absolute value of (scalar) variable.
Definition: math_func.hpp:83
Allow produced/accepted cargoes callbacks to supply more than 2 and 3 types.
Definition: industrytype.h:84
The tile has no foundation, the slope remains unchanged.
Definition: slope_type.h:96
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:21
static bool IsOilRig(TileIndex t)
Is tile t part of an oilrig?
Definition: station_map.h:276
Slope
Enumeration for the slope-type.
Definition: slope_type.h:50
VehicleType type
Type of vehicle.
Definition: vehicle_type.h:54
uint32 Next()
Generate the next pseudo random number.
Definition: random_func.cpp:33
A tile of a station.
Definition: tile_type.h:48
0-3
Definition: clear_map.h:26
Called to query the cargo acceptance of the industry tile.
TownCache cache
Container for all cacheable data.
Definition: town.h:58
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:113
#define endof(x)
Get the end element of an fixed size array.
Definition: stdafx.h:386
static void DecIndustryTypeCount(IndustryType type)
Decrement the count of industries for this type.
Definition: industry.h:139
call production callback when cargo arrives at the industry
Town data structure.
Definition: town.h:55
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:27
static const IndustryType NEW_INDUSTRYOFFSET
original number of industry types
Definition: industry_type.h:27
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:216
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:20
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:45
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:63
uint32 probability
Relative probability of building this industry.
Definition: industry.h:177
static void SetIndustryIndexOfField(TileIndex t, IndustryID i)
Set the industry (farm) that made the field.
Definition: clear_map.h:209
static uint16 counts[NUM_INDUSTRYTYPES]
Number of industries per type ingame.
Definition: industry.h:163
Owner founder
Founder of the industry.
Definition: industry.h:68
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
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:577
IndustryType conflicting[3]
Industries this industry cannot be close to.
Definition: industrytype.h:113
byte GetSnowLine()
Get the current snow line, either variable or static.
Definition: landscape.cpp:646
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:235
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:31
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:193
Fields are planted around when built (all farms)
Definition: industrytype.h:71
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:56
Allow closing down the last instance of this type.
Definition: industrytype.h:83
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:19
static TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition: map_func.h:181
Base of all industries.
const char * GetName() const
Get the name of this grf.
Aircraft vehicle type.
Definition: vehicle_type.h:29
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:817
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:131
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:136
void MonthlyLoop()
Monthly update of industry build data.
StringID str
Description of the tile.
Definition: tile_cmd.h:54
byte min_number
Smallest number of industries that should exist (either 0 or 1).
Definition: industry.h:178
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:97
StringID production_up_text
Message appearing when the industry&#39;s production is increasing.
Definition: industrytype.h:131
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.
#define FOR_ALL_VEHICLES(var)
Iterate over all vehicles.
Definition: vehicle_base.h:987
static const TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:85
static void SetClearCounter(TileIndex t, uint c)
Sets the counter used to advance to the next clear density/field type.
Definition: clear_map.h:146
Base of the town class.
byte check_proc
Index to a procedure to check for conflicting circumstances.
Definition: industrytype.h:114
Definition of one tile in an industry tile layout.
Definition: industrytype.h:97
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:242
Northeast, upper right on your monitor.
bool TileBelongsToIndustry(TileIndex tile) const
Check if a given tile belongs to this industry.
Definition: industry.h:88
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:43
A house by a town.
Definition: tile_type.h:46
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:22
Defines the data structure of each individual tile of an industry.
Definition: industrytype.h:157
static uint MapMaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition: map_func.h:104
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:61
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition: industry.h:115
Very few industries at game start.
Definition: settings_type.h:46
uint16 target_count
Desired number of industries of this type.
Definition: industry.h:179
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:56
Structure to encapsulate the pseudo random number generators.
Definition: random_func.hpp:23
town rating does not disallow you from building
Definition: command_type.h:351
byte industry_density
The industry density.
Definition: settings_type.h:58
static bool IsTileOnWater(TileIndex t)
Tests if the tile was built on water.
Definition: water_map.h:132
Production changes of industry serviced by competitor(s)
Definition: news_type.h:32
can only be built in towns larger than 1200 inhabitants (temperate bank)
Definition: industrytype.h:68
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:54
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:25
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:191
NewsType
Type of news.
Definition: news_type.h:23
Functions related to news.
The tile of the industry has been triggered during the tileloop.
Like forests.
Definition: industrytype.h:33
industries
Definition: transparency.h:28
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:28
static T Delta(const T a, const T b)
Returns the (absolute) difference between two (scalar) variables.
Definition: math_func.hpp:232
uint16 h
The height of the area.
Definition: tilearea_type.h:21
static void MakeIndustry(TileIndex t, IndustryID index, IndustryGfx gfx, uint8 random, WaterClass wc)
Make the given tile an industry tile.
Definition: industry_map.h:280
static const int INDUSTRY_PRODUCE_TICKS
cycle duration for industry production
Definition: date_type.h:38
can only be built before 1950 (oil wells)
Definition: industrytype.h:73
the south corner of the tile is raised
Definition: slope_type.h:53
static const IndustryGfx INDUSTRYTILE_NOANIM
flag to mark industry tiles as having no animation
Definition: industry_type.h:33
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:46
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:29
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:39
Class for backupping variables and making sure they are restored later.
Station data structure.
Definition: station_base.h:452
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:50
#define TILE_MASK(x)
&#39;Wraps&#39; the given tile to it is within the map.
Definition: map_func.h:28
Functions related to subsidies.
Used for industry tiles on land (also for oilrig if newgrf says so).
Definition: water_map.h:53
Road vehicle type.
Definition: vehicle_type.h:27
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:114
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:164
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:3300
byte HighestSnowLine()
Get the highest possible snow line height, either variable or static.
Definition: landscape.cpp:660
Source/destination is an industry.
Definition: cargo_type.h:149
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:167
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:51
Cheats _cheats
All the cheats.
Definition: cheat.cpp:18
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:306
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:201
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:26