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) {
1724  for (size_t ci = 0; ci < lengthof(i->last_month_production); ci++) {
1725  i->last_month_production[ci] = i->produced_cargo_waiting[ci] * 8;
1726  i->produced_cargo_waiting[ci] = 0;
1727  }
1728  }
1729 
1730  for (size_t ci = 0; ci < lengthof(i->last_month_production); ci++) {
1731  i->last_month_production[ci] += i->production_rate[ci] * 8;
1732  }
1733  }
1734 
1735  if (HasBit(indspec->callback_mask, CBM_IND_DECIDE_COLOUR)) {
1736  uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE);
1737  if (res != CALLBACK_FAILED) {
1738  if (GB(res, 4, 11) != 0) ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_DECIDE_COLOUR, res);
1739  i->random_colour = GB(res, 0, 4);
1740  }
1741  }
1742 
1744  /* Clear all input cargo types */
1745  for (uint j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID;
1746  /* Query actual types */
1747  uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? lengthof(i->accepts_cargo) : 3;
1748  for (uint j = 0; j < maxcargoes; j++) {
1750  if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
1751  if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) {
1753  break;
1754  }
1755  CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
1756  if (std::find(indspec->accepts_cargo, endof(indspec->accepts_cargo), cargo) == endof(indspec->accepts_cargo)) {
1757  /* Cargo not in spec, error in NewGRF */
1759  break;
1760  }
1761  if (std::find(i->accepts_cargo, i->accepts_cargo + j, cargo) != i->accepts_cargo + j) {
1762  /* Duplicate cargo */
1764  break;
1765  }
1766  i->accepts_cargo[j] = cargo;
1767  }
1768  }
1769 
1771  /* Clear all output cargo types */
1772  for (uint j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID;
1773  /* Query actual types */
1774  uint maxcargoes = (indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED) ? lengthof(i->produced_cargo) : 2;
1775  for (uint j = 0; j < maxcargoes; j++) {
1777  if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
1778  if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) {
1780  break;
1781  }
1782  CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
1783  if (std::find(indspec->produced_cargo, endof(indspec->produced_cargo), cargo) == endof(indspec->produced_cargo)) {
1784  /* Cargo not in spec, error in NewGRF */
1786  break;
1787  }
1788  if (std::find(i->produced_cargo, i->produced_cargo + j, cargo) != i->produced_cargo + j) {
1789  /* Duplicate cargo */
1791  break;
1792  }
1793  i->produced_cargo[j] = cargo;
1794  }
1795  }
1796 
1797  /* Plant the tiles */
1798 
1799  do {
1800  TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
1801 
1802  if (it->gfx != GFX_WATERTILE_SPECIALCHECK) {
1803  i->location.Add(cur_tile);
1804 
1805  WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID);
1806 
1808 
1809  MakeIndustry(cur_tile, i->index, it->gfx, Random(), wc);
1810 
1811  if (_generating_world) {
1812  SetIndustryConstructionCounter(cur_tile, 3);
1813  SetIndustryConstructionStage(cur_tile, 2);
1814  }
1815 
1816  /* it->gfx is stored in the map. But the translated ID cur_gfx is the interesting one */
1817  IndustryGfx cur_gfx = GetTranslatedIndustryTileID(it->gfx);
1818  const IndustryTileSpec *its = GetIndustryTileSpec(cur_gfx);
1820  }
1821  } while ((++it)->ti.x != -0x80);
1822 
1824  for (uint j = 0; j != 50; j++) PlantRandomFarmField(i);
1825  }
1827 
1829 }
1830 
1847 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)
1848 {
1849  assert(itspec_index < indspec->num_table);
1850  const IndustryTileTable *it = indspec->table[itspec_index];
1851  bool custom_shape_check = false;
1852 
1853  *ip = NULL;
1854 
1855  SmallVector<ClearedObjectArea, 1> object_areas(_cleared_object_areas);
1856  CommandCost ret = CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, random_initial_bits, founder, creation_type, &custom_shape_check);
1857  _cleared_object_areas = object_areas;
1858  if (ret.Failed()) return ret;
1859 
1860  if (HasBit(GetIndustrySpec(type)->callback_mask, CBM_IND_LOCATION)) {
1861  ret = CheckIfCallBackAllowsCreation(tile, type, itspec_index, random_var8f, random_initial_bits, founder, creation_type);
1862  } else {
1863  ret = _check_new_industry_procs[indspec->check_proc](tile);
1864  }
1865  if (ret.Failed()) return ret;
1866 
1868  !_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER, it, type)) {
1869  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1870  }
1871 
1872  ret = CheckIfFarEnoughFromConflictingIndustry(tile, type);
1873  if (ret.Failed()) return ret;
1874 
1875  Town *t = NULL;
1876  ret = FindTownForIndustry(tile, type, &t);
1877  if (ret.Failed()) return ret;
1878  assert(t != NULL);
1879 
1880  ret = CheckIfIndustryIsAllowed(tile, type, t);
1881  if (ret.Failed()) return ret;
1882 
1883  if (!Industry::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_INDUSTRIES);
1884 
1885  if (flags & DC_EXEC) {
1886  *ip = new Industry(tile);
1887  if (!custom_shape_check) CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER | DC_EXEC, it, type);
1888  DoCreateNewIndustry(*ip, tile, type, it, itspec_index, t, founder, random_initial_bits);
1889  }
1890 
1891  return CommandCost();
1892 }
1893 
1906 CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1907 {
1908  IndustryType it = GB(p1, 0, 8);
1909  if (it >= NUM_INDUSTRYTYPES) return CMD_ERROR;
1910 
1911  const IndustrySpec *indspec = GetIndustrySpec(it);
1912 
1913  /* Check if the to-be built/founded industry is available for this climate. */
1914  if (!indspec->enabled || indspec->num_table == 0) return CMD_ERROR;
1915 
1916  /* If the setting for raw-material industries is not on, you cannot build raw-material industries.
1917  * Raw material industries are industries that do not accept cargo (at least for now) */
1918  if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 0 && indspec->IsRawIndustry()) {
1919  return CMD_ERROR;
1920  }
1921 
1922  if (_game_mode != GM_EDITOR && GetIndustryProbabilityCallback(it, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, 1) == 0) {
1923  return CMD_ERROR;
1924  }
1925 
1926  Randomizer randomizer;
1927  randomizer.SetSeed(p2);
1928  uint16 random_initial_bits = GB(p2, 0, 16);
1929  uint32 random_var8f = randomizer.Next();
1930  int num_layouts = indspec->num_table;
1931  CommandCost ret = CommandCost(STR_ERROR_SITE_UNSUITABLE);
1932  const bool deity_prospect = _current_company == OWNER_DEITY && !HasBit(p1, 16);
1933 
1934  Industry *ind = NULL;
1935  if (deity_prospect || (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry())) {
1936  if (flags & DC_EXEC) {
1937  /* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */
1938  Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
1939  /* Prospecting has a chance to fail, however we cannot guarantee that something can
1940  * be built on the map, so the chance gets lower when the map is fuller, but there
1941  * is nothing we can really do about that. */
1942  if (deity_prospect || Random() <= indspec->prospecting_chance) {
1943  for (int i = 0; i < 5000; i++) {
1944  /* We should not have more than one Random() in a function call
1945  * because parameter evaluation order is not guaranteed in the c++ standard
1946  */
1947  tile = RandomTile();
1948  /* Start with a random layout */
1949  int layout = RandomRange(num_layouts);
1950  /* Check now each layout, starting with the random one */
1951  for (int j = 0; j < num_layouts; j++) {
1952  layout = (layout + 1) % num_layouts;
1953  ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, cur_company.GetOriginalValue(), _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_PROSPECTCREATION, &ind);
1954  if (ret.Succeeded()) break;
1955  }
1956  if (ret.Succeeded()) break;
1957  }
1958  }
1959  cur_company.Restore();
1960  }
1961  } else {
1962  int layout = GB(p1, 8, 8);
1963  if (layout >= num_layouts) return CMD_ERROR;
1964 
1965  /* Check subsequently each layout, starting with the given layout in p1 */
1966  for (int i = 0; i < num_layouts; i++) {
1967  layout = (layout + 1) % num_layouts;
1968  ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, _current_company, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, &ind);
1969  if (ret.Succeeded()) break;
1970  }
1971 
1972  /* If it still failed, there's no suitable layout to build here, return the error */
1973  if (ret.Failed()) return ret;
1974  }
1975 
1976  if ((flags & DC_EXEC) && ind != NULL && _game_mode != GM_EDITOR) {
1978  }
1979 
1980  return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
1981 }
1982 
1983 
1991 static Industry *CreateNewIndustry(TileIndex tile, IndustryType type, IndustryAvailabilityCallType creation_type)
1992 {
1993  const IndustrySpec *indspec = GetIndustrySpec(type);
1994 
1995  uint32 seed = Random();
1996  uint32 seed2 = Random();
1997  Industry *i = NULL;
1998  CommandCost ret = CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, RandomRange(indspec->num_table), seed, GB(seed2, 0, 16), OWNER_NONE, creation_type, &i);
1999  assert(i != NULL || ret.Failed());
2000  return i;
2001 }
2002 
2009 static uint32 GetScaledIndustryGenerationProbability(IndustryType it, bool *force_at_least_one)
2010 {
2011  const IndustrySpec *ind_spc = GetIndustrySpec(it);
2012  uint32 chance = ind_spc->appear_creation[_settings_game.game_creation.landscape] * 16; // * 16 to increase precision
2013  if (!ind_spc->enabled || ind_spc->num_table == 0 ||
2014  (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) ||
2015  (chance = GetIndustryProbabilityCallback(it, IACT_MAPGENERATION, chance)) == 0) {
2016  *force_at_least_one = false;
2017  return 0;
2018  } else {
2019  /* We want industries appearing at coast to appear less often on bigger maps, as length of coast increases slower than map area.
2020  * For simplicity we scale in both cases, though scaling the probabilities of all industries has no effect. */
2021  chance = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? ScaleByMapSize1D(chance) : ScaleByMapSize(chance);
2022 
2023  *force_at_least_one = (chance > 0) && !(ind_spc->behaviour & INDUSTRYBEH_NOBUILT_MAPCREATION) && (_game_mode != GM_EDITOR);
2024  return chance;
2025  }
2026 }
2027 
2034 static uint16 GetIndustryGamePlayProbability(IndustryType it, byte *min_number)
2035 {
2037  *min_number = 0;
2038  return 0;
2039  }
2040 
2041  const IndustrySpec *ind_spc = GetIndustrySpec(it);
2042  byte chance = ind_spc->appear_ingame[_settings_game.game_creation.landscape];
2043  if (!ind_spc->enabled || ind_spc->num_table == 0 ||
2044  ((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && _cur_year > 1950) ||
2045  ((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && _cur_year < 1960) ||
2046  (chance = GetIndustryProbabilityCallback(it, IACT_RANDOMCREATION, chance)) == 0) {
2047  *min_number = 0;
2048  return 0;
2049  }
2050  *min_number = (ind_spc->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) ? 1 : 0;
2051  return chance;
2052 }
2053 
2059 {
2060  /* Number of industries on a 256x256 map. */
2061  static const uint16 numof_industry_table[] = {
2062  0, // none
2063  0, // minimal
2064  10, // very low
2065  25, // low
2066  55, // normal
2067  80, // high
2068  };
2069 
2070  assert(lengthof(numof_industry_table) == ID_END);
2071  uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.industry_density : (uint)ID_VERY_LOW;
2072  return min(IndustryPool::MAX_SIZE, ScaleByMapSize(numof_industry_table[difficulty]));
2073 }
2074 
2083 static Industry *PlaceIndustry(IndustryType type, IndustryAvailabilityCallType creation_type, bool try_hard)
2084 {
2085  uint tries = try_hard ? 10000u : 2000u;
2086  for (; tries > 0; tries--) {
2087  Industry *ind = CreateNewIndustry(RandomTile(), type, creation_type);
2088  if (ind != NULL) return ind;
2089  }
2090  return NULL;
2091 }
2092 
2098 static void PlaceInitialIndustry(IndustryType type, bool try_hard)
2099 {
2100  Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2101 
2103  PlaceIndustry(type, IACT_MAPGENERATION, try_hard);
2104 
2105  cur_company.Restore();
2106 }
2107 
2113 {
2114  int total = 0;
2115  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) total += Industry::GetIndustryTypeCount(it);
2116  return total;
2117 }
2118 
2119 
2122 {
2123  this->probability = 0;
2124  this->min_number = 0;
2125  this->target_count = 0;
2126  this->max_wait = 1;
2127  this->wait_count = 0;
2128 }
2129 
2132 {
2133  this->wanted_inds = GetCurrentTotalNumberOfIndustries() << 16;
2134 
2135  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2136  this->builddata[it].Reset();
2137  }
2138 }
2139 
2142 {
2143  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.
2144  if (_settings_game.difficulty.industry_density == ID_FUND_ONLY) return; // 'no industries' setting.
2145 
2146  /* To prevent running out of unused industries for the player to connect,
2147  * add a fraction of new industries each month, but only if the manager can keep up. */
2148  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).
2149  if (GetCurrentTotalNumberOfIndustries() + max_behind >= (this->wanted_inds >> 16)) {
2150  this->wanted_inds += ScaleByMapSize(NEWINDS_PER_MONTH);
2151  }
2152 }
2153 
2159 {
2160  if (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) return; // No industries in the game.
2161 
2162  uint32 industry_probs[NUM_INDUSTRYTYPES];
2163  bool force_at_least_one[NUM_INDUSTRYTYPES];
2164  uint32 total_prob = 0;
2165  uint num_forced = 0;
2166 
2167  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2168  industry_probs[it] = GetScaledIndustryGenerationProbability(it, force_at_least_one + it);
2169  total_prob += industry_probs[it];
2170  if (force_at_least_one[it]) num_forced++;
2171  }
2172 
2173  uint total_amount = GetNumberOfIndustries();
2174  if (total_prob == 0 || total_amount < num_forced) {
2175  /* Only place the forced ones */
2176  total_amount = num_forced;
2177  }
2178 
2180 
2181  /* Try to build one industry per type independent of any probabilities */
2182  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2183  if (force_at_least_one[it]) {
2184  assert(total_amount > 0);
2185  total_amount--;
2186  PlaceInitialIndustry(it, true);
2187  }
2188  }
2189 
2190  /* Add the remaining industries according to their probabilities */
2191  for (uint i = 0; i < total_amount; i++) {
2192  uint32 r = RandomRange(total_prob);
2193  IndustryType it = 0;
2194  while (r >= industry_probs[it]) {
2195  r -= industry_probs[it];
2196  it++;
2197  assert(it < NUM_INDUSTRYTYPES);
2198  }
2199  assert(industry_probs[it] > 0);
2200  PlaceInitialIndustry(it, false);
2201  }
2202  _industry_builder.Reset();
2203 }
2204 
2210 {
2211  for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
2212  if (i->produced_cargo[j] != CT_INVALID) {
2213  byte pct = 0;
2214  if (i->this_month_production[j] != 0) {
2216  pct = min(i->this_month_transported[j] * 256 / i->this_month_production[j], 255);
2217  }
2218  i->last_month_pct_transported[j] = pct;
2219 
2221  i->this_month_production[j] = 0;
2222 
2224  i->this_month_transported[j] = 0;
2225  }
2226  }
2227 }
2228 
2234 {
2235  const IndustrySpec *indspec = GetIndustrySpec(this->type);
2236  assert(!indspec->UsesSmoothEconomy());
2237 
2238  /* Rates are rounded up, so e.g. oilrig always produces some passengers */
2239  for (size_t i = 0; i < lengthof(this->production_rate); i++) {
2240  this->production_rate[i] = min(CeilDiv(indspec->production_rate[i] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF);
2241  }
2242 }
2243 
2244 
2251 {
2252  byte min_number;
2253  uint32 probability = GetIndustryGamePlayProbability(it, &min_number);
2254  bool changed = min_number != this->min_number || probability != this->probability;
2255  this->min_number = min_number;
2256  this->probability = probability;
2257  return changed;
2258 }
2259 
2262 {
2263  bool changed = false;
2264  uint num_planned = 0; // Number of industries planned in the industry build data.
2265  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2266  changed |= this->builddata[it].GetIndustryTypeData(it);
2267  num_planned += this->builddata[it].target_count;
2268  }
2269  uint total_amount = this->wanted_inds >> 16; // Desired total number of industries.
2270  changed |= num_planned != total_amount;
2271  if (!changed) return; // All industries are still the same, no need to re-randomize.
2272 
2273  /* Initialize the target counts. */
2274  uint force_build = 0; // Number of industries that should always be available.
2275  uint32 total_prob = 0; // Sum of probabilities.
2276  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2277  IndustryTypeBuildData *ibd = this->builddata + it;
2278  force_build += ibd->min_number;
2279  ibd->target_count = ibd->min_number;
2280  total_prob += ibd->probability;
2281  }
2282 
2283  if (total_prob == 0) return; // No buildable industries.
2284 
2285  /* Subtract forced industries from the number of industries available for construction. */
2286  total_amount = (total_amount <= force_build) ? 0 : total_amount - force_build;
2287 
2288  /* Assign number of industries that should be aimed for, by using the probability as a weight. */
2289  while (total_amount > 0) {
2290  uint32 r = RandomRange(total_prob);
2291  IndustryType it = 0;
2292  while (r >= this->builddata[it].probability) {
2293  r -= this->builddata[it].probability;
2294  it++;
2295  assert(it < NUM_INDUSTRYTYPES);
2296  }
2297  assert(this->builddata[it].probability > 0);
2298  this->builddata[it].target_count++;
2299  total_amount--;
2300  }
2301 }
2302 
2307 {
2308  this->SetupTargetCount();
2309 
2310  int missing = 0; // Number of industries that need to be build.
2311  uint count = 0; // Number of industry types eligible for build.
2312  uint32 total_prob = 0; // Sum of probabilities.
2313  IndustryType forced_build = NUM_INDUSTRYTYPES; // Industry type that should be forcibly build.
2314  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2315  int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
2316  missing += difference;
2317  if (this->builddata[it].wait_count > 0) continue; // This type may not be built now.
2318  if (difference > 0) {
2319  if (Industry::GetIndustryTypeCount(it) == 0 && this->builddata[it].min_number > 0) {
2320  /* An industry that should exist at least once, is not available. Force it, trying the most needed one first. */
2321  if (forced_build == NUM_INDUSTRYTYPES ||
2322  difference > this->builddata[forced_build].target_count - Industry::GetIndustryTypeCount(forced_build)) {
2323  forced_build = it;
2324  }
2325  }
2326  total_prob += difference;
2327  count++;
2328  }
2329  }
2330 
2331  if (EconomyIsInRecession() || (forced_build == NUM_INDUSTRYTYPES && (missing <= 0 || total_prob == 0))) count = 0; // Skip creation of an industry.
2332 
2333  if (count >= 1) {
2334  /* If not forced, pick a weighted random industry to build.
2335  * For the case that count == 1, there is no need to draw a random number. */
2336  IndustryType it;
2337  if (forced_build != NUM_INDUSTRYTYPES) {
2338  it = forced_build;
2339  } else {
2340  /* Non-forced, select an industry type to build (weighted random). */
2341  uint32 r = 0; // Initialized to silence the compiler.
2342  if (count > 1) r = RandomRange(total_prob);
2343  for (it = 0; it < NUM_INDUSTRYTYPES; it++) {
2344  if (this->builddata[it].wait_count > 0) continue; // Type may not be built now.
2345  int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
2346  if (difference <= 0) continue; // Too many of this kind.
2347  if (count == 1) break;
2348  if (r < (uint)difference) break;
2349  r -= difference;
2350  }
2351  assert(it < NUM_INDUSTRYTYPES && this->builddata[it].target_count > Industry::GetIndustryTypeCount(it));
2352  }
2353 
2354  /* Try to create the industry. */
2355  const Industry *ind = PlaceIndustry(it, IACT_RANDOMCREATION, false);
2356  if (ind == NULL) {
2357  this->builddata[it].wait_count = this->builddata[it].max_wait + 1; // Compensate for decrementing below.
2358  this->builddata[it].max_wait = min(1000, this->builddata[it].max_wait + 2);
2359  } else {
2361  this->builddata[it].max_wait = max(this->builddata[it].max_wait / 2, 1); // Reduce waiting time of the industry type.
2362  }
2363  }
2364 
2365  /* Decrement wait counters. */
2366  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2367  if (this->builddata[it].wait_count > 0) this->builddata[it].wait_count--;
2368  }
2369 }
2370 
2379 static bool CheckIndustryCloseDownProtection(IndustryType type)
2380 {
2381  const IndustrySpec *indspec = GetIndustrySpec(type);
2382 
2383  /* oil wells (or the industries with that flag set) are always allowed to closedown */
2384  if ((indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE) return false;
2385  return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) == 0 && Industry::GetIndustryTypeCount(type) <= 1;
2386 }
2387 
2397 static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accepts, bool *c_produces)
2398 {
2399  if (cargo == CT_INVALID) return;
2400 
2401  /* Check for acceptance of cargo */
2402  for (byte j = 0; j < lengthof(ind->accepts_cargo); j++) {
2403  if (cargo == ind->accepts_cargo[j] && !IndustryTemporarilyRefusesCargo(ind, cargo)) {
2404  *c_accepts = true;
2405  break;
2406  }
2407  }
2408 
2409  /* Check for produced cargo */
2410  for (byte j = 0; j < lengthof(ind->produced_cargo); j++) {
2411  if (cargo == ind->produced_cargo[j]) {
2412  *c_produces = true;
2413  break;
2414  }
2415  }
2416 }
2417 
2432 {
2433  /* Find all stations within reach of the industry */
2434  StationList stations;
2435  FindStationsAroundTiles(ind->location, &stations);
2436 
2437  if (stations.Length() == 0) return 0; // No stations found at all => nobody services
2438 
2439  const Vehicle *v;
2440  int result = 0;
2441  FOR_ALL_VEHICLES(v) {
2442  /* Is it worthwhile to try this vehicle? */
2443  if (v->owner != _local_company && result != 0) continue;
2444 
2445  /* Check whether it accepts the right kind of cargo */
2446  bool c_accepts = false;
2447  bool c_produces = false;
2448  if (v->type == VEH_TRAIN && v->IsFrontEngine()) {
2449  for (const Vehicle *u = v; u != NULL; u = u->Next()) {
2450  CanCargoServiceIndustry(u->cargo_type, ind, &c_accepts, &c_produces);
2451  }
2452  } else if (v->type == VEH_ROAD || v->type == VEH_SHIP || v->type == VEH_AIRCRAFT) {
2453  CanCargoServiceIndustry(v->cargo_type, ind, &c_accepts, &c_produces);
2454  } else {
2455  continue;
2456  }
2457  if (!c_accepts && !c_produces) continue; // Wrong cargo
2458 
2459  /* Check orders of the vehicle.
2460  * We cannot check the first of shared orders only, since the first vehicle in such a chain
2461  * may have a different cargo type.
2462  */
2463  const Order *o;
2464  FOR_VEHICLE_ORDERS(v, o) {
2465  if (o->IsType(OT_GOTO_STATION) && !(o->GetUnloadType() & OUFB_TRANSFER)) {
2466  /* Vehicle visits a station to load or unload */
2467  Station *st = Station::Get(o->GetDestination());
2468  assert(st != NULL);
2469 
2470  /* Same cargo produced by industry is dropped here => not serviced by vehicle v */
2471  if ((o->GetUnloadType() & OUFB_UNLOAD) && !c_accepts) break;
2472 
2473  if (stations.Contains(st)) {
2474  if (v->owner == _local_company) return 2; // Company services industry
2475  result = 1; // Competitor services industry
2476  }
2477  }
2478  }
2479  }
2480  return result;
2481 }
2482 
2491 {
2492  NewsType nt;
2493 
2494  switch (WhoCanServiceIndustry(ind)) {
2495  case 0: nt = NT_INDUSTRY_NOBODY; break;
2496  case 1: nt = NT_INDUSTRY_OTHER; break;
2497  case 2: nt = NT_INDUSTRY_COMPANY; break;
2498  default: NOT_REACHED();
2499  }
2500  SetDParam(2, abs(percent));
2501  SetDParam(0, CargoSpec::Get(type)->name);
2502  SetDParam(1, ind->index);
2503  AddIndustryNewsItem(
2504  percent >= 0 ? STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH : STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH,
2505  nt,
2506  ind->index
2507  );
2508 }
2509 
2510 static const uint PERCENT_TRANSPORTED_60 = 153;
2511 static const uint PERCENT_TRANSPORTED_80 = 204;
2512 
2518 static void ChangeIndustryProduction(Industry *i, bool monthly)
2519 {
2520  StringID str = STR_NULL;
2521  bool closeit = false;
2522  const IndustrySpec *indspec = GetIndustrySpec(i->type);
2523  bool standard = false;
2524  bool suppress_message = false;
2525  bool recalculate_multipliers = false;
2526  /* don't use smooth economy for industries using production related callbacks */
2527  bool smooth_economy = indspec->UsesSmoothEconomy();
2528  byte div = 0;
2529  byte mul = 0;
2530  int8 increment = 0;
2531 
2532  bool callback_enabled = HasBit(indspec->callback_mask, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE);
2533  if (callback_enabled) {
2535  if (res != CALLBACK_FAILED) { // failed callback means "do nothing"
2536  suppress_message = HasBit(res, 7);
2537  /* Get the custom message if any */
2538  if (HasBit(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16));
2539  res = GB(res, 0, 4);
2540  switch (res) {
2541  default: NOT_REACHED();
2542  case 0x0: break; // Do nothing, but show the custom message if any
2543  case 0x1: div = 1; break; // Halve industry production. If production reaches the quarter of the default, the industry is closed instead.
2544  case 0x2: mul = 1; break; // Double industry production if it hasn't reached eight times of the original yet.
2545  case 0x3: closeit = true; break; // The industry announces imminent closure, and is physically removed from the map next month.
2546  case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one.
2547  case 0x5: case 0x6: case 0x7: // Divide production by 4, 8, 16
2548  case 0x8: div = res - 0x3; break; // Divide production by 32
2549  case 0x9: case 0xA: case 0xB: // Multiply production by 4, 8, 16
2550  case 0xC: mul = res - 0x7; break; // Multiply production by 32
2551  case 0xD: // decrement production
2552  case 0xE: // increment production
2553  increment = res == 0x0D ? -1 : 1;
2554  break;
2555  case 0xF: // Set production to third byte of register 0x100
2557  recalculate_multipliers = true;
2558  break;
2559  }
2560  }
2561  } else {
2562  if (monthly != smooth_economy) return;
2563  if (indspec->life_type == INDUSTRYLIFE_BLACK_HOLE) return;
2564  }
2565 
2566  if (standard || (!callback_enabled && (indspec->life_type & (INDUSTRYLIFE_ORGANIC | INDUSTRYLIFE_EXTRACTIVE)) != 0)) {
2567  /* decrease or increase */
2568  bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE;
2569 
2570  if (smooth_economy) {
2571  closeit = true;
2572  for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
2573  if (i->produced_cargo[j] == CT_INVALID) continue;
2574  uint32 r = Random();
2575  int old_prod, new_prod, percent;
2576  /* If over 60% is transported, mult is 1, else mult is -1. */
2577  int mult = (i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_60) ? 1 : -1;
2578 
2579  new_prod = old_prod = i->production_rate[j];
2580 
2581  /* For industries with only_decrease flags (temperate terrain Oil Wells),
2582  * the multiplier will always be -1 so they will only decrease. */
2583  if (only_decrease) {
2584  mult = -1;
2585  /* For normal industries, if over 60% is transported, 33% chance for decrease.
2586  * Bonus for very high station ratings (over 80%): 16% chance for decrease. */
2587  } else if (Chance16I(1, ((i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_80) ? 6 : 3), r)) {
2588  mult *= -1;
2589  }
2590 
2591  /* 4.5% chance for 3-23% (or 1 unit for very low productions) production change,
2592  * determined by mult value. If mult = 1 prod. increases, else (-1) it decreases. */
2593  if (Chance16I(1, 22, r >> 16)) {
2594  new_prod += mult * (max(((RandomRange(50) + 10) * old_prod) >> 8, 1U));
2595  }
2596 
2597  /* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
2598  new_prod = Clamp(new_prod, 1, 255);
2599 
2600  if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1) {
2601  new_prod = Clamp(new_prod, 0, 16);
2602  }
2603 
2604  /* Do not stop closing the industry when it has the lowest possible production rate */
2605  if (new_prod == old_prod && old_prod > 1) {
2606  closeit = false;
2607  continue;
2608  }
2609 
2610  percent = (old_prod == 0) ? 100 : (new_prod * 100 / old_prod - 100);
2611  i->production_rate[j] = new_prod;
2612 
2613  /* Close the industry when it has the lowest possible production rate */
2614  if (new_prod > 1) closeit = false;
2615 
2616  if (abs(percent) >= 10) {
2618  }
2619  }
2620  } else {
2621  if (only_decrease || Chance16(1, 3)) {
2622  /* If more than 60% transported, 66% chance of increase, else 33% chance of increase */
2623  if (!only_decrease && (i->last_month_pct_transported[0] > PERCENT_TRANSPORTED_60) != Chance16(1, 3)) {
2624  mul = 1; // Increase production
2625  } else {
2626  div = 1; // Decrease production
2627  }
2628  }
2629  }
2630  }
2631 
2632  if (!callback_enabled && (indspec->life_type & INDUSTRYLIFE_PROCESSING)) {
2633  if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, smooth_economy ? 180 : 2)) {
2634  closeit = true;
2635  }
2636  }
2637 
2638  /* Increase if needed */
2639  while (mul-- != 0 && i->prod_level < PRODLEVEL_MAXIMUM) {
2641  recalculate_multipliers = true;
2642  if (str == STR_NULL) str = indspec->production_up_text;
2643  }
2644 
2645  /* Decrease if needed */
2646  while (div-- != 0 && !closeit) {
2647  if (i->prod_level == PRODLEVEL_MINIMUM) {
2648  closeit = true;
2649  } else {
2650  i->prod_level = max(i->prod_level / 2, (int)PRODLEVEL_MINIMUM); // typecast to int required to please MSVC
2651  recalculate_multipliers = true;
2652  if (str == STR_NULL) str = indspec->production_down_text;
2653  }
2654  }
2655 
2656  /* Increase or Decreasing the production level if needed */
2657  if (increment != 0) {
2658  if (increment < 0 && i->prod_level == PRODLEVEL_MINIMUM) {
2659  closeit = true;
2660  } else {
2662  recalculate_multipliers = true;
2663  }
2664  }
2665 
2666  /* Recalculate production_rate
2667  * For non-smooth economy these should always be synchronized with prod_level */
2668  if (recalculate_multipliers) i->RecomputeProductionMultipliers();
2669 
2670  /* Close if needed and allowed */
2671  if (closeit && !CheckIndustryCloseDownProtection(i->type)) {
2674  str = indspec->closure_text;
2675  }
2676 
2677  if (!suppress_message && str != STR_NULL) {
2678  NewsType nt;
2679  /* Compute news category */
2680  if (closeit) {
2681  nt = NT_INDUSTRY_CLOSE;
2682  AI::BroadcastNewEvent(new ScriptEventIndustryClose(i->index));
2683  Game::NewEvent(new ScriptEventIndustryClose(i->index));
2684  } else {
2685  switch (WhoCanServiceIndustry(i)) {
2686  case 0: nt = NT_INDUSTRY_NOBODY; break;
2687  case 1: nt = NT_INDUSTRY_OTHER; break;
2688  case 2: nt = NT_INDUSTRY_COMPANY; break;
2689  default: NOT_REACHED();
2690  }
2691  }
2692  /* Set parameters of news string */
2693  if (str > STR_LAST_STRINGID) {
2694  SetDParam(0, STR_TOWN_NAME);
2695  SetDParam(1, i->town->index);
2696  SetDParam(2, indspec->name);
2697  } else if (closeit) {
2698  SetDParam(0, STR_FORMAT_INDUSTRY_NAME);
2699  SetDParam(1, i->town->index);
2700  SetDParam(2, indspec->name);
2701  } else {
2702  SetDParam(0, i->index);
2703  }
2704  /* and report the news to the user */
2705  if (closeit) {
2706  AddTileNewsItem(str, nt, i->location.tile + TileDiffXY(1, 1));
2707  } else {
2708  AddIndustryNewsItem(str, nt, i->index);
2709  }
2710  }
2711 }
2712 
2721 {
2723 
2724  /* Bits 16-31 of industry_construction_counter contain the number of industries to change/create today,
2725  * the lower 16 bit are a fractional part that might accumulate over several days until it
2726  * is sufficient for an industry. */
2727  uint16 change_loop = _economy.industry_daily_change_counter >> 16;
2728 
2729  /* Reset the active part of the counter, just keeping the "fractional part" */
2730  _economy.industry_daily_change_counter &= 0xFFFF;
2731 
2732  if (change_loop == 0) {
2733  return; // Nothing to do? get out
2734  }
2735 
2736  Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2737 
2738  /* perform the required industry changes for the day */
2739 
2740  uint perc = 3; // Between 3% and 9% chance of creating a new industry.
2741  if ((_industry_builder.wanted_inds >> 16) > GetCurrentTotalNumberOfIndustries()) {
2742  perc = min(9u, perc + (_industry_builder.wanted_inds >> 16) - GetCurrentTotalNumberOfIndustries());
2743  }
2744  for (uint16 j = 0; j < change_loop; j++) {
2745  if (Chance16(perc, 100)) {
2746  _industry_builder.TryBuildNewIndustry();
2747  } else {
2749  if (i != NULL) {
2750  ChangeIndustryProduction(i, false);
2752  }
2753  }
2754  }
2755 
2756  cur_company.Restore();
2757 
2758  /* production-change */
2760 }
2761 
2762 void IndustryMonthlyLoop()
2763 {
2764  Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2765 
2766  _industry_builder.MonthlyLoop();
2767 
2768  Industry *i;
2769  FOR_ALL_INDUSTRIES(i) {
2771  if (i->prod_level == PRODLEVEL_CLOSURE) {
2772  delete i;
2773  } else {
2774  ChangeIndustryProduction(i, true);
2776  }
2777  }
2778 
2779  cur_company.Restore();
2780 
2781  /* production-change */
2783 }
2784 
2785 
2786 void InitializeIndustries()
2787 {
2789  _industry_sound_tile = 0;
2790 
2791  _industry_builder.Reset();
2792 }
2793 
2796 {
2797  int count = 0;
2798  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2799  if (Industry::GetIndustryTypeCount(it) > 0) continue; // Types of existing industries can be skipped.
2800 
2801  bool force_at_least_one;
2802  uint32 chance = GetScaledIndustryGenerationProbability(it, &force_at_least_one);
2803  if (chance == 0 || !force_at_least_one) continue; // Types that are not available can be skipped.
2804 
2805  const IndustrySpec *is = GetIndustrySpec(it);
2806  SetDParam(0, is->name);
2807  ShowErrorMessage(STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES, STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION, WL_WARNING);
2808 
2809  count++;
2810  if (count >= 3) break; // Don't swamp the user with errors.
2811  }
2812 }
2813 
2819 {
2820  return (this->life_type & (INDUSTRYLIFE_EXTRACTIVE | INDUSTRYLIFE_ORGANIC)) != 0;
2821 }
2822 
2828 {
2829  /* Lumber mills are neither raw nor processing */
2830  return (this->life_type & INDUSTRYLIFE_PROCESSING) != 0 &&
2831  (this->behaviour & INDUSTRYBEH_CUT_TREES) == 0;
2832 }
2833 
2839 {
2840  /* Building raw industries like secondary uses different price base */
2841  return (_price[(_settings_game.construction.raw_industry_construction == 1 && this->IsRawIndustry()) ?
2842  PR_BUILD_INDUSTRY_RAW : PR_BUILD_INDUSTRY] * this->cost_multiplier) >> 8;
2843 }
2844 
2852 {
2853  return (_price[PR_CLEAR_INDUSTRY] * this->removal_cost_multiplier) >> 8;
2854 }
2855 
2861 {
2863  !(HasBit(this->callback_mask, CBM_IND_PRODUCTION_256_TICKS) || HasBit(this->callback_mask, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks
2864  !(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
2865 }
2866 
2867 static CommandCost TerraformTile_Industry(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
2868 {
2869  if (AutoslopeEnabled()) {
2870  /* We imitate here TTDP's behaviour:
2871  * - Both new and old slope must not be steep.
2872  * - TileMaxZ must not be changed.
2873  * - Allow autoslope by default.
2874  * - Disallow autoslope if callback succeeds and returns non-zero.
2875  */
2876  Slope tileh_old = GetTileSlope(tile);
2877  /* TileMaxZ must not be changed. Slopes must not be steep. */
2878  if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
2879  const IndustryGfx gfx = GetIndustryGfx(tile);
2880  const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
2881 
2882  /* Call callback 3C 'disable autosloping for industry tiles'. */
2883  if (HasBit(itspec->callback_mask, CBM_INDT_AUTOSLOPE)) {
2884  /* If the callback fails, allow autoslope. */
2885  uint16 res = GetIndustryTileCallback(CBID_INDTILE_AUTOSLOPE, 0, 0, gfx, Industry::GetByTile(tile), tile);
2886  if (res == CALLBACK_FAILED || !ConvertBooleanCallback(itspec->grf_prop.grffile, CBID_INDTILE_AUTOSLOPE, res)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2887  } else {
2888  /* allow autoslope */
2889  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2890  }
2891  }
2892  }
2893  return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
2894 }
2895 
2896 extern const TileTypeProcs _tile_type_industry_procs = {
2897  DrawTile_Industry, // draw_tile_proc
2898  GetSlopePixelZ_Industry, // get_slope_z_proc
2899  ClearTile_Industry, // clear_tile_proc
2900  AddAcceptedCargo_Industry, // add_accepted_cargo_proc
2901  GetTileDesc_Industry, // get_tile_desc_proc
2902  GetTileTrackStatus_Industry, // get_tile_track_status_proc
2903  ClickTile_Industry, // click_tile_proc
2904  AnimateTile_Industry, // animate_tile_proc
2905  TileLoop_Industry, // tile_loop_proc
2906  ChangeTileOwner_Industry, // change_tile_owner_proc
2907  NULL, // add_produced_cargo_proc
2908  NULL, // vehicle_enter_tile_proc
2909  GetFoundation_Industry, // get_foundation_proc
2910  TerraformTile_Industry, // terraform_tile_proc
2911 };
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:143
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:3201
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:838
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:263
bool ambient
Play ambient, industry and town sounds.
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
the east corner of the tile is raised
Definition: slope_type.h:54
int8 acceptance[INDUSTRY_NUM_INPUTS]
Level of acceptance per cargo type (signed, may be negative!)
Definition: industrytype.h: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:183
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:23
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition: tile_map.cpp:123
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:500
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:226
static uint16 GetIndustryGamePlayProbability(IndustryType it, byte *min_number)
Compute the probability for constructing a new industry during game play.
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1146
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:90
north and west corner are raised
Definition: slope_type.h:57
static const IndustryType NUM_INDUSTRYTYPES
total number of industry types, new and old; limited to 240 because we need some special ids like INV...
Definition: industry_type.h:28
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:412
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:100
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:3301
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