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  memset(&_industry_specs, 0, sizeof(_industry_specs));
75  memcpy(&_industry_specs, &_origin_industry_specs, sizeof(_origin_industry_specs));
76 
77  /* once performed, enable only the current climate industries */
78  for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) {
79  _industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET &&
80  HasBit(_origin_industry_specs[i].climate_availability, _settings_game.game_creation.landscape);
81  }
82 
83  memset(&_industry_tile_specs, 0, sizeof(_industry_tile_specs));
84  memcpy(&_industry_tile_specs, &_origin_industry_tile_specs, sizeof(_origin_industry_tile_specs));
85 
86  /* Reset any overrides that have been set. */
87  _industile_mngr.ResetOverride();
88  _industry_mngr.ResetOverride();
89 }
90 
99 IndustryType GetIndustryType(TileIndex tile)
100 {
101  assert(IsTileType(tile, MP_INDUSTRY));
102 
103  const Industry *ind = Industry::GetByTile(tile);
104  assert(ind != NULL);
105  return ind->type;
106 }
107 
116 const IndustrySpec *GetIndustrySpec(IndustryType thistype)
117 {
118  assert(thistype < NUM_INDUSTRYTYPES);
119  return &_industry_specs[thistype];
120 }
121 
130 const IndustryTileSpec *GetIndustryTileSpec(IndustryGfx gfx)
131 {
132  assert(gfx < INVALID_INDUSTRYTILE);
133  return &_industry_tile_specs[gfx];
134 }
135 
136 Industry::~Industry()
137 {
138  if (CleaningPool()) return;
139 
140  /* Industry can also be destroyed when not fully initialized.
141  * This means that we do not have to clear tiles either.
142  * Also we must not decrement industry counts in that case. */
143  if (this->location.w == 0) return;
144 
145  TILE_AREA_LOOP(tile_cur, this->location) {
146  if (IsTileType(tile_cur, MP_INDUSTRY)) {
147  if (GetIndustryIndex(tile_cur) == this->index) {
148  DeleteNewGRFInspectWindow(GSF_INDUSTRYTILES, tile_cur);
149 
150  /* MakeWaterKeepingClass() can also handle 'land' */
151  MakeWaterKeepingClass(tile_cur, OWNER_NONE);
152  }
153  } else if (IsTileType(tile_cur, MP_STATION) && IsOilRig(tile_cur)) {
154  DeleteOilRig(tile_cur);
155  }
156  }
157 
158  if (GetIndustrySpec(this->type)->behaviour & INDUSTRYBEH_PLANT_FIELDS) {
159  TileArea ta(this->location.tile - TileDiffXY(min(TileX(this->location.tile), 21), min(TileY(this->location.tile), 21)), 42, 42);
160  ta.ClampToMap();
161 
162  /* Remove the farmland and convert it to regular tiles over time. */
163  TILE_AREA_LOOP(tile_cur, ta) {
164  if (IsTileType(tile_cur, MP_CLEAR) && IsClearGround(tile_cur, CLEAR_FIELDS) &&
165  GetIndustryIndexOfField(tile_cur) == this->index) {
166  SetIndustryIndexOfField(tile_cur, INVALID_INDUSTRY);
167  }
168  }
169  }
170 
171  /* don't let any disaster vehicle target invalid industry */
173 
174  /* Clear the persistent storage. */
175  delete this->psa;
176 
177  DecIndustryTypeCount(this->type);
178 
179  DeleteIndustryNews(this->index);
181  DeleteNewGRFInspectWindow(GSF_INDUSTRIES, this->index);
182 
185 }
186 
192 {
195 }
196 
197 
203 {
204  if (Industry::GetNumItems() == 0) return NULL;
205  int num = RandomRange((uint16)Industry::GetNumItems());
206  size_t index = MAX_UVALUE(size_t);
207 
208  while (num >= 0) {
209  num--;
210  index++;
211 
212  /* Make sure we have a valid industry */
213  while (!Industry::IsValidID(index)) {
214  index++;
215  assert(index < Industry::GetPoolSize());
216  }
217  }
218 
219  return Industry::Get(index);
220 }
221 
222 
223 static void IndustryDrawSugarMine(const TileInfo *ti)
224 {
225  if (!IsIndustryCompleted(ti->tile)) return;
226 
227  const DrawIndustryAnimationStruct *d = &_draw_industry_spec1[GetAnimationFrame(ti->tile)];
228 
229  AddChildSpriteScreen(SPR_IT_SUGAR_MINE_SIEVE + d->image_1, PAL_NONE, d->x, 0);
230 
231  if (d->image_2 != 0) {
232  AddChildSpriteScreen(SPR_IT_SUGAR_MINE_CLOUDS + d->image_2 - 1, PAL_NONE, 8, 41);
233  }
234 
235  if (d->image_3 != 0) {
236  AddChildSpriteScreen(SPR_IT_SUGAR_MINE_PILE + d->image_3 - 1, PAL_NONE,
237  _drawtile_proc1[d->image_3 - 1].x, _drawtile_proc1[d->image_3 - 1].y);
238  }
239 }
240 
241 static void IndustryDrawToffeeQuarry(const TileInfo *ti)
242 {
243  uint8 x = 0;
244 
245  if (IsIndustryCompleted(ti->tile)) {
246  x = _industry_anim_offs_toffee[GetAnimationFrame(ti->tile)];
247  if (x == 0xFF) {
248  x = 0;
249  }
250  }
251 
252  AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_SHOVEL, PAL_NONE, 22 - x, 24 + x);
253  AddChildSpriteScreen(SPR_IT_TOFFEE_QUARRY_TOFFEE, PAL_NONE, 6, 14);
254 }
255 
256 static void IndustryDrawBubbleGenerator( const TileInfo *ti)
257 {
258  if (IsIndustryCompleted(ti->tile)) {
259  AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_BUBBLE, PAL_NONE, 5, _industry_anim_offs_bubbles[GetAnimationFrame(ti->tile)]);
260  }
261  AddChildSpriteScreen(SPR_IT_BUBBLE_GENERATOR_SPRING, PAL_NONE, 3, 67);
262 }
263 
264 static void IndustryDrawToyFactory(const TileInfo *ti)
265 {
266  const DrawIndustryAnimationStruct *d = &_industry_anim_offs_toys[GetAnimationFrame(ti->tile)];
267 
268  if (d->image_1 != 0xFF) {
269  AddChildSpriteScreen(SPR_IT_TOY_FACTORY_CLAY, PAL_NONE, d->x, 96 + d->image_1);
270  }
271 
272  if (d->image_2 != 0xFF) {
273  AddChildSpriteScreen(SPR_IT_TOY_FACTORY_ROBOT, PAL_NONE, 16 - d->image_2 * 2, 100 + d->image_2);
274  }
275 
276  AddChildSpriteScreen(SPR_IT_TOY_FACTORY_STAMP, PAL_NONE, 7, d->image_3);
277  AddChildSpriteScreen(SPR_IT_TOY_FACTORY_STAMP_HOLDER, PAL_NONE, 0, 42);
278 }
279 
280 static void IndustryDrawCoalPlantSparks(const TileInfo *ti)
281 {
282  if (IsIndustryCompleted(ti->tile)) {
283  uint8 image = GetAnimationFrame(ti->tile);
284 
285  if (image != 0 && image < 7) {
286  AddChildSpriteScreen(image + SPR_IT_POWER_PLANT_TRANSFORMERS,
287  PAL_NONE,
288  _coal_plant_sparks[image - 1].x,
289  _coal_plant_sparks[image - 1].y
290  );
291  }
292  }
293 }
294 
295 typedef void IndustryDrawTileProc(const TileInfo *ti);
296 static IndustryDrawTileProc * const _industry_draw_tile_procs[5] = {
297  IndustryDrawSugarMine,
298  IndustryDrawToffeeQuarry,
299  IndustryDrawBubbleGenerator,
300  IndustryDrawToyFactory,
301  IndustryDrawCoalPlantSparks,
302 };
303 
304 static void DrawTile_Industry(TileInfo *ti)
305 {
306  IndustryGfx gfx = GetIndustryGfx(ti->tile);
307  Industry *ind = Industry::GetByTile(ti->tile);
308  const IndustryTileSpec *indts = GetIndustryTileSpec(gfx);
309 
310  /* Retrieve pointer to the draw industry tile struct */
311  if (gfx >= NEW_INDUSTRYTILEOFFSET) {
312  /* Draw the tile using the specialized method of newgrf industrytile.
313  * DrawNewIndustry will return false if ever the resolver could not
314  * find any sprite to display. So in this case, we will jump on the
315  * substitute gfx instead. */
316  if (indts->grf_prop.spritegroup[0] != NULL && DrawNewIndustryTile(ti, ind, gfx, indts)) {
317  return;
318  } else {
319  /* No sprite group (or no valid one) found, meaning no graphics associated.
320  * Use the substitute one instead */
321  if (indts->grf_prop.subst_id != INVALID_INDUSTRYTILE) {
322  gfx = indts->grf_prop.subst_id;
323  /* And point the industrytile spec accordingly */
324  indts = GetIndustryTileSpec(gfx);
325  }
326  }
327  }
328 
329  const DrawBuildingsTileStruct *dits = &_industry_draw_tile_data[gfx << 2 | (indts->anim_state ?
332 
333  SpriteID image = dits->ground.sprite;
334 
335  /* DrawFoundation() modifies ti->z and ti->tileh */
337 
338  /* If the ground sprite is the default flat water sprite, draw also canal/river borders.
339  * Do not do this if the tile's WaterClass is 'land'. */
340  if (image == SPR_FLAT_WATER_TILE && IsTileOnWater(ti->tile)) {
341  DrawWaterClassGround(ti);
342  } else {
343  DrawGroundSprite(image, GroundSpritePaletteTransform(image, dits->ground.pal, GENERAL_SPRITE_COLOUR(ind->random_colour)));
344  }
345 
346  /* If industries are transparent and invisible, do not draw the upper part */
347  if (IsInvisibilitySet(TO_INDUSTRIES)) return;
348 
349  /* Add industry on top of the ground? */
350  image = dits->building.sprite;
351  if (image != 0) {
352  AddSortableSpriteToDraw(image, SpriteLayoutPaletteTransform(image, dits->building.pal, GENERAL_SPRITE_COLOUR(ind->random_colour)),
353  ti->x + dits->subtile_x,
354  ti->y + dits->subtile_y,
355  dits->width,
356  dits->height,
357  dits->dz,
358  ti->z,
360 
361  if (IsTransparencySet(TO_INDUSTRIES)) return;
362  }
363 
364  {
365  int proc = dits->draw_proc - 1;
366  if (proc >= 0) _industry_draw_tile_procs[proc](ti);
367  }
368 }
369 
370 static int GetSlopePixelZ_Industry(TileIndex tile, uint x, uint y)
371 {
372  return GetTileMaxPixelZ(tile);
373 }
374 
375 static Foundation GetFoundation_Industry(TileIndex tile, Slope tileh)
376 {
377  IndustryGfx gfx = GetIndustryGfx(tile);
378 
379  /* For NewGRF industry tiles we might not be drawing a foundation. We need to
380  * account for this, as other structures should
381  * draw the wall of the foundation in this case.
382  */
383  if (gfx >= NEW_INDUSTRYTILEOFFSET) {
384  const IndustryTileSpec *indts = GetIndustryTileSpec(gfx);
385  if (indts->grf_prop.spritegroup[0] != NULL && HasBit(indts->callback_mask, CBM_INDT_DRAW_FOUNDATIONS)) {
386  uint32 callback_res = GetIndustryTileCallback(CBID_INDTILE_DRAW_FOUNDATIONS, 0, 0, gfx, Industry::GetByTile(tile), tile);
387  if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(indts->grf_prop.grffile, CBID_INDTILE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE;
388  }
389  }
390  return FlatteningFoundation(tileh);
391 }
392 
393 static void AddAcceptedCargo_Industry(TileIndex tile, CargoArray &acceptance, CargoTypes *always_accepted)
394 {
395  IndustryGfx gfx = GetIndustryGfx(tile);
396  const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
397  const Industry *ind = Industry::GetByTile(tile);
398 
399  /* Starting point for acceptance */
401  int8 cargo_acceptance[lengthof(itspec->acceptance)];
402  MemCpyT(accepts_cargo, itspec->accepts_cargo, lengthof(accepts_cargo));
403  MemCpyT(cargo_acceptance, itspec->acceptance, lengthof(cargo_acceptance));
404 
406  /* Copy all accepted cargoes from industry itself */
407  for (uint i = 0; i < lengthof(ind->accepts_cargo); i++) {
408  CargoID *pos = std::find(accepts_cargo, endof(accepts_cargo), ind->accepts_cargo[i]);
409  if (pos == endof(accepts_cargo)) {
410  /* Not found, insert */
411  pos = std::find(accepts_cargo, endof(accepts_cargo), CT_INVALID);
412  if (pos == endof(accepts_cargo)) continue; // nowhere to place, give up on this one
413  *pos = ind->accepts_cargo[i];
414  }
415  cargo_acceptance[pos - accepts_cargo] += 8;
416  }
417  }
418 
420  /* Try callback for accepts list, if success override all existing accepts */
421  uint16 res = GetIndustryTileCallback(CBID_INDTILE_ACCEPT_CARGO, 0, 0, gfx, Industry::GetByTile(tile), tile);
422  if (res != CALLBACK_FAILED) {
423  MemSetT(accepts_cargo, CT_INVALID, lengthof(accepts_cargo));
424  for (uint i = 0; i < 3; i++) accepts_cargo[i] = GetCargoTranslation(GB(res, i * 5, 5), itspec->grf_prop.grffile);
425  }
426  }
427 
429  /* Try callback for acceptance list, if success override all existing acceptance */
430  uint16 res = GetIndustryTileCallback(CBID_INDTILE_CARGO_ACCEPTANCE, 0, 0, gfx, Industry::GetByTile(tile), tile);
431  if (res != CALLBACK_FAILED) {
432  MemSetT(cargo_acceptance, 0, lengthof(cargo_acceptance));
433  for (uint i = 0; i < 3; i++) cargo_acceptance[i] = GB(res, i * 4, 4);
434  }
435  }
436 
437  for (byte i = 0; i < lengthof(itspec->accepts_cargo); i++) {
438  CargoID a = accepts_cargo[i];
439  if (a == CT_INVALID || cargo_acceptance[i] <= 0) continue; // work only with valid cargoes
440 
441  /* Add accepted cargo */
442  acceptance[a] += cargo_acceptance[i];
443 
444  /* Maybe set 'always accepted' bit (if it's not set already) */
445  if (HasBit(*always_accepted, a)) continue;
446 
447  bool accepts = false;
448  for (uint cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
449  /* Test whether the industry itself accepts the cargo type */
450  if (ind->accepts_cargo[cargo_index] == a) {
451  accepts = true;
452  break;
453  }
454  }
455 
456  if (accepts) continue;
457 
458  /* If the industry itself doesn't accept this cargo, set 'always accepted' bit */
459  SetBit(*always_accepted, a);
460  }
461 }
462 
463 static void GetTileDesc_Industry(TileIndex tile, TileDesc *td)
464 {
465  const Industry *i = Industry::GetByTile(tile);
466  const IndustrySpec *is = GetIndustrySpec(i->type);
467 
468  td->owner[0] = i->owner;
469  td->str = is->name;
470  if (!IsIndustryCompleted(tile)) {
471  SetDParamX(td->dparam, 0, td->str);
472  td->str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
473  }
474 
475  if (is->grf_prop.grffile != NULL) {
476  td->grf = GetGRFConfig(is->grf_prop.grffile->grfid)->GetName();
477  }
478 }
479 
480 static CommandCost ClearTile_Industry(TileIndex tile, DoCommandFlag flags)
481 {
482  Industry *i = Industry::GetByTile(tile);
483  const IndustrySpec *indspec = GetIndustrySpec(i->type);
484 
485  /* water can destroy industries
486  * in editor you can bulldoze industries
487  * with magic_bulldozer cheat you can destroy industries
488  * (area around OILRIG is water, so water shouldn't flood it
489  */
490  if ((_current_company != OWNER_WATER && _game_mode != GM_EDITOR &&
492  ((flags & DC_AUTO) != 0) ||
494  ((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) ||
495  HasBit(GetIndustryTileSpec(GetIndustryGfx(tile))->slopes_refused, 5)))) {
496  SetDParam(1, indspec->name);
497  return_cmd_error(flags & DC_AUTO ? STR_ERROR_GENERIC_OBJECT_IN_THE_WAY : INVALID_STRING_ID);
498  }
499 
500  if (flags & DC_EXEC) {
501  AI::BroadcastNewEvent(new ScriptEventIndustryClose(i->index));
502  Game::NewEvent(new ScriptEventIndustryClose(i->index));
503  delete i;
504  }
506 }
507 
514 {
515  Industry *i = Industry::GetByTile(tile);
516  const IndustrySpec *indspec = GetIndustrySpec(i->type);
517  bool moved_cargo = false;
518 
519  StationFinder stations(i->location);
520 
521  for (uint j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
522  uint cw = min(i->produced_cargo_waiting[j], 255);
523  if (cw > indspec->minimal_cargo && i->produced_cargo[j] != CT_INVALID) {
524  i->produced_cargo_waiting[j] -= cw;
525 
526  /* fluctuating economy? */
527  if (EconomyIsInRecession()) cw = (cw + 1) / 2;
528 
529  i->this_month_production[j] += cw;
530 
531  uint am = MoveGoodsToStation(i->produced_cargo[j], cw, ST_INDUSTRY, i->index, stations.GetStations());
532  i->this_month_transported[j] += am;
533 
534  moved_cargo |= (am != 0);
535  }
536  }
537 
538  return moved_cargo;
539 }
540 
541 
542 static void AnimateTile_Industry(TileIndex tile)
543 {
544  IndustryGfx gfx = GetIndustryGfx(tile);
545 
546  if (GetIndustryTileSpec(gfx)->animation.status != ANIM_STATUS_NO_ANIMATION) {
547  AnimateNewIndustryTile(tile);
548  return;
549  }
550 
551  switch (gfx) {
552  case GFX_SUGAR_MINE_SIEVE:
553  if ((_tick_counter & 1) == 0) {
554  byte m = GetAnimationFrame(tile) + 1;
555 
557  switch (m & 7) {
558  case 2: SndPlayTileFx(SND_2D_RIP_2, tile); break;
559  case 6: SndPlayTileFx(SND_29_RIP, tile); break;
560  }
561  }
562 
563  if (m >= 96) {
564  m = 0;
565  DeleteAnimatedTile(tile);
566  }
567  SetAnimationFrame(tile, m);
568 
569  MarkTileDirtyByTile(tile);
570  }
571  break;
572 
573  case GFX_TOFFEE_QUARY:
574  if ((_tick_counter & 3) == 0) {
575  byte m = GetAnimationFrame(tile);
576 
577  if (_industry_anim_offs_toffee[m] == 0xFF && _settings_client.sound.ambient) {
578  SndPlayTileFx(SND_30_CARTOON_SOUND, tile);
579  }
580 
581  if (++m >= 70) {
582  m = 0;
583  DeleteAnimatedTile(tile);
584  }
585  SetAnimationFrame(tile, m);
586 
587  MarkTileDirtyByTile(tile);
588  }
589  break;
590 
591  case GFX_BUBBLE_CATCHER:
592  if ((_tick_counter & 1) == 0) {
593  byte m = GetAnimationFrame(tile);
594 
595  if (++m >= 40) {
596  m = 0;
597  DeleteAnimatedTile(tile);
598  }
599  SetAnimationFrame(tile, m);
600 
601  MarkTileDirtyByTile(tile);
602  }
603  break;
604 
605  /* Sparks on a coal plant */
606  case GFX_POWERPLANT_SPARKS:
607  if ((_tick_counter & 3) == 0) {
608  byte m = GetAnimationFrame(tile);
609  if (m == 6) {
610  SetAnimationFrame(tile, 0);
611  DeleteAnimatedTile(tile);
612  } else {
613  SetAnimationFrame(tile, m + 1);
614  MarkTileDirtyByTile(tile);
615  }
616  }
617  break;
618 
619  case GFX_TOY_FACTORY:
620  if ((_tick_counter & 1) == 0) {
621  byte m = GetAnimationFrame(tile) + 1;
622 
623  switch (m) {
624  case 1: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2C_MACHINERY, tile); break;
625  case 23: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2B_COMEDY_HIT, tile); break;
626  case 28: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2A_EXTRACT_AND_POP, tile); break;
627  default:
628  if (m >= 50) {
629  int n = GetIndustryAnimationLoop(tile) + 1;
630  m = 0;
631  if (n >= 8) {
632  n = 0;
633  DeleteAnimatedTile(tile);
634  }
635  SetIndustryAnimationLoop(tile, n);
636  }
637  }
638 
639  SetAnimationFrame(tile, m);
640  MarkTileDirtyByTile(tile);
641  }
642  break;
643 
644  case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
645  case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
646  case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
647  case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
648  if ((_tick_counter & 3) == 0) {
649  IndustryGfx gfx = GetIndustryGfx(tile);
650 
651  gfx = (gfx < 155) ? gfx + 1 : 148;
652  SetIndustryGfx(tile, gfx);
653  MarkTileDirtyByTile(tile);
654  }
655  break;
656 
657  case GFX_OILWELL_ANIMATED_1:
658  case GFX_OILWELL_ANIMATED_2:
659  case GFX_OILWELL_ANIMATED_3:
660  if ((_tick_counter & 7) == 0) {
661  bool b = Chance16(1, 7);
662  IndustryGfx gfx = GetIndustryGfx(tile);
663 
664  byte m = GetAnimationFrame(tile) + 1;
665  if (m == 4 && (m = 0, ++gfx) == GFX_OILWELL_ANIMATED_3 + 1 && (gfx = GFX_OILWELL_ANIMATED_1, b)) {
666  SetIndustryGfx(tile, GFX_OILWELL_NOT_ANIMATED);
668  DeleteAnimatedTile(tile);
669  } else {
670  SetAnimationFrame(tile, m);
671  SetIndustryGfx(tile, gfx);
672  MarkTileDirtyByTile(tile);
673  }
674  }
675  break;
676 
677  case GFX_COAL_MINE_TOWER_ANIMATED:
678  case GFX_COPPER_MINE_TOWER_ANIMATED:
679  case GFX_GOLD_MINE_TOWER_ANIMATED: {
680  int state = _tick_counter & 0x7FF;
681 
682  if ((state -= 0x400) < 0) return;
683 
684  if (state < 0x1A0) {
685  if (state < 0x20 || state >= 0x180) {
686  byte m = GetAnimationFrame(tile);
687  if (!(m & 0x40)) {
688  SetAnimationFrame(tile, m | 0x40);
689  if (_settings_client.sound.ambient) SndPlayTileFx(SND_0B_MINING_MACHINERY, tile);
690  }
691  if (state & 7) return;
692  } else {
693  if (state & 3) return;
694  }
695  byte m = (GetAnimationFrame(tile) + 1) | 0x40;
696  if (m > 0xC2) m = 0xC0;
697  SetAnimationFrame(tile, m);
698  MarkTileDirtyByTile(tile);
699  } else if (state >= 0x200 && state < 0x3A0) {
700  int i = (state < 0x220 || state >= 0x380) ? 7 : 3;
701  if (state & i) return;
702 
703  byte m = (GetAnimationFrame(tile) & 0xBF) - 1;
704  if (m < 0x80) m = 0x82;
705  SetAnimationFrame(tile, m);
706  MarkTileDirtyByTile(tile);
707  }
708  break;
709  }
710  }
711 }
712 
713 static void CreateChimneySmoke(TileIndex tile)
714 {
715  uint x = TileX(tile) * TILE_SIZE;
716  uint y = TileY(tile) * TILE_SIZE;
717  int z = GetTileMaxPixelZ(tile);
718 
719  CreateEffectVehicle(x + 15, y + 14, z + 59, EV_CHIMNEY_SMOKE);
720 }
721 
722 static void MakeIndustryTileBigger(TileIndex tile)
723 {
724  byte cnt = GetIndustryConstructionCounter(tile) + 1;
725  if (cnt != 4) {
727  return;
728  }
729 
730  byte stage = GetIndustryConstructionStage(tile) + 1;
732  SetIndustryConstructionStage(tile, stage);
733  StartStopIndustryTileAnimation(tile, IAT_CONSTRUCTION_STATE_CHANGE);
734  if (stage == INDUSTRY_COMPLETED) SetIndustryCompleted(tile);
735 
736  MarkTileDirtyByTile(tile);
737 
738  if (!IsIndustryCompleted(tile)) return;
739 
740  IndustryGfx gfx = GetIndustryGfx(tile);
741  if (gfx >= NEW_INDUSTRYTILEOFFSET) {
742  /* New industries are already animated on construction. */
743  return;
744  }
745 
746  switch (gfx) {
747  case GFX_POWERPLANT_CHIMNEY:
748  CreateChimneySmoke(tile);
749  break;
750 
751  case GFX_OILRIG_1: {
752  /* Do not require an industry tile to be after the first two GFX_OILRIG_1
753  * tiles (like the default oil rig). Do a proper check to ensure the
754  * tiles belong to the same industry and based on that build the oil rig's
755  * station. */
756  TileIndex other = tile + TileDiffXY(0, 1);
757 
758  if (IsTileType(other, MP_INDUSTRY) &&
759  GetIndustryGfx(other) == GFX_OILRIG_1 &&
760  GetIndustryIndex(tile) == GetIndustryIndex(other)) {
761  BuildOilRig(tile);
762  }
763  break;
764  }
765 
766  case GFX_TOY_FACTORY:
767  case GFX_BUBBLE_CATCHER:
768  case GFX_TOFFEE_QUARY:
769  SetAnimationFrame(tile, 0);
770  SetIndustryAnimationLoop(tile, 0);
771  break;
772 
773  case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
774  case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
775  case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
776  case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
777  AddAnimatedTile(tile);
778  break;
779  }
780 }
781 
782 static void TileLoopIndustry_BubbleGenerator(TileIndex tile)
783 {
784  static const int8 _bubble_spawn_location[3][4] = {
785  { 11, 0, -4, -14 },
786  { -4, -10, -4, 1 },
787  { 49, 59, 60, 65 },
788  };
789 
790  if (_settings_client.sound.ambient) SndPlayTileFx(SND_2E_EXTRACT_AND_POP, tile);
791 
792  int dir = Random() & 3;
793 
795  TileX(tile) * TILE_SIZE + _bubble_spawn_location[0][dir],
796  TileY(tile) * TILE_SIZE + _bubble_spawn_location[1][dir],
797  _bubble_spawn_location[2][dir],
798  EV_BUBBLE
799  );
800 
801  if (v != NULL) v->animation_substate = dir;
802 }
803 
804 static void TileLoop_Industry(TileIndex tile)
805 {
806  if (IsTileOnWater(tile)) TileLoop_Water(tile);
807 
808  /* Normally this doesn't happen, but if an industry NewGRF is removed
809  * an industry that was previously build on water can now be flooded.
810  * If this happens the tile is no longer an industry tile after
811  * returning from TileLoop_Water. */
812  if (!IsTileType(tile, MP_INDUSTRY)) return;
813 
815 
816  if (!IsIndustryCompleted(tile)) {
817  MakeIndustryTileBigger(tile);
818  return;
819  }
820 
821  if (_game_mode == GM_EDITOR) return;
822 
823  if (TransportIndustryGoods(tile) && !StartStopIndustryTileAnimation(Industry::GetByTile(tile), IAT_INDUSTRY_DISTRIBUTES_CARGO)) {
824  uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production;
825 
826  if (newgfx != INDUSTRYTILE_NOANIM) {
828  SetIndustryCompleted(tile);
829  SetIndustryGfx(tile, newgfx);
830  MarkTileDirtyByTile(tile);
831  return;
832  }
833  }
834 
835  if (StartStopIndustryTileAnimation(tile, IAT_TILELOOP)) return;
836 
837  IndustryGfx newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_next;
838  if (newgfx != INDUSTRYTILE_NOANIM) {
840  SetIndustryGfx(tile, newgfx);
841  MarkTileDirtyByTile(tile);
842  return;
843  }
844 
845  IndustryGfx gfx = GetIndustryGfx(tile);
846  switch (gfx) {
847  case GFX_COAL_MINE_TOWER_NOT_ANIMATED:
848  case GFX_COPPER_MINE_TOWER_NOT_ANIMATED:
849  case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:
850  if (!(_tick_counter & 0x400) && Chance16(1, 2)) {
851  switch (gfx) {
852  case GFX_COAL_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COAL_MINE_TOWER_ANIMATED; break;
853  case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_ANIMATED; break;
854  case GFX_GOLD_MINE_TOWER_NOT_ANIMATED: gfx = GFX_GOLD_MINE_TOWER_ANIMATED; break;
855  }
856  SetIndustryGfx(tile, gfx);
857  SetAnimationFrame(tile, 0x80);
858  AddAnimatedTile(tile);
859  }
860  break;
861 
862  case GFX_OILWELL_NOT_ANIMATED:
863  if (Chance16(1, 6)) {
864  SetIndustryGfx(tile, GFX_OILWELL_ANIMATED_1);
865  SetAnimationFrame(tile, 0);
866  AddAnimatedTile(tile);
867  }
868  break;
869 
870  case GFX_COAL_MINE_TOWER_ANIMATED:
871  case GFX_COPPER_MINE_TOWER_ANIMATED:
872  case GFX_GOLD_MINE_TOWER_ANIMATED:
873  if (!(_tick_counter & 0x400)) {
874  switch (gfx) {
875  case GFX_COAL_MINE_TOWER_ANIMATED: gfx = GFX_COAL_MINE_TOWER_NOT_ANIMATED; break;
876  case GFX_COPPER_MINE_TOWER_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_NOT_ANIMATED; break;
877  case GFX_GOLD_MINE_TOWER_ANIMATED: gfx = GFX_GOLD_MINE_TOWER_NOT_ANIMATED; break;
878  }
879  SetIndustryGfx(tile, gfx);
880  SetIndustryCompleted(tile);
882  DeleteAnimatedTile(tile);
883  }
884  break;
885 
886  case GFX_POWERPLANT_SPARKS:
887  if (Chance16(1, 3)) {
888  if (_settings_client.sound.ambient) SndPlayTileFx(SND_0C_ELECTRIC_SPARK, tile);
889  AddAnimatedTile(tile);
890  }
891  break;
892 
893  case GFX_COPPER_MINE_CHIMNEY:
895  break;
896 
897 
898  case GFX_TOY_FACTORY: {
899  Industry *i = Industry::GetByTile(tile);
900  if (i->was_cargo_delivered) {
901  i->was_cargo_delivered = false;
902  SetIndustryAnimationLoop(tile, 0);
903  AddAnimatedTile(tile);
904  }
905  }
906  break;
907 
908  case GFX_BUBBLE_GENERATOR:
909  TileLoopIndustry_BubbleGenerator(tile);
910  break;
911 
912  case GFX_TOFFEE_QUARY:
913  AddAnimatedTile(tile);
914  break;
915 
916  case GFX_SUGAR_MINE_SIEVE:
917  if (Chance16(1, 3)) AddAnimatedTile(tile);
918  break;
919  }
920 }
921 
922 static bool ClickTile_Industry(TileIndex tile)
923 {
924  ShowIndustryViewWindow(GetIndustryIndex(tile));
925  return true;
926 }
927 
928 static TrackStatus GetTileTrackStatus_Industry(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
929 {
930  return 0;
931 }
932 
933 static void ChangeTileOwner_Industry(TileIndex tile, Owner old_owner, Owner new_owner)
934 {
935  /* If the founder merges, the industry was created by the merged company */
936  Industry *i = Industry::GetByTile(tile);
937  if (i->founder == old_owner) i->founder = (new_owner == INVALID_OWNER) ? OWNER_NONE : new_owner;
938 }
939 
946 {
947  /* Check for industry tile */
948  if (!IsTileType(tile, MP_INDUSTRY)) return false;
949 
950  const Industry *ind = Industry::GetByTile(tile);
951 
952  /* Check for organic industry (i.e. not processing or extractive) */
953  if ((GetIndustrySpec(ind->type)->life_type & INDUSTRYLIFE_ORGANIC) == 0) return false;
954 
955  /* Check for wood production */
956  for (uint i = 0; i < lengthof(ind->produced_cargo); i++) {
957  /* The industry produces wood. */
958  if (ind->produced_cargo[i] != CT_INVALID && CargoSpec::Get(ind->produced_cargo[i])->label == 'WOOD') return true;
959  }
960 
961  return false;
962 }
963 
964 static const byte _plantfarmfield_type[] = {1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
965 
973 static bool IsSuitableForFarmField(TileIndex tile, bool allow_fields)
974 {
975  switch (GetTileType(tile)) {
976  case MP_CLEAR: return !IsClearGround(tile, CLEAR_SNOW) && !IsClearGround(tile, CLEAR_DESERT) && (allow_fields || !IsClearGround(tile, CLEAR_FIELDS));
977  case MP_TREES: return GetTreeGround(tile) != TREE_GROUND_SHORE;
978  default: return false;
979  }
980 }
981 
989 static void SetupFarmFieldFence(TileIndex tile, int size, byte type, DiagDirection side)
990 {
991  TileIndexDiff diff = (DiagDirToAxis(side) == AXIS_Y ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
992 
993  do {
994  tile = TILE_MASK(tile);
995 
996  if (IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS)) {
997  byte or_ = type;
998 
999  if (or_ == 1 && Chance16(1, 7)) or_ = 2;
1000 
1001  SetFence(tile, side, or_);
1002  }
1003 
1004  tile += diff;
1005  } while (--size);
1006 }
1007 
1008 static void PlantFarmField(TileIndex tile, IndustryID industry)
1009 {
1010  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
1011  if (GetTileZ(tile) + 2 >= GetSnowLine()) return;
1012  }
1013 
1014  /* determine field size */
1015  uint32 r = (Random() & 0x303) + 0x404;
1016  if (_settings_game.game_creation.landscape == LT_ARCTIC) r += 0x404;
1017  uint size_x = GB(r, 0, 8);
1018  uint size_y = GB(r, 8, 8);
1019 
1020  TileArea ta(tile - TileDiffXY(min(TileX(tile), size_x / 2), min(TileY(tile), size_y / 2)), size_x, size_y);
1021  ta.ClampToMap();
1022 
1023  if (ta.w == 0 || ta.h == 0) return;
1024 
1025  /* check the amount of bad tiles */
1026  int count = 0;
1027  TILE_AREA_LOOP(cur_tile, ta) {
1028  assert(cur_tile < MapSize());
1029  count += IsSuitableForFarmField(cur_tile, false);
1030  }
1031  if (count * 2 < ta.w * ta.h) return;
1032 
1033  /* determine type of field */
1034  r = Random();
1035  uint counter = GB(r, 5, 3);
1036  uint field_type = GB(r, 8, 8) * 9 >> 8;
1037 
1038  /* make field */
1039  TILE_AREA_LOOP(cur_tile, ta) {
1040  assert(cur_tile < MapSize());
1041  if (IsSuitableForFarmField(cur_tile, true)) {
1042  MakeField(cur_tile, field_type, industry);
1043  SetClearCounter(cur_tile, counter);
1044  MarkTileDirtyByTile(cur_tile);
1045  }
1046  }
1047 
1048  int type = 3;
1049  if (_settings_game.game_creation.landscape != LT_ARCTIC && _settings_game.game_creation.landscape != LT_TROPIC) {
1050  type = _plantfarmfield_type[Random() & 0xF];
1051  }
1052 
1053  SetupFarmFieldFence(ta.tile, ta.h, type, DIAGDIR_NE);
1054  SetupFarmFieldFence(ta.tile, ta.w, type, DIAGDIR_NW);
1055  SetupFarmFieldFence(ta.tile + TileDiffXY(ta.w - 1, 0), ta.h, type, DIAGDIR_SW);
1056  SetupFarmFieldFence(ta.tile + TileDiffXY(0, ta.h - 1), ta.w, type, DIAGDIR_SE);
1057 }
1058 
1059 void PlantRandomFarmField(const Industry *i)
1060 {
1061  int x = i->location.w / 2 + Random() % 31 - 16;
1062  int y = i->location.h / 2 + Random() % 31 - 16;
1063 
1064  TileIndex tile = TileAddWrap(i->location.tile, x, y);
1065 
1066  if (tile != INVALID_TILE) PlantFarmField(tile, i->index);
1067 }
1068 
1075 static bool SearchLumberMillTrees(TileIndex tile, void *user_data)
1076 {
1077  if (IsTileType(tile, MP_TREES) && GetTreeGrowth(tile) > 2) {
1078  /* found a tree */
1079 
1080  Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
1081 
1082  _industry_sound_ctr = 1;
1083  _industry_sound_tile = tile;
1084  if (_settings_client.sound.ambient) SndPlayTileFx(SND_38_CHAINSAW, tile);
1085 
1086  DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
1087 
1088  cur_company.Restore();
1089  return true;
1090  }
1091  return false;
1092 }
1093 
1099 {
1100  /* We only want to cut trees if all tiles are completed. */
1101  TILE_AREA_LOOP(tile_cur, i->location) {
1102  if (i->TileBelongsToIndustry(tile_cur)) {
1103  if (!IsIndustryCompleted(tile_cur)) return;
1104  }
1105  }
1106 
1107  TileIndex tile = i->location.tile;
1108  if (CircularTileSearch(&tile, 40, SearchLumberMillTrees, NULL)) { // 40x40 tiles to search.
1109  i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + 45); // Found a tree, add according value to waiting cargo.
1110  }
1111 }
1112 
1113 static void ProduceIndustryGoods(Industry *i)
1114 {
1115  const IndustrySpec *indsp = GetIndustrySpec(i->type);
1116 
1117  /* play a sound? */
1118  if ((i->counter & 0x3F) == 0) {
1119  uint32 r;
1120  uint num;
1121  if (Chance16R(1, 14, r) && (num = indsp->number_of_sounds) != 0 && _settings_client.sound.ambient) {
1122  SndPlayTileFx(
1123  (SoundFx)(indsp->random_sounds[((r >> 16) * num) >> 16]),
1124  i->location.tile);
1125  }
1126  }
1127 
1128  i->counter--;
1129 
1130  /* produce some cargo */
1131  if ((i->counter % INDUSTRY_PRODUCE_TICKS) == 0) {
1133 
1134  IndustryBehaviour indbehav = indsp->behaviour;
1135  for (size_t j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
1136  i->produced_cargo_waiting[j] = min(0xffff, i->produced_cargo_waiting[j] + i->production_rate[j]);
1137  }
1138 
1139  if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
1140  uint16 cb_res = CALLBACK_FAILED;
1142  cb_res = GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 0, i, i->type, i->location.tile);
1143  }
1144 
1145  bool plant;
1146  if (cb_res != CALLBACK_FAILED) {
1148  } else {
1149  plant = Chance16(1, 8);
1150  }
1151 
1152  if (plant) PlantRandomFarmField(i);
1153  }
1154  if ((indbehav & INDUSTRYBEH_CUT_TREES) != 0) {
1155  uint16 cb_res = CALLBACK_FAILED;
1157  cb_res = GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 1, i, i->type, i->location.tile);
1158  }
1159 
1160  bool cut;
1161  if (cb_res != CALLBACK_FAILED) {
1163  } else {
1164  cut = ((i->counter % INDUSTRY_CUT_TREE_TICKS) == 0);
1165  }
1166 
1167  if (cut) ChopLumberMillTrees(i);
1168  }
1169 
1171  StartStopIndustryTileAnimation(i, IAT_INDUSTRY_TICK);
1172  }
1173 }
1174 
1175 void OnTick_Industry()
1176 {
1177  if (_industry_sound_ctr != 0) {
1178  _industry_sound_ctr++;
1179 
1180  if (_industry_sound_ctr == 75) {
1181  if (_settings_client.sound.ambient) SndPlayTileFx(SND_37_BALLOON_SQUEAK, _industry_sound_tile);
1182  } else if (_industry_sound_ctr == 160) {
1183  _industry_sound_ctr = 0;
1184  if (_settings_client.sound.ambient) SndPlayTileFx(SND_36_CARTOON_CRASH, _industry_sound_tile);
1185  }
1186  }
1187 
1188  if (_game_mode == GM_EDITOR) return;
1189 
1190  Industry *i;
1191  FOR_ALL_INDUSTRIES(i) {
1192  ProduceIndustryGoods(i);
1193  }
1194 }
1195 
1202 {
1203  return CommandCost();
1204 }
1205 
1212 {
1213  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
1214  if (GetTileZ(tile) < HighestSnowLine() + 2) {
1215  return_cmd_error(STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED);
1216  }
1217  }
1218  return CommandCost();
1219 }
1220 
1227 {
1228  if (_game_mode == GM_EDITOR) return CommandCost();
1230 
1231  return_cmd_error(STR_ERROR_CAN_ONLY_BE_POSITIONED);
1232 }
1233 
1234 extern bool _ignore_restrictions;
1235 
1242 {
1243  if (_game_mode == GM_EDITOR && _ignore_restrictions) return CommandCost();
1244  if (TileHeight(tile) == 0 &&
1246 
1247  return_cmd_error(STR_ERROR_CAN_ONLY_BE_POSITIONED);
1248 }
1249 
1256 {
1257  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
1258  if (GetTileZ(tile) + 2 >= HighestSnowLine()) {
1259  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1260  }
1261  }
1262  return CommandCost();
1263 }
1264 
1271 {
1272  if (GetTropicZone(tile) == TROPICZONE_DESERT) {
1273  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1274  }
1275  return CommandCost();
1276 }
1277 
1284 {
1285  if (GetTropicZone(tile) != TROPICZONE_DESERT) {
1286  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT);
1287  }
1288  return CommandCost();
1289 }
1290 
1297 {
1298  if (GetTropicZone(tile) != TROPICZONE_RAINFOREST) {
1299  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST);
1300  }
1301  return CommandCost();
1302 }
1303 
1310 {
1311  if (GetTileZ(tile) > 4) {
1312  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_LOW_AREAS);
1313  }
1314  return CommandCost();
1315 }
1316 
1323 
1335 };
1336 
1348 {
1349  *t = ClosestTownFromTile(tile, UINT_MAX);
1350 
1352 
1353  const Industry *i;
1354  FOR_ALL_INDUSTRIES(i) {
1355  if (i->type == (byte)type && i->town == *t) {
1356  *t = NULL;
1357  return_cmd_error(STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN);
1358  }
1359  }
1360 
1361  return CommandCost();
1362 }
1363 
1364 bool IsSlopeRefused(Slope current, Slope refused)
1365 {
1366  if (IsSteepSlope(current)) return true;
1367  if (current != SLOPE_FLAT) {
1368  if (IsSteepSlope(refused)) return true;
1369 
1370  Slope t = ComplementSlope(current);
1371 
1372  if ((refused & SLOPE_W) && (t & SLOPE_NW)) return true;
1373  if ((refused & SLOPE_S) && (t & SLOPE_NE)) return true;
1374  if ((refused & SLOPE_E) && (t & SLOPE_SW)) return true;
1375  if ((refused & SLOPE_N) && (t & SLOPE_SE)) return true;
1376  }
1377 
1378  return false;
1379 }
1380 
1393 static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, uint itspec_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool *custom_shape_check = NULL)
1394 {
1395  bool refused_slope = false;
1396  bool custom_shape = false;
1397 
1398  do {
1399  IndustryGfx gfx = GetTranslatedIndustryTileID(it->gfx);
1400  TileIndex cur_tile = TileAddWrap(tile, it->ti.x, it->ti.y);
1401 
1402  if (!IsValidTile(cur_tile)) {
1403  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1404  }
1405 
1406  if (gfx == GFX_WATERTILE_SPECIALCHECK) {
1407  if (!IsWaterTile(cur_tile) ||
1408  !IsTileFlat(cur_tile)) {
1409  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1410  }
1411  } else {
1412  CommandCost ret = EnsureNoVehicleOnGround(cur_tile);
1413  if (ret.Failed()) return ret;
1414  if (IsBridgeAbove(cur_tile)) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1415 
1416  const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
1417 
1418  IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
1419 
1420  /* Perform land/water check if not disabled */
1421  if (!HasBit(its->slopes_refused, 5) && ((HasTileWaterClass(cur_tile) && IsTileOnWater(cur_tile)) == !(ind_behav & INDUSTRYBEH_BUILT_ONWATER))) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1422 
1424  custom_shape = true;
1425  CommandCost ret = PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index, initial_random_bits, founder, creation_type);
1426  if (ret.Failed()) return ret;
1427  } else {
1428  Slope tileh = GetTileSlope(cur_tile);
1429  refused_slope |= IsSlopeRefused(tileh, its->slopes_refused);
1430  }
1431 
1432  if ((ind_behav & (INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE)) || // Tile must be a house
1433  ((ind_behav & INDUSTRYBEH_ONLY_NEARTOWN) && IsTileType(cur_tile, MP_HOUSE))) { // Tile is allowed to be a house (and it is a house)
1434  if (!IsTileType(cur_tile, MP_HOUSE)) {
1435  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS);
1436  }
1437 
1438  /* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */
1439  Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
1440  CommandCost ret = DoCommand(cur_tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR);
1441  cur_company.Restore();
1442 
1443  if (ret.Failed()) return ret;
1444  } else {
1445  /* Clear the tiles, but do not affect town ratings */
1447 
1448  if (ret.Failed()) return ret;
1449  }
1450  }
1451  } while ((++it)->ti.x != -0x80);
1452 
1453  if (custom_shape_check != NULL) *custom_shape_check = custom_shape;
1454 
1455  /* It is almost impossible to have a fully flat land in TG, so what we
1456  * do is that we check if we can make the land flat later on. See
1457  * CheckIfCanLevelIndustryPlatform(). */
1458  if (!refused_slope || (_settings_game.game_creation.land_generator == LG_TERRAGENESIS && _generating_world && !custom_shape && !_ignore_restrictions)) {
1459  return CommandCost();
1460  }
1461  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1462 }
1463 
1472 {
1473  if ((GetIndustrySpec(type)->behaviour & INDUSTRYBEH_TOWN1200_MORE) && t->cache.population < 1200) {
1474  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200);
1475  }
1476 
1477  if ((GetIndustrySpec(type)->behaviour & INDUSTRYBEH_ONLY_NEARTOWN) && DistanceMax(t->xy, tile) > 9) {
1478  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_NEAR_TOWN_CENTER);
1479  }
1480 
1481  return CommandCost();
1482 }
1483 
1484 static bool CheckCanTerraformSurroundingTiles(TileIndex tile, uint height, int internal)
1485 {
1486  /* Check if we don't leave the map */
1487  if (TileX(tile) == 0 || TileY(tile) == 0 || GetTileType(tile) == MP_VOID) return false;
1488 
1489  TileArea ta(tile - TileDiffXY(1, 1), 2, 2);
1490  TILE_AREA_LOOP(tile_walk, ta) {
1491  uint curh = TileHeight(tile_walk);
1492  /* Is the tile clear? */
1493  if ((GetTileType(tile_walk) != MP_CLEAR) && (GetTileType(tile_walk) != MP_TREES)) return false;
1494 
1495  /* Don't allow too big of a change if this is the sub-tile check */
1496  if (internal != 0 && Delta(curh, height) > 1) return false;
1497 
1498  /* Different height, so the surrounding tiles of this tile
1499  * has to be correct too (in level, or almost in level)
1500  * else you get a chain-reaction of terraforming. */
1501  if (internal == 0 && curh != height) {
1502  if (TileX(tile_walk) == 0 || TileY(tile_walk) == 0 || !CheckCanTerraformSurroundingTiles(tile_walk + TileDiffXY(-1, -1), height, internal + 1)) {
1503  return false;
1504  }
1505  }
1506  }
1507 
1508  return true;
1509 }
1510 
1516 {
1517  const int MKEND = -0x80; // used for last element in an IndustryTileTable (see build_industry.h)
1518  int max_x = 0;
1519  int max_y = 0;
1520 
1521  /* Finds dimensions of largest variant of this industry */
1522  do {
1523  if (it->gfx == 0xFF) continue; // FF been a marquer for a check on clear water, skip it
1524  if (it->ti.x > max_x) max_x = it->ti.x;
1525  if (it->ti.y > max_y) max_y = it->ti.y;
1526  } while ((++it)->ti.x != MKEND);
1527 
1528  /* Remember level height */
1529  uint h = TileHeight(tile);
1530 
1531  if (TileX(tile) <= _settings_game.construction.industry_platform + 1U || TileY(tile) <= _settings_game.construction.industry_platform + 1U) return false;
1532  /* Check that all tiles in area and surrounding are clear
1533  * this determines that there are no obstructing items */
1534 
1537 
1538  if (TileX(ta.tile) + ta.w >= MapMaxX() || TileY(ta.tile) + ta.h >= MapMaxY()) return false;
1539 
1540  /* _current_company is OWNER_NONE for randomly generated industries and in editor, or the company who funded or prospected the industry.
1541  * Perform terraforming as OWNER_TOWN to disable autoslope and town ratings. */
1542  Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
1543 
1544  TILE_AREA_LOOP(tile_walk, ta) {
1545  uint curh = TileHeight(tile_walk);
1546  if (curh != h) {
1547  /* This tile needs terraforming. Check if we can do that without
1548  * damaging the surroundings too much. */
1549  if (!CheckCanTerraformSurroundingTiles(tile_walk, h, 0)) {
1550  cur_company.Restore();
1551  return false;
1552  }
1553  /* This is not 100% correct check, but the best we can do without modifying the map.
1554  * What is missing, is if the difference in height is more than 1.. */
1555  if (DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND).Failed()) {
1556  cur_company.Restore();
1557  return false;
1558  }
1559  }
1560  }
1561 
1562  if (flags & DC_EXEC) {
1563  /* Terraform the land under the industry */
1564  TILE_AREA_LOOP(tile_walk, ta) {
1565  uint curh = TileHeight(tile_walk);
1566  while (curh != h) {
1567  /* We give the terraforming for free here, because we can't calculate
1568  * exact cost in the test-round, and as we all know, that will cause
1569  * a nice assert if they don't match ;) */
1570  DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND);
1571  curh += (curh > h) ? -1 : 1;
1572  }
1573  }
1574  }
1575 
1576  cur_company.Restore();
1577  return true;
1578 }
1579 
1580 
1588 {
1589  const IndustrySpec *indspec = GetIndustrySpec(type);
1590  const Industry *i = NULL;
1591 
1592  /* On a large map with many industries, it may be faster to check an area. */
1593  static const int dmax = 14;
1594  if (Industry::GetNumItems() > (size_t) (dmax * dmax * 2)) {
1595  const int tx = TileX(tile);
1596  const int ty = TileY(tile);
1597  TileArea tile_area = TileArea(TileXY(max(0, tx - dmax), max(0, ty - dmax)), TileXY(min(MapMaxX(), tx + dmax), min(MapMaxY(), ty + dmax)));
1598  TILE_AREA_LOOP(atile, tile_area) {
1599  if (GetTileType(atile) == MP_INDUSTRY) {
1600  const Industry *i2 = Industry::GetByTile(atile);
1601  if (i == i2) continue;
1602  i = i2;
1603  if (DistanceMax(tile, i->location.tile) > (uint)dmax) continue;
1604  if (i->type == indspec->conflicting[0] ||
1605  i->type == indspec->conflicting[1] ||
1606  i->type == indspec->conflicting[2]) {
1607  return_cmd_error(STR_ERROR_INDUSTRY_TOO_CLOSE);
1608  }
1609  }
1610  }
1611  return CommandCost();
1612  }
1613 
1614  FOR_ALL_INDUSTRIES(i) {
1615  /* Within 14 tiles from another industry is considered close */
1616  if (DistanceMax(tile, i->location.tile) > 14) continue;
1617 
1618  /* check if there are any conflicting industry types around */
1619  if (i->type == indspec->conflicting[0] ||
1620  i->type == indspec->conflicting[1] ||
1621  i->type == indspec->conflicting[2]) {
1622  return_cmd_error(STR_ERROR_INDUSTRY_TOO_CLOSE);
1623  }
1624  }
1625  return CommandCost();
1626 }
1627 
1632 static void AdvertiseIndustryOpening(const Industry *ind)
1633 {
1634  const IndustrySpec *ind_spc = GetIndustrySpec(ind->type);
1635  SetDParam(0, ind_spc->name);
1636  if (ind_spc->new_industry_text > STR_LAST_STRINGID) {
1637  SetDParam(1, STR_TOWN_NAME);
1638  SetDParam(2, ind->town->index);
1639  } else {
1640  SetDParam(1, ind->town->index);
1641  }
1642  AddIndustryNewsItem(ind_spc->new_industry_text, NT_INDUSTRY_OPEN, ind->index);
1643  AI::BroadcastNewEvent(new ScriptEventIndustryOpen(ind->index));
1644  Game::NewEvent(new ScriptEventIndustryOpen(ind->index));
1645 }
1646 
1658 static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, const IndustryTileTable *it, byte layout, Town *t, Owner founder, uint16 initial_random_bits)
1659 {
1660  const IndustrySpec *indspec = GetIndustrySpec(type);
1661 
1662  i->location = TileArea(tile, 1, 1);
1663  i->type = type;
1665 
1666  MemCpyT(i->produced_cargo, indspec->produced_cargo, lengthof(i->produced_cargo));
1667  MemCpyT(i->production_rate, indspec->production_rate, lengthof(i->production_rate));
1669 
1677 
1678  /* don't use smooth economy for industries using production related callbacks */
1679  if (indspec->UsesSmoothEconomy()) {
1680  for (size_t ci = 0; ci < lengthof(i->production_rate); ci++) {
1681  i->production_rate[ci] = min((RandomRange(256) + 128) * i->production_rate[ci] >> 8, 255);
1682  }
1683  }
1684 
1685  i->town = t;
1686  i->owner = OWNER_NONE;
1687 
1688  uint16 r = Random();
1689  i->random_colour = GB(r, 0, 4);
1690  i->counter = GB(r, 4, 12);
1691  i->random = initial_random_bits;
1692  i->was_cargo_delivered = false;
1694  i->founder = founder;
1695 
1696  i->construction_date = _date;
1697  i->construction_type = (_game_mode == GM_EDITOR) ? ICT_SCENARIO_EDITOR :
1699 
1700  /* Adding 1 here makes it conform to specs of var44 of varaction2 for industries
1701  * 0 = created prior of newindustries
1702  * else, chosen layout + 1 */
1703  i->selected_layout = layout + 1;
1704 
1706 
1707  /* Call callbacks after the regular fields got initialised. */
1708 
1710  uint16 res = GetIndustryCallback(CBID_INDUSTRY_PROD_CHANGE_BUILD, 0, Random(), i, type, INVALID_TILE);
1711  if (res != CALLBACK_FAILED) {
1712  if (res < PRODLEVEL_MINIMUM || res > PRODLEVEL_MAXIMUM) {
1714  } else {
1715  i->prod_level = res;
1717  }
1718  }
1719  }
1720 
1721  if (_generating_world) {
1722  for (size_t ci = 0; ci < lengthof(i->last_month_production); ci++) {
1723  i->last_month_production[ci] = i->production_rate[ci] * 8;
1724  }
1725  }
1726 
1727  if (HasBit(indspec->callback_mask, CBM_IND_DECIDE_COLOUR)) {
1728  uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE);
1729  if (res != CALLBACK_FAILED) {
1730  if (GB(res, 4, 11) != 0) ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_DECIDE_COLOUR, res);
1731  i->random_colour = GB(res, 0, 4);
1732  }
1733  }
1734 
1736  /* Clear all input cargo types */
1737  for (uint j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID;
1738  /* Query actual types */
1739  uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? lengthof(i->accepts_cargo) : 3;
1740  for (uint j = 0; j < maxcargoes; j++) {
1742  if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
1743  if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) {
1745  break;
1746  }
1747  CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
1748  if (std::find(indspec->accepts_cargo, endof(indspec->accepts_cargo), cargo) == endof(indspec->accepts_cargo)) {
1749  /* Cargo not in spec, error in NewGRF */
1751  break;
1752  }
1753  if (std::find(i->accepts_cargo, i->accepts_cargo + j, cargo) != i->accepts_cargo + j) {
1754  /* Duplicate cargo */
1756  break;
1757  }
1758  i->accepts_cargo[j] = cargo;
1759  }
1760  }
1761 
1763  /* Clear all output cargo types */
1764  for (uint j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID;
1765  /* Query actual types */
1766  uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? lengthof(i->produced_cargo) : 2;
1767  for (uint j = 0; j < maxcargoes; j++) {
1769  if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
1770  if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) {
1772  break;
1773  }
1774  CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
1775  if (std::find(indspec->produced_cargo, endof(indspec->produced_cargo), cargo) == endof(indspec->produced_cargo)) {
1776  /* Cargo not in spec, error in NewGRF */
1778  break;
1779  }
1780  if (std::find(i->produced_cargo, i->produced_cargo + j, cargo) != i->produced_cargo + j) {
1781  /* Duplicate cargo */
1783  break;
1784  }
1785  i->produced_cargo[j] = cargo;
1786  }
1787  }
1788 
1789  /* Plant the tiles */
1790 
1791  do {
1792  TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
1793 
1794  if (it->gfx != GFX_WATERTILE_SPECIALCHECK) {
1795  i->location.Add(cur_tile);
1796 
1797  WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID);
1798 
1800 
1801  MakeIndustry(cur_tile, i->index, it->gfx, Random(), wc);
1802 
1803  if (_generating_world) {
1804  SetIndustryConstructionCounter(cur_tile, 3);
1805  SetIndustryConstructionStage(cur_tile, 2);
1806  }
1807 
1808  /* it->gfx is stored in the map. But the translated ID cur_gfx is the interesting one */
1809  IndustryGfx cur_gfx = GetTranslatedIndustryTileID(it->gfx);
1810  const IndustryTileSpec *its = GetIndustryTileSpec(cur_gfx);
1812  }
1813  } while ((++it)->ti.x != -0x80);
1814 
1816  for (uint j = 0; j != 50; j++) PlantRandomFarmField(i);
1817  }
1819 
1821 }
1822 
1839 static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCommandFlag flags, const IndustrySpec *indspec, uint itspec_index, uint32 random_var8f, uint16 random_initial_bits, Owner founder, IndustryAvailabilityCallType creation_type, Industry **ip)
1840 {
1841  assert(itspec_index < indspec->num_table);
1842  const IndustryTileTable *it = indspec->table[itspec_index];
1843  bool custom_shape_check = false;
1844 
1845  *ip = NULL;
1846 
1847  SmallVector<ClearedObjectArea, 1> object_areas(_cleared_object_areas);
1848  CommandCost ret = CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, random_initial_bits, founder, creation_type, &custom_shape_check);
1849  _cleared_object_areas = object_areas;
1850  if (ret.Failed()) return ret;
1851 
1852  if (HasBit(GetIndustrySpec(type)->callback_mask, CBM_IND_LOCATION)) {
1853  ret = CheckIfCallBackAllowsCreation(tile, type, itspec_index, random_var8f, random_initial_bits, founder, creation_type);
1854  } else {
1855  ret = _check_new_industry_procs[indspec->check_proc](tile);
1856  }
1857  if (ret.Failed()) return ret;
1858 
1860  !_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER, it, type)) {
1861  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1862  }
1863 
1864  ret = CheckIfFarEnoughFromConflictingIndustry(tile, type);
1865  if (ret.Failed()) return ret;
1866 
1867  Town *t = NULL;
1868  ret = FindTownForIndustry(tile, type, &t);
1869  if (ret.Failed()) return ret;
1870  assert(t != NULL);
1871 
1872  ret = CheckIfIndustryIsAllowed(tile, type, t);
1873  if (ret.Failed()) return ret;
1874 
1875  if (!Industry::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_INDUSTRIES);
1876 
1877  if (flags & DC_EXEC) {
1878  *ip = new Industry(tile);
1879  if (!custom_shape_check) CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER | DC_EXEC, it, type);
1880  DoCreateNewIndustry(*ip, tile, type, it, itspec_index, t, founder, random_initial_bits);
1881  }
1882 
1883  return CommandCost();
1884 }
1885 
1898 CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1899 {
1900  IndustryType it = GB(p1, 0, 8);
1901  if (it >= NUM_INDUSTRYTYPES) return CMD_ERROR;
1902 
1903  const IndustrySpec *indspec = GetIndustrySpec(it);
1904 
1905  /* Check if the to-be built/founded industry is available for this climate. */
1906  if (!indspec->enabled || indspec->num_table == 0) return CMD_ERROR;
1907 
1908  /* If the setting for raw-material industries is not on, you cannot build raw-material industries.
1909  * Raw material industries are industries that do not accept cargo (at least for now) */
1910  if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 0 && indspec->IsRawIndustry()) {
1911  return CMD_ERROR;
1912  }
1913 
1914  if (_game_mode != GM_EDITOR && GetIndustryProbabilityCallback(it, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, 1) == 0) {
1915  return CMD_ERROR;
1916  }
1917 
1918  Randomizer randomizer;
1919  randomizer.SetSeed(p2);
1920  uint16 random_initial_bits = GB(p2, 0, 16);
1921  uint32 random_var8f = randomizer.Next();
1922  int num_layouts = indspec->num_table;
1923  CommandCost ret = CommandCost(STR_ERROR_SITE_UNSUITABLE);
1924  const bool deity_prospect = _current_company == OWNER_DEITY && !HasBit(p1, 16);
1925 
1926  Industry *ind = NULL;
1927  if (deity_prospect || (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry())) {
1928  if (flags & DC_EXEC) {
1929  /* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */
1930  Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
1931  /* Prospecting has a chance to fail, however we cannot guarantee that something can
1932  * be built on the map, so the chance gets lower when the map is fuller, but there
1933  * is nothing we can really do about that. */
1934  if (deity_prospect || Random() <= indspec->prospecting_chance) {
1935  for (int i = 0; i < 5000; i++) {
1936  /* We should not have more than one Random() in a function call
1937  * because parameter evaluation order is not guaranteed in the c++ standard
1938  */
1939  tile = RandomTile();
1940  /* Start with a random layout */
1941  int layout = RandomRange(num_layouts);
1942  /* Check now each layout, starting with the random one */
1943  for (int j = 0; j < num_layouts; j++) {
1944  layout = (layout + 1) % num_layouts;
1945  ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, cur_company.GetOriginalValue(), _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_PROSPECTCREATION, &ind);
1946  if (ret.Succeeded()) break;
1947  }
1948  if (ret.Succeeded()) break;
1949  }
1950  }
1951  cur_company.Restore();
1952  }
1953  } else {
1954  int layout = GB(p1, 8, 8);
1955  if (layout >= num_layouts) return CMD_ERROR;
1956 
1957  /* Check subsequently each layout, starting with the given layout in p1 */
1958  for (int i = 0; i < num_layouts; i++) {
1959  layout = (layout + 1) % num_layouts;
1960  ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, _current_company, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, &ind);
1961  if (ret.Succeeded()) break;
1962  }
1963 
1964  /* If it still failed, there's no suitable layout to build here, return the error */
1965  if (ret.Failed()) return ret;
1966  }
1967 
1968  if ((flags & DC_EXEC) && ind != NULL && _game_mode != GM_EDITOR) {
1970  }
1971 
1972  return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
1973 }
1974 
1975 
1983 static Industry *CreateNewIndustry(TileIndex tile, IndustryType type, IndustryAvailabilityCallType creation_type)
1984 {
1985  const IndustrySpec *indspec = GetIndustrySpec(type);
1986 
1987  uint32 seed = Random();
1988  uint32 seed2 = Random();
1989  Industry *i = NULL;
1990  CommandCost ret = CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, RandomRange(indspec->num_table), seed, GB(seed2, 0, 16), OWNER_NONE, creation_type, &i);
1991  assert(i != NULL || ret.Failed());
1992  return i;
1993 }
1994 
2001 static uint32 GetScaledIndustryGenerationProbability(IndustryType it, bool *force_at_least_one)
2002 {
2003  const IndustrySpec *ind_spc = GetIndustrySpec(it);
2004  uint32 chance = ind_spc->appear_creation[_settings_game.game_creation.landscape] * 16; // * 16 to increase precision
2005  if (!ind_spc->enabled || ind_spc->num_table == 0 ||
2006  (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) ||
2007  (chance = GetIndustryProbabilityCallback(it, IACT_MAPGENERATION, chance)) == 0) {
2008  *force_at_least_one = false;
2009  return 0;
2010  } else {
2011  /* We want industries appearing at coast to appear less often on bigger maps, as length of coast increases slower than map area.
2012  * For simplicity we scale in both cases, though scaling the probabilities of all industries has no effect. */
2013  chance = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? ScaleByMapSize1D(chance) : ScaleByMapSize(chance);
2014 
2015  *force_at_least_one = (chance > 0) && !(ind_spc->behaviour & INDUSTRYBEH_NOBUILT_MAPCREATION) && (_game_mode != GM_EDITOR);
2016  return chance;
2017  }
2018 }
2019 
2026 static uint16 GetIndustryGamePlayProbability(IndustryType it, byte *min_number)
2027 {
2029  *min_number = 0;
2030  return 0;
2031  }
2032 
2033  const IndustrySpec *ind_spc = GetIndustrySpec(it);
2034  byte chance = ind_spc->appear_ingame[_settings_game.game_creation.landscape];
2035  if (!ind_spc->enabled || ind_spc->num_table == 0 ||
2036  ((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && _cur_year > 1950) ||
2037  ((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && _cur_year < 1960) ||
2038  (chance = GetIndustryProbabilityCallback(it, IACT_RANDOMCREATION, chance)) == 0) {
2039  *min_number = 0;
2040  return 0;
2041  }
2042  *min_number = (ind_spc->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) ? 1 : 0;
2043  return chance;
2044 }
2045 
2051 {
2052  /* Number of industries on a 256x256 map. */
2053  static const uint16 numof_industry_table[] = {
2054  0, // none
2055  0, // minimal
2056  10, // very low
2057  25, // low
2058  55, // normal
2059  80, // high
2060  };
2061 
2062  assert(lengthof(numof_industry_table) == ID_END);
2063  uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.industry_density : (uint)ID_VERY_LOW;
2064  return min(IndustryPool::MAX_SIZE, ScaleByMapSize(numof_industry_table[difficulty]));
2065 }
2066 
2075 static Industry *PlaceIndustry(IndustryType type, IndustryAvailabilityCallType creation_type, bool try_hard)
2076 {
2077  uint tries = try_hard ? 10000u : 2000u;
2078  for (; tries > 0; tries--) {
2079  Industry *ind = CreateNewIndustry(RandomTile(), type, creation_type);
2080  if (ind != NULL) return ind;
2081  }
2082  return NULL;
2083 }
2084 
2090 static void PlaceInitialIndustry(IndustryType type, bool try_hard)
2091 {
2092  Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2093 
2095  PlaceIndustry(type, IACT_MAPGENERATION, try_hard);
2096 
2097  cur_company.Restore();
2098 }
2099 
2105 {
2106  int total = 0;
2107  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) total += Industry::GetIndustryTypeCount(it);
2108  return total;
2109 }
2110 
2111 
2114 {
2115  this->probability = 0;
2116  this->min_number = 0;
2117  this->target_count = 0;
2118  this->max_wait = 1;
2119  this->wait_count = 0;
2120 }
2121 
2124 {
2125  this->wanted_inds = GetCurrentTotalNumberOfIndustries() << 16;
2126 
2127  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2128  this->builddata[it].Reset();
2129  }
2130 }
2131 
2134 {
2135  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.
2136  if (_settings_game.difficulty.industry_density == ID_FUND_ONLY) return; // 'no industries' setting.
2137 
2138  /* To prevent running out of unused industries for the player to connect,
2139  * add a fraction of new industries each month, but only if the manager can keep up. */
2140  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).
2141  if (GetCurrentTotalNumberOfIndustries() + max_behind >= (this->wanted_inds >> 16)) {
2142  this->wanted_inds += ScaleByMapSize(NEWINDS_PER_MONTH);
2143  }
2144 }
2145 
2151 {
2152  if (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) return; // No industries in the game.
2153 
2154  uint32 industry_probs[NUM_INDUSTRYTYPES];
2155  bool force_at_least_one[NUM_INDUSTRYTYPES];
2156  uint32 total_prob = 0;
2157  uint num_forced = 0;
2158 
2159  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2160  industry_probs[it] = GetScaledIndustryGenerationProbability(it, force_at_least_one + it);
2161  total_prob += industry_probs[it];
2162  if (force_at_least_one[it]) num_forced++;
2163  }
2164 
2165  uint total_amount = GetNumberOfIndustries();
2166  if (total_prob == 0 || total_amount < num_forced) {
2167  /* Only place the forced ones */
2168  total_amount = num_forced;
2169  }
2170 
2172 
2173  /* Try to build one industry per type independent of any probabilities */
2174  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2175  if (force_at_least_one[it]) {
2176  assert(total_amount > 0);
2177  total_amount--;
2178  PlaceInitialIndustry(it, true);
2179  }
2180  }
2181 
2182  /* Add the remaining industries according to their probabilities */
2183  for (uint i = 0; i < total_amount; i++) {
2184  uint32 r = RandomRange(total_prob);
2185  IndustryType it = 0;
2186  while (r >= industry_probs[it]) {
2187  r -= industry_probs[it];
2188  it++;
2189  assert(it < NUM_INDUSTRYTYPES);
2190  }
2191  assert(industry_probs[it] > 0);
2192  PlaceInitialIndustry(it, false);
2193  }
2194  _industry_builder.Reset();
2195 }
2196 
2202 {
2203  for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
2204  if (i->produced_cargo[j] != CT_INVALID) {
2205  byte pct = 0;
2206  if (i->this_month_production[j] != 0) {
2208  pct = min(i->this_month_transported[j] * 256 / i->this_month_production[j], 255);
2209  }
2210  i->last_month_pct_transported[j] = pct;
2211 
2213  i->this_month_production[j] = 0;
2214 
2216  i->this_month_transported[j] = 0;
2217  }
2218  }
2219 }
2220 
2226 {
2227  const IndustrySpec *indspec = GetIndustrySpec(this->type);
2228  assert(!indspec->UsesSmoothEconomy());
2229 
2230  /* Rates are rounded up, so e.g. oilrig always produces some passengers */
2231  for (size_t i = 0; i < lengthof(this->production_rate); i++) {
2232  this->production_rate[i] = min(CeilDiv(indspec->production_rate[i] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF);
2233  }
2234 }
2235 
2236 
2243 {
2244  byte min_number;
2245  uint32 probability = GetIndustryGamePlayProbability(it, &min_number);
2246  bool changed = min_number != this->min_number || probability != this->probability;
2247  this->min_number = min_number;
2248  this->probability = probability;
2249  return changed;
2250 }
2251 
2254 {
2255  bool changed = false;
2256  uint num_planned = 0; // Number of industries planned in the industry build data.
2257  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2258  changed |= this->builddata[it].GetIndustryTypeData(it);
2259  num_planned += this->builddata[it].target_count;
2260  }
2261  uint total_amount = this->wanted_inds >> 16; // Desired total number of industries.
2262  changed |= num_planned != total_amount;
2263  if (!changed) return; // All industries are still the same, no need to re-randomize.
2264 
2265  /* Initialize the target counts. */
2266  uint force_build = 0; // Number of industries that should always be available.
2267  uint32 total_prob = 0; // Sum of probabilities.
2268  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2269  IndustryTypeBuildData *ibd = this->builddata + it;
2270  force_build += ibd->min_number;
2271  ibd->target_count = ibd->min_number;
2272  total_prob += ibd->probability;
2273  }
2274 
2275  if (total_prob == 0) return; // No buildable industries.
2276 
2277  /* Subtract forced industries from the number of industries available for construction. */
2278  total_amount = (total_amount <= force_build) ? 0 : total_amount - force_build;
2279 
2280  /* Assign number of industries that should be aimed for, by using the probability as a weight. */
2281  while (total_amount > 0) {
2282  uint32 r = RandomRange(total_prob);
2283  IndustryType it = 0;
2284  while (r >= this->builddata[it].probability) {
2285  r -= this->builddata[it].probability;
2286  it++;
2287  assert(it < NUM_INDUSTRYTYPES);
2288  }
2289  assert(this->builddata[it].probability > 0);
2290  this->builddata[it].target_count++;
2291  total_amount--;
2292  }
2293 }
2294 
2299 {
2300  this->SetupTargetCount();
2301 
2302  int missing = 0; // Number of industries that need to be build.
2303  uint count = 0; // Number of industry types eligible for build.
2304  uint32 total_prob = 0; // Sum of probabilities.
2305  IndustryType forced_build = NUM_INDUSTRYTYPES; // Industry type that should be forcibly build.
2306  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2307  int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
2308  missing += difference;
2309  if (this->builddata[it].wait_count > 0) continue; // This type may not be built now.
2310  if (difference > 0) {
2311  if (Industry::GetIndustryTypeCount(it) == 0 && this->builddata[it].min_number > 0) {
2312  /* An industry that should exist at least once, is not available. Force it, trying the most needed one first. */
2313  if (forced_build == NUM_INDUSTRYTYPES ||
2314  difference > this->builddata[forced_build].target_count - Industry::GetIndustryTypeCount(forced_build)) {
2315  forced_build = it;
2316  }
2317  }
2318  total_prob += difference;
2319  count++;
2320  }
2321  }
2322 
2323  if (EconomyIsInRecession() || (forced_build == NUM_INDUSTRYTYPES && (missing <= 0 || total_prob == 0))) count = 0; // Skip creation of an industry.
2324 
2325  if (count >= 1) {
2326  /* If not forced, pick a weighted random industry to build.
2327  * For the case that count == 1, there is no need to draw a random number. */
2328  IndustryType it;
2329  if (forced_build != NUM_INDUSTRYTYPES) {
2330  it = forced_build;
2331  } else {
2332  /* Non-forced, select an industry type to build (weighted random). */
2333  uint32 r = 0; // Initialized to silence the compiler.
2334  if (count > 1) r = RandomRange(total_prob);
2335  for (it = 0; it < NUM_INDUSTRYTYPES; it++) {
2336  if (this->builddata[it].wait_count > 0) continue; // Type may not be built now.
2337  int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
2338  if (difference <= 0) continue; // Too many of this kind.
2339  if (count == 1) break;
2340  if (r < (uint)difference) break;
2341  r -= difference;
2342  }
2343  assert(it < NUM_INDUSTRYTYPES && this->builddata[it].target_count > Industry::GetIndustryTypeCount(it));
2344  }
2345 
2346  /* Try to create the industry. */
2347  const Industry *ind = PlaceIndustry(it, IACT_RANDOMCREATION, false);
2348  if (ind == NULL) {
2349  this->builddata[it].wait_count = this->builddata[it].max_wait + 1; // Compensate for decrementing below.
2350  this->builddata[it].max_wait = min(1000, this->builddata[it].max_wait + 2);
2351  } else {
2353  this->builddata[it].max_wait = max(this->builddata[it].max_wait / 2, 1); // Reduce waiting time of the industry type.
2354  }
2355  }
2356 
2357  /* Decrement wait counters. */
2358  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2359  if (this->builddata[it].wait_count > 0) this->builddata[it].wait_count--;
2360  }
2361 }
2362 
2371 static bool CheckIndustryCloseDownProtection(IndustryType type)
2372 {
2373  const IndustrySpec *indspec = GetIndustrySpec(type);
2374 
2375  /* oil wells (or the industries with that flag set) are always allowed to closedown */
2376  if ((indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE) return false;
2377  return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) == 0 && Industry::GetIndustryTypeCount(type) <= 1;
2378 }
2379 
2389 static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accepts, bool *c_produces)
2390 {
2391  if (cargo == CT_INVALID) return;
2392 
2393  /* Check for acceptance of cargo */
2394  for (byte j = 0; j < lengthof(ind->accepts_cargo); j++) {
2395  if (cargo == ind->accepts_cargo[j] && !IndustryTemporarilyRefusesCargo(ind, cargo)) {
2396  *c_accepts = true;
2397  break;
2398  }
2399  }
2400 
2401  /* Check for produced cargo */
2402  for (byte j = 0; j < lengthof(ind->produced_cargo); j++) {
2403  if (cargo == ind->produced_cargo[j]) {
2404  *c_produces = true;
2405  break;
2406  }
2407  }
2408 }
2409 
2424 {
2425  /* Find all stations within reach of the industry */
2426  StationList stations;
2427  FindStationsAroundTiles(ind->location, &stations);
2428 
2429  if (stations.Length() == 0) return 0; // No stations found at all => nobody services
2430 
2431  const Vehicle *v;
2432  int result = 0;
2433  FOR_ALL_VEHICLES(v) {
2434  /* Is it worthwhile to try this vehicle? */
2435  if (v->owner != _local_company && result != 0) continue;
2436 
2437  /* Check whether it accepts the right kind of cargo */
2438  bool c_accepts = false;
2439  bool c_produces = false;
2440  if (v->type == VEH_TRAIN && v->IsFrontEngine()) {
2441  for (const Vehicle *u = v; u != NULL; u = u->Next()) {
2442  CanCargoServiceIndustry(u->cargo_type, ind, &c_accepts, &c_produces);
2443  }
2444  } else if (v->type == VEH_ROAD || v->type == VEH_SHIP || v->type == VEH_AIRCRAFT) {
2445  CanCargoServiceIndustry(v->cargo_type, ind, &c_accepts, &c_produces);
2446  } else {
2447  continue;
2448  }
2449  if (!c_accepts && !c_produces) continue; // Wrong cargo
2450 
2451  /* Check orders of the vehicle.
2452  * We cannot check the first of shared orders only, since the first vehicle in such a chain
2453  * may have a different cargo type.
2454  */
2455  const Order *o;
2456  FOR_VEHICLE_ORDERS(v, o) {
2457  if (o->IsType(OT_GOTO_STATION) && !(o->GetUnloadType() & OUFB_TRANSFER)) {
2458  /* Vehicle visits a station to load or unload */
2459  Station *st = Station::Get(o->GetDestination());
2460  assert(st != NULL);
2461 
2462  /* Same cargo produced by industry is dropped here => not serviced by vehicle v */
2463  if ((o->GetUnloadType() & OUFB_UNLOAD) && !c_accepts) break;
2464 
2465  if (stations.Contains(st)) {
2466  if (v->owner == _local_company) return 2; // Company services industry
2467  result = 1; // Competitor services industry
2468  }
2469  }
2470  }
2471  }
2472  return result;
2473 }
2474 
2483 {
2484  NewsType nt;
2485 
2486  switch (WhoCanServiceIndustry(ind)) {
2487  case 0: nt = NT_INDUSTRY_NOBODY; break;
2488  case 1: nt = NT_INDUSTRY_OTHER; break;
2489  case 2: nt = NT_INDUSTRY_COMPANY; break;
2490  default: NOT_REACHED();
2491  }
2492  SetDParam(2, abs(percent));
2493  SetDParam(0, CargoSpec::Get(type)->name);
2494  SetDParam(1, ind->index);
2495  AddIndustryNewsItem(
2496  percent >= 0 ? STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH : STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH,
2497  nt,
2498  ind->index
2499  );
2500 }
2501 
2502 static const uint PERCENT_TRANSPORTED_60 = 153;
2503 static const uint PERCENT_TRANSPORTED_80 = 204;
2504 
2510 static void ChangeIndustryProduction(Industry *i, bool monthly)
2511 {
2512  StringID str = STR_NULL;
2513  bool closeit = false;
2514  const IndustrySpec *indspec = GetIndustrySpec(i->type);
2515  bool standard = false;
2516  bool suppress_message = false;
2517  bool recalculate_multipliers = false;
2518  /* don't use smooth economy for industries using production related callbacks */
2519  bool smooth_economy = indspec->UsesSmoothEconomy();
2520  byte div = 0;
2521  byte mul = 0;
2522  int8 increment = 0;
2523 
2524  bool callback_enabled = HasBit(indspec->callback_mask, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE);
2525  if (callback_enabled) {
2527  if (res != CALLBACK_FAILED) { // failed callback means "do nothing"
2528  suppress_message = HasBit(res, 7);
2529  /* Get the custom message if any */
2530  if (HasBit(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16));
2531  res = GB(res, 0, 4);
2532  switch (res) {
2533  default: NOT_REACHED();
2534  case 0x0: break; // Do nothing, but show the custom message if any
2535  case 0x1: div = 1; break; // Halve industry production. If production reaches the quarter of the default, the industry is closed instead.
2536  case 0x2: mul = 1; break; // Double industry production if it hasn't reached eight times of the original yet.
2537  case 0x3: closeit = true; break; // The industry announces imminent closure, and is physically removed from the map next month.
2538  case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one.
2539  case 0x5: case 0x6: case 0x7: // Divide production by 4, 8, 16
2540  case 0x8: div = res - 0x3; break; // Divide production by 32
2541  case 0x9: case 0xA: case 0xB: // Multiply production by 4, 8, 16
2542  case 0xC: mul = res - 0x7; break; // Multiply production by 32
2543  case 0xD: // decrement production
2544  case 0xE: // increment production
2545  increment = res == 0x0D ? -1 : 1;
2546  break;
2547  case 0xF: // Set production to third byte of register 0x100
2549  recalculate_multipliers = true;
2550  break;
2551  }
2552  }
2553  } else {
2554  if (monthly != smooth_economy) return;
2555  if (indspec->life_type == INDUSTRYLIFE_BLACK_HOLE) return;
2556  }
2557 
2558  if (standard || (!callback_enabled && (indspec->life_type & (INDUSTRYLIFE_ORGANIC | INDUSTRYLIFE_EXTRACTIVE)) != 0)) {
2559  /* decrease or increase */
2560  bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE;
2561 
2562  if (smooth_economy) {
2563  closeit = true;
2564  for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
2565  if (i->produced_cargo[j] == CT_INVALID) continue;
2566  uint32 r = Random();
2567  int old_prod, new_prod, percent;
2568  /* If over 60% is transported, mult is 1, else mult is -1. */
2569  int mult = (i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_60) ? 1 : -1;
2570 
2571  new_prod = old_prod = i->production_rate[j];
2572 
2573  /* For industries with only_decrease flags (temperate terrain Oil Wells),
2574  * the multiplier will always be -1 so they will only decrease. */
2575  if (only_decrease) {
2576  mult = -1;
2577  /* For normal industries, if over 60% is transported, 33% chance for decrease.
2578  * Bonus for very high station ratings (over 80%): 16% chance for decrease. */
2579  } else if (Chance16I(1, ((i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_80) ? 6 : 3), r)) {
2580  mult *= -1;
2581  }
2582 
2583  /* 4.5% chance for 3-23% (or 1 unit for very low productions) production change,
2584  * determined by mult value. If mult = 1 prod. increases, else (-1) it decreases. */
2585  if (Chance16I(1, 22, r >> 16)) {
2586  new_prod += mult * (max(((RandomRange(50) + 10) * old_prod) >> 8, 1U));
2587  }
2588 
2589  /* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
2590  new_prod = Clamp(new_prod, 1, 255);
2591 
2592  if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1) {
2593  new_prod = Clamp(new_prod, 0, 16);
2594  }
2595 
2596  /* Do not stop closing the industry when it has the lowest possible production rate */
2597  if (new_prod == old_prod && old_prod > 1) {
2598  closeit = false;
2599  continue;
2600  }
2601 
2602  percent = (old_prod == 0) ? 100 : (new_prod * 100 / old_prod - 100);
2603  i->production_rate[j] = new_prod;
2604 
2605  /* Close the industry when it has the lowest possible production rate */
2606  if (new_prod > 1) closeit = false;
2607 
2608  if (abs(percent) >= 10) {
2610  }
2611  }
2612  } else {
2613  if (only_decrease || Chance16(1, 3)) {
2614  /* If more than 60% transported, 66% chance of increase, else 33% chance of increase */
2615  if (!only_decrease && (i->last_month_pct_transported[0] > PERCENT_TRANSPORTED_60) != Chance16(1, 3)) {
2616  mul = 1; // Increase production
2617  } else {
2618  div = 1; // Decrease production
2619  }
2620  }
2621  }
2622  }
2623 
2624  if (!callback_enabled && (indspec->life_type & INDUSTRYLIFE_PROCESSING)) {
2625  if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, smooth_economy ? 180 : 2)) {
2626  closeit = true;
2627  }
2628  }
2629 
2630  /* Increase if needed */
2631  while (mul-- != 0 && i->prod_level < PRODLEVEL_MAXIMUM) {
2633  recalculate_multipliers = true;
2634  if (str == STR_NULL) str = indspec->production_up_text;
2635  }
2636 
2637  /* Decrease if needed */
2638  while (div-- != 0 && !closeit) {
2639  if (i->prod_level == PRODLEVEL_MINIMUM) {
2640  closeit = true;
2641  } else {
2642  i->prod_level = max(i->prod_level / 2, (int)PRODLEVEL_MINIMUM); // typecast to int required to please MSVC
2643  recalculate_multipliers = true;
2644  if (str == STR_NULL) str = indspec->production_down_text;
2645  }
2646  }
2647 
2648  /* Increase or Decreasing the production level if needed */
2649  if (increment != 0) {
2650  if (increment < 0 && i->prod_level == PRODLEVEL_MINIMUM) {
2651  closeit = true;
2652  } else {
2654  recalculate_multipliers = true;
2655  }
2656  }
2657 
2658  /* Recalculate production_rate
2659  * For non-smooth economy these should always be synchronized with prod_level */
2660  if (recalculate_multipliers) i->RecomputeProductionMultipliers();
2661 
2662  /* Close if needed and allowed */
2663  if (closeit && !CheckIndustryCloseDownProtection(i->type)) {
2666  str = indspec->closure_text;
2667  }
2668 
2669  if (!suppress_message && str != STR_NULL) {
2670  NewsType nt;
2671  /* Compute news category */
2672  if (closeit) {
2673  nt = NT_INDUSTRY_CLOSE;
2674  AI::BroadcastNewEvent(new ScriptEventIndustryClose(i->index));
2675  Game::NewEvent(new ScriptEventIndustryClose(i->index));
2676  } else {
2677  switch (WhoCanServiceIndustry(i)) {
2678  case 0: nt = NT_INDUSTRY_NOBODY; break;
2679  case 1: nt = NT_INDUSTRY_OTHER; break;
2680  case 2: nt = NT_INDUSTRY_COMPANY; break;
2681  default: NOT_REACHED();
2682  }
2683  }
2684  /* Set parameters of news string */
2685  if (str > STR_LAST_STRINGID) {
2686  SetDParam(0, STR_TOWN_NAME);
2687  SetDParam(1, i->town->index);
2688  SetDParam(2, indspec->name);
2689  } else if (closeit) {
2690  SetDParam(0, STR_FORMAT_INDUSTRY_NAME);
2691  SetDParam(1, i->town->index);
2692  SetDParam(2, indspec->name);
2693  } else {
2694  SetDParam(0, i->index);
2695  }
2696  /* and report the news to the user */
2697  if (closeit) {
2698  AddTileNewsItem(str, nt, i->location.tile + TileDiffXY(1, 1));
2699  } else {
2700  AddIndustryNewsItem(str, nt, i->index);
2701  }
2702  }
2703 }
2704 
2713 {
2715 
2716  /* Bits 16-31 of industry_construction_counter contain the number of industries to change/create today,
2717  * the lower 16 bit are a fractional part that might accumulate over several days until it
2718  * is sufficient for an industry. */
2719  uint16 change_loop = _economy.industry_daily_change_counter >> 16;
2720 
2721  /* Reset the active part of the counter, just keeping the "fractional part" */
2722  _economy.industry_daily_change_counter &= 0xFFFF;
2723 
2724  if (change_loop == 0) {
2725  return; // Nothing to do? get out
2726  }
2727 
2728  Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2729 
2730  /* perform the required industry changes for the day */
2731 
2732  uint perc = 3; // Between 3% and 9% chance of creating a new industry.
2733  if ((_industry_builder.wanted_inds >> 16) > GetCurrentTotalNumberOfIndustries()) {
2734  perc = min(9u, perc + (_industry_builder.wanted_inds >> 16) - GetCurrentTotalNumberOfIndustries());
2735  }
2736  for (uint16 j = 0; j < change_loop; j++) {
2737  if (Chance16(perc, 100)) {
2738  _industry_builder.TryBuildNewIndustry();
2739  } else {
2741  if (i != NULL) {
2742  ChangeIndustryProduction(i, false);
2744  }
2745  }
2746  }
2747 
2748  cur_company.Restore();
2749 
2750  /* production-change */
2752 }
2753 
2754 void IndustryMonthlyLoop()
2755 {
2756  Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2757 
2758  _industry_builder.MonthlyLoop();
2759 
2760  Industry *i;
2761  FOR_ALL_INDUSTRIES(i) {
2763  if (i->prod_level == PRODLEVEL_CLOSURE) {
2764  delete i;
2765  } else {
2766  ChangeIndustryProduction(i, true);
2768  }
2769  }
2770 
2771  cur_company.Restore();
2772 
2773  /* production-change */
2775 }
2776 
2777 
2778 void InitializeIndustries()
2779 {
2781  _industry_sound_tile = 0;
2782 
2783  _industry_builder.Reset();
2784 }
2785 
2788 {
2789  int count = 0;
2790  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2791  if (Industry::GetIndustryTypeCount(it) > 0) continue; // Types of existing industries can be skipped.
2792 
2793  bool force_at_least_one;
2794  uint32 chance = GetScaledIndustryGenerationProbability(it, &force_at_least_one);
2795  if (chance == 0 || !force_at_least_one) continue; // Types that are not available can be skipped.
2796 
2797  const IndustrySpec *is = GetIndustrySpec(it);
2798  SetDParam(0, is->name);
2799  ShowErrorMessage(STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES, STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION, WL_WARNING);
2800 
2801  count++;
2802  if (count >= 3) break; // Don't swamp the user with errors.
2803  }
2804 }
2805 
2811 {
2812  return (this->life_type & (INDUSTRYLIFE_EXTRACTIVE | INDUSTRYLIFE_ORGANIC)) != 0;
2813 }
2814 
2820 {
2821  /* Lumber mills are neither raw nor processing */
2822  return (this->life_type & INDUSTRYLIFE_PROCESSING) != 0 &&
2823  (this->behaviour & INDUSTRYBEH_CUT_TREES) == 0;
2824 }
2825 
2831 {
2832  /* Building raw industries like secondary uses different price base */
2833  return (_price[(_settings_game.construction.raw_industry_construction == 1 && this->IsRawIndustry()) ?
2834  PR_BUILD_INDUSTRY_RAW : PR_BUILD_INDUSTRY] * this->cost_multiplier) >> 8;
2835 }
2836 
2844 {
2845  return (_price[PR_CLEAR_INDUSTRY] * this->removal_cost_multiplier) >> 8;
2846 }
2847 
2853 {
2855  !(HasBit(this->callback_mask, CBM_IND_PRODUCTION_256_TICKS) || HasBit(this->callback_mask, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks
2856  !(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
2857 }
2858 
2859 static CommandCost TerraformTile_Industry(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
2860 {
2861  if (AutoslopeEnabled()) {
2862  /* We imitate here TTDP's behaviour:
2863  * - Both new and old slope must not be steep.
2864  * - TileMaxZ must not be changed.
2865  * - Allow autoslope by default.
2866  * - Disallow autoslope if callback succeeds and returns non-zero.
2867  */
2868  Slope tileh_old = GetTileSlope(tile);
2869  /* TileMaxZ must not be changed. Slopes must not be steep. */
2870  if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
2871  const IndustryGfx gfx = GetIndustryGfx(tile);
2872  const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
2873 
2874  /* Call callback 3C 'disable autosloping for industry tiles'. */
2875  if (HasBit(itspec->callback_mask, CBM_INDT_AUTOSLOPE)) {
2876  /* If the callback fails, allow autoslope. */
2877  uint16 res = GetIndustryTileCallback(CBID_INDTILE_AUTOSLOPE, 0, 0, gfx, Industry::GetByTile(tile), tile);
2878  if (res == CALLBACK_FAILED || !ConvertBooleanCallback(itspec->grf_prop.grffile, CBID_INDTILE_AUTOSLOPE, res)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2879  } else {
2880  /* allow autoslope */
2881  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2882  }
2883  }
2884  }
2885  return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
2886 }
2887 
2888 extern const TileTypeProcs _tile_type_industry_procs = {
2889  DrawTile_Industry, // draw_tile_proc
2890  GetSlopePixelZ_Industry, // get_slope_z_proc
2891  ClearTile_Industry, // clear_tile_proc
2892  AddAcceptedCargo_Industry, // add_accepted_cargo_proc
2893  GetTileDesc_Industry, // get_tile_desc_proc
2894  GetTileTrackStatus_Industry, // get_tile_track_status_proc
2895  ClickTile_Industry, // click_tile_proc
2896  AnimateTile_Industry, // animate_tile_proc
2897  TileLoop_Industry, // tile_loop_proc
2898  ChangeTileOwner_Industry, // change_tile_owner_proc
2899  NULL, // add_produced_cargo_proc
2900  NULL, // vehicle_enter_tile_proc
2901  GetFoundation_Industry, // get_foundation_proc
2902  TerraformTile_Industry, // terraform_tile_proc
2903 };
CargoID accepts_cargo[INDUSTRY_NUM_INPUTS]
16 accepted cargoes.
Definition: industrytype.h:118
static void ResetIndustryCounts()
Resets industry counts.
Definition: industry.h:154
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
don&#39;t allow building on structures
Definition: command_type.h:346
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:355
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
void ClampToMap()
Clamp the tile area to map borders.
Definition: tilearea.cpp:123
byte image_2
image offset 2
Definition: industry_land.h:23
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:77
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition: game_core.cpp:134
Trigger whenever the construction state changes.
bool enabled
entity still available (by default true).newgrf can disable it, though
Definition: industrytype.h:137
byte production_rate[INDUSTRY_NUM_OUTPUTS]
production rate for each cargo
Definition: industry.h:47
void SetupTargetCount()
Decide how many industries of each type are needed.
static TropicZone GetTropicZone(TileIndex tile)
Get the tropic zone.
Definition: tile_map.h: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
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:74
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:3179
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:1153
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
while editing a scenario
Definition: industrytype.h:58
static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, const IndustryTileTable *it, int type)
This function tries to flatten out the land below an industry, without damaging the surroundings too ...
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
uint16 counter
used for animation and/or production (if available cargo)
Definition: industry.h:55
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition: vehicle.cpp:539
below this level, the industry is set to be closing
Definition: industry.h:33
void DeleteIndustryNews(IndustryID iid)
Remove news regarding given industry.
Definition: news_gui.cpp:833
int32 TileIndexDiff
An offset value between to tiles.
Definition: map_func.h:156
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:106
const char * grf
newGRF used for the tile contents
Definition: tile_cmd.h:63
OwnerByte founder
Founder of the industry.
Definition: industry.h:65
static bool IsSuitableForFarmField(TileIndex tile, bool allow_fields)
Check whether the tile can be replaced by a farm field.
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:43
uint32 prospecting_chance
Chance prospecting succeeds.
Definition: industrytype.h:108
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:49
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
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:69
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
CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type)
Check that the industry callback allows creation of the industry.
uint8 construction_type
Way the industry was constructed (.
Definition: industry.h:67
no flag is set
Definition: command_type.h:344
from the Fund/build window
default level set when the industry is created
Definition: industry.h:34
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:120
periodically plants fields around itself (temp and arctic farms)
Definition: industrytype.h:64
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:71
Functions related to vehicles.
uint16 callback_mask
Bitmask of industry callbacks that have to be called.
Definition: industrytype.h:135
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:207
CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type)
Check the slope of a tile of a new industry.
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:32
Defines the internal data of a functional industry.
Definition: industry.h:41
during random map creation
Definition: industrytype.h:57
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:258
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:153
Like factories.
Definition: industrytype.h:33
void IndustryProductionCallback(Industry *ind, int reason)
Get the industry production callback and apply it to the industry.
Northeast, upper right on your monitor.
A special vehicle is one of the following:
static bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition: slope_func.h:38
static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, const IndustryTileTable *it, byte layout, Town *t, Owner founder, uint16 initial_random_bits)
Put an industry on the map.
Date last_cargo_accepted_at[INDUSTRY_NUM_INPUTS]
Last day each cargo type was accepted by this industry.
Definition: industry.h:68
static byte GetIndustryAnimationLoop(TileIndex tile)
Get the animation loop number.
Definition: industry_map.h:201
check industry construction on given area
Simple vector template class.
Map accessors for tree tiles.
Functions related to world/map generation.
byte was_cargo_delivered
flag that indicate this has been the closest industry chosen for cargo delivery by a station...
Definition: industry.h:61
const IndustryTileTable *const * table
List of the tiles composing the industry.
Definition: industrytype.h:104
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:71
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.
control special effects
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:69
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:35
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
static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCommandFlag flags, const IndustrySpec *indspec, uint itspec_index, uint32 random_var8f, uint16 random_initial_bits, Owner founder, IndustryAvailabilityCallType creation_type, Industry **ip)
Helper function for Build/Fund an industry.
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.
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:128
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:59
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:124
IndustryBuildData _industry_builder
In-game manager of industries.
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:165
can only be built in towns (arctic/tropic banks, water tower)
Definition: industrytype.h:68
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:81
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:181
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
CompanyByte _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:46
Date construction_date
Date of the construction of the industry.
Definition: industry.h:66
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).
The object is owned by a superuser / goal script.
Definition: company_type.h:29
static IndustryGfx GetTranslatedIndustryTileID(IndustryGfx gfx)
Do industry gfx ID translation for NewGRFs.
Definition: industrytype.h:189
Data for managing the number and type of industries in the game.
Definition: industry.h:188
Invalid cargo type.
Definition: cargo_type.h:70
int16 y
The y value of the coordinate.
Definition: map_type.h:61
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:154
static bool IsBridgeAbove(TileIndex t)
checks if a bridge is set above the ground of this tile
Definition: bridge_map.h:45
const uint8 * random_sounds
array of random sounds.
Definition: industrytype.h:133
uint8 industry_platform
the amount of flat land around an industry
void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel wl, int x=0, int y=0, const GRFFile *textref_stack_grffile=NULL, uint textref_stack_size=0, const uint32 *textref_stack=NULL)
Display an error message in a window.
Definition: error_gui.cpp:378
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:3329
uint16 this_month_production[INDUSTRY_NUM_OUTPUTS]
stats of this month&#39;s production per cargo
Definition: industry.h:50
Aircraft vehicle type.
Definition: vehicle_type.h:29
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".
OrthogonalTileArea TileArea
Shorthand for the much more common orthogonal tile area.
Definition: tilearea_type.h:96
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
can only be built after 1960 (oil rigs)
Definition: industrytype.h:73
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:440
The y axis.
bool IsRawIndustry() const
Is an industry with the spec a raw industry?
uint Length() const
Get the number of items in the list.
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:73
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
bool Contains(const T &item) const
Tests whether a item is present in the vector.
Like power plants and banks.
Definition: industrytype.h:30
static void ChangeIndustryProduction(Industry *i, bool monthly)
Change industry production or do closure.
uint16 this_month_transported[INDUSTRY_NUM_OUTPUTS]
stats of this month&#39;s transport per cargo
Definition: industry.h:51
controls random production change
either by user or random creation process
Definition: industrytype.h:56
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:60
bool multiple_industry_per_town
allow many industries of the same type per town
bool IsType(OrderType type) const
Check whether this order is of the given type.
Definition: order_base.h:63
decides if default foundations need to be drawn
const StationList * GetStations()
Run a tile loop to find stations around a tile, on demand.
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:343
Called to determine the type (if any) of foundation to draw for industry tile.
Southeast.
Southwest.
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:76
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:91
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
int16 x
The x value of the coordinate.
Definition: map_type.h:60
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:57
static PaletteID GroundSpritePaletteTransform(SpriteID image, PaletteID pal, PaletteID default_pal)
Applies PALETTE_MODIFIER_COLOUR to a palette entry of a ground sprite.
Definition: sprite.h: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:125
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
#define MKEND()
Macro for end of list marker in arrays of LegendAndColour.
End marker of the industry check procedures.
Definition: industrytype.h:50
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:552
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:155
decides amount of cargo acceptance
CargoLabel label
Unique label of the cargo type.
Definition: cargotype.h:58
TileArea location
Location of the industry.
Definition: industry.h:42
static int WhoCanServiceIndustry(Industry *ind)
Compute who can service the industry.
uint16 last_month_production[INDUSTRY_NUM_OUTPUTS]
total units produced per cargo in the last full month
Definition: industry.h:53
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
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:44
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:348
Defines the data structure for constructing industry.
Definition: industrytype.h:103
TerraGenesis Perlin landscape generator.
Definition: genworld.h:22
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:147
Smoke at copper mine.
The tile has no ownership.
Definition: company_type.h:27
Northwest.
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:1785
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:167
Industry should be positioned near edge of the map.
Definition: industrytype.h:43
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:49
IndustryAvailabilityCallType
From where has callback CBID_INDUSTRY_PROBABILITY been called.
static void PlaceInitialIndustry(IndustryType type, bool try_hard)
Try to build a industry on the map.
Industry view; Window numbers:
Definition: window_type.h:358
DiagDirection
Enumeration for diagonal directions.
uint16 incoming_cargo_waiting[INDUSTRY_NUM_INPUTS]
incoming cargo waiting to be processed
Definition: industry.h:46
static CommandCost CheckIfFarEnoughFromConflictingIndustry(TileIndex tile, int type)
Check that the new industry is far enough from conflicting industries.
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
Road vehicle type.
Definition: vehicle_type.h:27
IndustryBehaviour behaviour
How this industry will behave, and how others entities can use it.
Definition: industrytype.h:122
byte prod_level
general production level
Definition: industry.h:48
byte appear_ingame[NUM_LANDSCAPE]
Probability of appearance in game.
Definition: industrytype.h:130
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:138
static bool IsWaterTile(TileIndex t)
Is it a water tile with plain water?
Definition: water_map.h:184
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:42
#define MAX_UVALUE(type)
The largest value that can be entered in a variable.
Definition: stdafx.h:491
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:65
Data for managing the number of industries of a single industry type.
Definition: industry.h:173
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
uint DistanceFromEdge(TileIndex tile)
Param the minimum distance to an edge.
Definition: map.cpp:219
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:654
Transfer all cargo onto the platform.
Definition: order_type.h:61
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:125
Base class for all pools.
Definition: pool_type.hpp:83
Ship vehicle type.
Definition: vehicle_type.h:28
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:163
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:224
static uint16 GetIndustryGamePlayProbability(IndustryType it, byte *min_number)
Compute the probability for constructing a new industry during game play.
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1143
Construction costs.
Definition: economy_type.h:151
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
byte num_table
Number of elements in the table.
Definition: industrytype.h:105
execute the given command
Definition: command_type.h:345
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:152
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.
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:61
uint16 produced_cargo_waiting[INDUSTRY_NUM_OUTPUTS]
amount of cargo produced per cargo
Definition: industry.h:45
byte oil_refinery_limit
distance oil refineries allowed from map edge
DestinationID GetDestination() const
Gets the destination of this order.
Definition: order_base.h:96
during creation of random ingame industry
is built on water (oil rig)
Definition: industrytype.h:66
byte minimal_cargo
minimum amount of cargo transported to the stations.
Definition: industrytype.h:117
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:131
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:118
CompanyByte _current_company
Company currently doing an action.
Definition: company_cmd.cpp:47
Set of callback functions for performing tile operations of a given tile type.
Definition: tile_cmd.h:144
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:164
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.
A town owns the tile, or a town is expanding.
Definition: company_type.h:26
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:89
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
Source/destination is an industry.
Definition: cargo_type.h:149
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:126
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
OwnerByte owner
Which company owns the vehicle?
Definition: vehicle_base.h:273
byte anim_next
Next frame in an animation.
Definition: industrytype.h:156
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:83
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:275
Slope
Enumeration for the slope-type.
Definition: slope_type.h:50
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:403
static void DecIndustryTypeCount(IndustryType type)
Decrement the count of industries for this type.
Definition: industry.h:136
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
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.
static void RecomputeIndustriesNearForAll()
Recomputes Station::industries_near for all stations.
Definition: station.cpp:377
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:62
uint32 probability
Relative probability of building this industry.
Definition: industry.h:174
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:160
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:570
IndustryType conflicting[3]
Industries this industry cannot be close to.
Definition: industrytype.h:109
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-NULL) 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:190
Fields are planted around when built (all farms)
Definition: industrytype.h:70
Smoke of power plant (industry).
uint16 last_month_transported[INDUSTRY_NUM_OUTPUTS]
total units transported per cargo in the last full month
Definition: industry.h:54
Allow closing down the last instance of this type.
Definition: industrytype.h:82
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.
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:809
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:132
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:175
static bool HasBit(const T x, const uint8 y)
Checks if a bit in a value is set.
static bool HasTileWaterClass(TileIndex t)
Checks whether the tile has an waterclass associated.
Definition: water_map.h:95
StringID production_up_text
Message appearing when the industry&#39;s production is increasing.
Definition: industrytype.h:127
static bool SearchLumberMillTrees(TileIndex tile, void *user_data)
Search callback function for ChopLumberMillTrees.
void Restore()
Restore the variable.
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:110
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
bool TileBelongsToIndustry(TileIndex tile) const
Check if a given tile belongs to this industry.
Definition: industry.h:85
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:151
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
Other expenses.
Definition: economy_type.h:163
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition: industry.h:112
Very few industries at game start.
Definition: settings_type.h:46
uint16 target_count
Desired number of industries of this type.
Definition: industry.h:176
Owner
Enum for all companies/owners.
Definition: company_type.h:20
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:60
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:350
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:130
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:67
static void ChopLumberMillTrees(Industry *i)
Perform a circular search around the Lumber Mill in order to find trees to cut.
byte last_month_pct_transported[INDUSTRY_NUM_OUTPUTS]
percentage transported per cargo in the last full month
Definition: industry.h:52
static CheckNewIndustryProc *const _check_new_industry_procs[CHECK_END]
Check functions for different types of industry.
SpriteID sprite
The &#39;real&#39; sprite.
Definition: gfx_type.h:25
OwnerByte owner
owner of the industry. Which SHOULD always be (imho) OWNER_NONE
Definition: industry.h:58
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:32
Structure contains cached list of stations nearby.
Definition: station_type.h:104
void FindStationsAroundTiles(const TileArea &location, StationList *stations)
Find all stations around a rectangular producer (industry, house, headquarter, ...)
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:72
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
The tile/execution is done by "water".
Definition: company_type.h:28
static bool TransportIndustryGoods(TileIndex tile)
Move produced cargo from industry to nearby stations.
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.
VehicleTypeByte type
Type of vehicle.
Definition: vehicle_type.h:56
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:446
Functions related to effect vehicles.
static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, uint itspec_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool *custom_shape_check=NULL)
Are the tiles of the industry free?
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
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 TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition: map_func.h:165
static byte GetIndustryConstructionCounter(TileIndex tile)
Returns this industry tile&#39;s construction counter value.
Definition: industry_map.h:164
An invalid owner.
Definition: company_type.h:31
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:3279
byte HighestSnowLine()
Get the highest possible snow line height, either variable or static.
Definition: landscape.cpp:660
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:161
give a custom colour to newly build industries
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
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
Train vehicle type.
Definition: vehicle_type.h:26
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