OpenTTD
industry_cmd.cpp
Go to the documentation of this file.
1 /* $Id: industry_cmd.cpp 27932 2017-11-25 16:50:28Z frosch $ */
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, uint32 *always_accepted)
394 {
395  IndustryGfx gfx = GetIndustryGfx(tile);
396  const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
397 
398  /* When we have to use a callback, we put our data in the next two variables */
399  CargoID raw_accepts_cargo[lengthof(itspec->accepts_cargo)];
400  uint8 raw_cargo_acceptance[lengthof(itspec->acceptance)];
401 
402  /* And then these will always point to a same sized array with the required data */
403  const CargoID *accepts_cargo = itspec->accepts_cargo;
404  const uint8 *cargo_acceptance = itspec->acceptance;
405 
407  uint16 res = GetIndustryTileCallback(CBID_INDTILE_ACCEPT_CARGO, 0, 0, gfx, Industry::GetByTile(tile), tile);
408  if (res != CALLBACK_FAILED) {
409  accepts_cargo = raw_accepts_cargo;
410  for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_accepts_cargo[i] = GetCargoTranslation(GB(res, i * 5, 5), itspec->grf_prop.grffile);
411  }
412  }
413 
415  uint16 res = GetIndustryTileCallback(CBID_INDTILE_CARGO_ACCEPTANCE, 0, 0, gfx, Industry::GetByTile(tile), tile);
416  if (res != CALLBACK_FAILED) {
417  cargo_acceptance = raw_cargo_acceptance;
418  for (uint i = 0; i < lengthof(itspec->accepts_cargo); i++) raw_cargo_acceptance[i] = GB(res, i * 4, 4);
419  }
420  }
421 
422  const Industry *ind = Industry::GetByTile(tile);
423  for (byte i = 0; i < lengthof(itspec->accepts_cargo); i++) {
424  CargoID a = accepts_cargo[i];
425  if (a == CT_INVALID || cargo_acceptance[i] == 0) continue; // work only with valid cargoes
426 
427  /* Add accepted cargo */
428  acceptance[a] += cargo_acceptance[i];
429 
430  /* Maybe set 'always accepted' bit (if it's not set already) */
431  if (HasBit(*always_accepted, a)) continue;
432 
433  bool accepts = false;
434  for (uint cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) {
435  /* Test whether the industry itself accepts the cargo type */
436  if (ind->accepts_cargo[cargo_index] == a) {
437  accepts = true;
438  break;
439  }
440  }
441 
442  if (accepts) continue;
443 
444  /* If the industry itself doesn't accept this cargo, set 'always accepted' bit */
445  SetBit(*always_accepted, a);
446  }
447 }
448 
449 static void GetTileDesc_Industry(TileIndex tile, TileDesc *td)
450 {
451  const Industry *i = Industry::GetByTile(tile);
452  const IndustrySpec *is = GetIndustrySpec(i->type);
453 
454  td->owner[0] = i->owner;
455  td->str = is->name;
456  if (!IsIndustryCompleted(tile)) {
457  SetDParamX(td->dparam, 0, td->str);
458  td->str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION;
459  }
460 
461  if (is->grf_prop.grffile != NULL) {
462  td->grf = GetGRFConfig(is->grf_prop.grffile->grfid)->GetName();
463  }
464 }
465 
466 static CommandCost ClearTile_Industry(TileIndex tile, DoCommandFlag flags)
467 {
468  Industry *i = Industry::GetByTile(tile);
469  const IndustrySpec *indspec = GetIndustrySpec(i->type);
470 
471  /* water can destroy industries
472  * in editor you can bulldoze industries
473  * with magic_bulldozer cheat you can destroy industries
474  * (area around OILRIG is water, so water shouldn't flood it
475  */
476  if ((_current_company != OWNER_WATER && _game_mode != GM_EDITOR &&
478  ((flags & DC_AUTO) != 0) ||
480  ((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) ||
481  HasBit(GetIndustryTileSpec(GetIndustryGfx(tile))->slopes_refused, 5)))) {
482  SetDParam(1, indspec->name);
483  return_cmd_error(flags & DC_AUTO ? STR_ERROR_GENERIC_OBJECT_IN_THE_WAY : INVALID_STRING_ID);
484  }
485 
486  if (flags & DC_EXEC) {
487  AI::BroadcastNewEvent(new ScriptEventIndustryClose(i->index));
488  Game::NewEvent(new ScriptEventIndustryClose(i->index));
489  delete i;
490  }
492 }
493 
500 {
501  Industry *i = Industry::GetByTile(tile);
502  const IndustrySpec *indspec = GetIndustrySpec(i->type);
503  bool moved_cargo = false;
504 
505  StationFinder stations(i->location);
506 
507  for (uint j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
508  uint cw = min(i->produced_cargo_waiting[j], 255);
509  if (cw > indspec->minimal_cargo && i->produced_cargo[j] != CT_INVALID) {
510  i->produced_cargo_waiting[j] -= cw;
511 
512  /* fluctuating economy? */
513  if (EconomyIsInRecession()) cw = (cw + 1) / 2;
514 
515  i->this_month_production[j] += cw;
516 
517  uint am = MoveGoodsToStation(i->produced_cargo[j], cw, ST_INDUSTRY, i->index, stations.GetStations());
518  i->this_month_transported[j] += am;
519 
520  moved_cargo |= (am != 0);
521  }
522  }
523 
524  return moved_cargo;
525 }
526 
527 
528 static void AnimateTile_Industry(TileIndex tile)
529 {
530  IndustryGfx gfx = GetIndustryGfx(tile);
531 
532  if (GetIndustryTileSpec(gfx)->animation.status != ANIM_STATUS_NO_ANIMATION) {
533  AnimateNewIndustryTile(tile);
534  return;
535  }
536 
537  switch (gfx) {
538  case GFX_SUGAR_MINE_SIEVE:
539  if ((_tick_counter & 1) == 0) {
540  byte m = GetAnimationFrame(tile) + 1;
541 
543  switch (m & 7) {
544  case 2: SndPlayTileFx(SND_2D_RIP_2, tile); break;
545  case 6: SndPlayTileFx(SND_29_RIP, tile); break;
546  }
547  }
548 
549  if (m >= 96) {
550  m = 0;
551  DeleteAnimatedTile(tile);
552  }
553  SetAnimationFrame(tile, m);
554 
555  MarkTileDirtyByTile(tile);
556  }
557  break;
558 
559  case GFX_TOFFEE_QUARY:
560  if ((_tick_counter & 3) == 0) {
561  byte m = GetAnimationFrame(tile);
562 
563  if (_industry_anim_offs_toffee[m] == 0xFF && _settings_client.sound.ambient) {
564  SndPlayTileFx(SND_30_CARTOON_SOUND, tile);
565  }
566 
567  if (++m >= 70) {
568  m = 0;
569  DeleteAnimatedTile(tile);
570  }
571  SetAnimationFrame(tile, m);
572 
573  MarkTileDirtyByTile(tile);
574  }
575  break;
576 
577  case GFX_BUBBLE_CATCHER:
578  if ((_tick_counter & 1) == 0) {
579  byte m = GetAnimationFrame(tile);
580 
581  if (++m >= 40) {
582  m = 0;
583  DeleteAnimatedTile(tile);
584  }
585  SetAnimationFrame(tile, m);
586 
587  MarkTileDirtyByTile(tile);
588  }
589  break;
590 
591  /* Sparks on a coal plant */
592  case GFX_POWERPLANT_SPARKS:
593  if ((_tick_counter & 3) == 0) {
594  byte m = GetAnimationFrame(tile);
595  if (m == 6) {
596  SetAnimationFrame(tile, 0);
597  DeleteAnimatedTile(tile);
598  } else {
599  SetAnimationFrame(tile, m + 1);
600  MarkTileDirtyByTile(tile);
601  }
602  }
603  break;
604 
605  case GFX_TOY_FACTORY:
606  if ((_tick_counter & 1) == 0) {
607  byte m = GetAnimationFrame(tile) + 1;
608 
609  switch (m) {
610  case 1: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2C_MACHINERY, tile); break;
611  case 23: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2B_COMEDY_HIT, tile); break;
612  case 28: if (_settings_client.sound.ambient) SndPlayTileFx(SND_2A_EXTRACT_AND_POP, tile); break;
613  default:
614  if (m >= 50) {
615  int n = GetIndustryAnimationLoop(tile) + 1;
616  m = 0;
617  if (n >= 8) {
618  n = 0;
619  DeleteAnimatedTile(tile);
620  }
621  SetIndustryAnimationLoop(tile, n);
622  }
623  }
624 
625  SetAnimationFrame(tile, m);
626  MarkTileDirtyByTile(tile);
627  }
628  break;
629 
630  case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
631  case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
632  case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
633  case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
634  if ((_tick_counter & 3) == 0) {
635  IndustryGfx gfx = GetIndustryGfx(tile);
636 
637  gfx = (gfx < 155) ? gfx + 1 : 148;
638  SetIndustryGfx(tile, gfx);
639  MarkTileDirtyByTile(tile);
640  }
641  break;
642 
643  case GFX_OILWELL_ANIMATED_1:
644  case GFX_OILWELL_ANIMATED_2:
645  case GFX_OILWELL_ANIMATED_3:
646  if ((_tick_counter & 7) == 0) {
647  bool b = Chance16(1, 7);
648  IndustryGfx gfx = GetIndustryGfx(tile);
649 
650  byte m = GetAnimationFrame(tile) + 1;
651  if (m == 4 && (m = 0, ++gfx) == GFX_OILWELL_ANIMATED_3 + 1 && (gfx = GFX_OILWELL_ANIMATED_1, b)) {
652  SetIndustryGfx(tile, GFX_OILWELL_NOT_ANIMATED);
654  DeleteAnimatedTile(tile);
655  } else {
656  SetAnimationFrame(tile, m);
657  SetIndustryGfx(tile, gfx);
658  MarkTileDirtyByTile(tile);
659  }
660  }
661  break;
662 
663  case GFX_COAL_MINE_TOWER_ANIMATED:
664  case GFX_COPPER_MINE_TOWER_ANIMATED:
665  case GFX_GOLD_MINE_TOWER_ANIMATED: {
666  int state = _tick_counter & 0x7FF;
667 
668  if ((state -= 0x400) < 0) return;
669 
670  if (state < 0x1A0) {
671  if (state < 0x20 || state >= 0x180) {
672  byte m = GetAnimationFrame(tile);
673  if (!(m & 0x40)) {
674  SetAnimationFrame(tile, m | 0x40);
675  if (_settings_client.sound.ambient) SndPlayTileFx(SND_0B_MINING_MACHINERY, tile);
676  }
677  if (state & 7) return;
678  } else {
679  if (state & 3) return;
680  }
681  byte m = (GetAnimationFrame(tile) + 1) | 0x40;
682  if (m > 0xC2) m = 0xC0;
683  SetAnimationFrame(tile, m);
684  MarkTileDirtyByTile(tile);
685  } else if (state >= 0x200 && state < 0x3A0) {
686  int i = (state < 0x220 || state >= 0x380) ? 7 : 3;
687  if (state & i) return;
688 
689  byte m = (GetAnimationFrame(tile) & 0xBF) - 1;
690  if (m < 0x80) m = 0x82;
691  SetAnimationFrame(tile, m);
692  MarkTileDirtyByTile(tile);
693  }
694  break;
695  }
696  }
697 }
698 
699 static void CreateChimneySmoke(TileIndex tile)
700 {
701  uint x = TileX(tile) * TILE_SIZE;
702  uint y = TileY(tile) * TILE_SIZE;
703  int z = GetTileMaxPixelZ(tile);
704 
705  CreateEffectVehicle(x + 15, y + 14, z + 59, EV_CHIMNEY_SMOKE);
706 }
707 
708 static void MakeIndustryTileBigger(TileIndex tile)
709 {
710  byte cnt = GetIndustryConstructionCounter(tile) + 1;
711  if (cnt != 4) {
713  return;
714  }
715 
716  byte stage = GetIndustryConstructionStage(tile) + 1;
718  SetIndustryConstructionStage(tile, stage);
719  StartStopIndustryTileAnimation(tile, IAT_CONSTRUCTION_STATE_CHANGE);
720  if (stage == INDUSTRY_COMPLETED) SetIndustryCompleted(tile);
721 
722  MarkTileDirtyByTile(tile);
723 
724  if (!IsIndustryCompleted(tile)) return;
725 
726  IndustryGfx gfx = GetIndustryGfx(tile);
727  if (gfx >= NEW_INDUSTRYTILEOFFSET) {
728  /* New industries are already animated on construction. */
729  return;
730  }
731 
732  switch (gfx) {
733  case GFX_POWERPLANT_CHIMNEY:
734  CreateChimneySmoke(tile);
735  break;
736 
737  case GFX_OILRIG_1: {
738  /* Do not require an industry tile to be after the first two GFX_OILRIG_1
739  * tiles (like the default oil rig). Do a proper check to ensure the
740  * tiles belong to the same industry and based on that build the oil rig's
741  * station. */
742  TileIndex other = tile + TileDiffXY(0, 1);
743 
744  if (IsTileType(other, MP_INDUSTRY) &&
745  GetIndustryGfx(other) == GFX_OILRIG_1 &&
746  GetIndustryIndex(tile) == GetIndustryIndex(other)) {
747  BuildOilRig(tile);
748  }
749  break;
750  }
751 
752  case GFX_TOY_FACTORY:
753  case GFX_BUBBLE_CATCHER:
754  case GFX_TOFFEE_QUARY:
755  SetAnimationFrame(tile, 0);
756  SetIndustryAnimationLoop(tile, 0);
757  break;
758 
759  case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
760  case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
761  case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
762  case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
763  AddAnimatedTile(tile);
764  break;
765  }
766 }
767 
768 static void TileLoopIndustry_BubbleGenerator(TileIndex tile)
769 {
770  static const int8 _bubble_spawn_location[3][4] = {
771  { 11, 0, -4, -14 },
772  { -4, -10, -4, 1 },
773  { 49, 59, 60, 65 },
774  };
775 
776  if (_settings_client.sound.ambient) SndPlayTileFx(SND_2E_EXTRACT_AND_POP, tile);
777 
778  int dir = Random() & 3;
779 
781  TileX(tile) * TILE_SIZE + _bubble_spawn_location[0][dir],
782  TileY(tile) * TILE_SIZE + _bubble_spawn_location[1][dir],
783  _bubble_spawn_location[2][dir],
784  EV_BUBBLE
785  );
786 
787  if (v != NULL) v->animation_substate = dir;
788 }
789 
790 static void TileLoop_Industry(TileIndex tile)
791 {
792  if (IsTileOnWater(tile)) TileLoop_Water(tile);
793 
794  /* Normally this doesn't happen, but if an industry NewGRF is removed
795  * an industry that was previously build on water can now be flooded.
796  * If this happens the tile is no longer an industry tile after
797  * returning from TileLoop_Water. */
798  if (!IsTileType(tile, MP_INDUSTRY)) return;
799 
801 
802  if (!IsIndustryCompleted(tile)) {
803  MakeIndustryTileBigger(tile);
804  return;
805  }
806 
807  if (_game_mode == GM_EDITOR) return;
808 
809  if (TransportIndustryGoods(tile) && !StartStopIndustryTileAnimation(Industry::GetByTile(tile), IAT_INDUSTRY_DISTRIBUTES_CARGO)) {
810  uint newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_production;
811 
812  if (newgfx != INDUSTRYTILE_NOANIM) {
814  SetIndustryCompleted(tile);
815  SetIndustryGfx(tile, newgfx);
816  MarkTileDirtyByTile(tile);
817  return;
818  }
819  }
820 
821  if (StartStopIndustryTileAnimation(tile, IAT_TILELOOP)) return;
822 
823  IndustryGfx newgfx = GetIndustryTileSpec(GetIndustryGfx(tile))->anim_next;
824  if (newgfx != INDUSTRYTILE_NOANIM) {
826  SetIndustryGfx(tile, newgfx);
827  MarkTileDirtyByTile(tile);
828  return;
829  }
830 
831  IndustryGfx gfx = GetIndustryGfx(tile);
832  switch (gfx) {
833  case GFX_COAL_MINE_TOWER_NOT_ANIMATED:
834  case GFX_COPPER_MINE_TOWER_NOT_ANIMATED:
835  case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:
836  if (!(_tick_counter & 0x400) && Chance16(1, 2)) {
837  switch (gfx) {
838  case GFX_COAL_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COAL_MINE_TOWER_ANIMATED; break;
839  case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_ANIMATED; break;
840  case GFX_GOLD_MINE_TOWER_NOT_ANIMATED: gfx = GFX_GOLD_MINE_TOWER_ANIMATED; break;
841  }
842  SetIndustryGfx(tile, gfx);
843  SetAnimationFrame(tile, 0x80);
844  AddAnimatedTile(tile);
845  }
846  break;
847 
848  case GFX_OILWELL_NOT_ANIMATED:
849  if (Chance16(1, 6)) {
850  SetIndustryGfx(tile, GFX_OILWELL_ANIMATED_1);
851  SetAnimationFrame(tile, 0);
852  AddAnimatedTile(tile);
853  }
854  break;
855 
856  case GFX_COAL_MINE_TOWER_ANIMATED:
857  case GFX_COPPER_MINE_TOWER_ANIMATED:
858  case GFX_GOLD_MINE_TOWER_ANIMATED:
859  if (!(_tick_counter & 0x400)) {
860  switch (gfx) {
861  case GFX_COAL_MINE_TOWER_ANIMATED: gfx = GFX_COAL_MINE_TOWER_NOT_ANIMATED; break;
862  case GFX_COPPER_MINE_TOWER_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_NOT_ANIMATED; break;
863  case GFX_GOLD_MINE_TOWER_ANIMATED: gfx = GFX_GOLD_MINE_TOWER_NOT_ANIMATED; break;
864  }
865  SetIndustryGfx(tile, gfx);
866  SetIndustryCompleted(tile);
868  DeleteAnimatedTile(tile);
869  }
870  break;
871 
872  case GFX_POWERPLANT_SPARKS:
873  if (Chance16(1, 3)) {
874  if (_settings_client.sound.ambient) SndPlayTileFx(SND_0C_ELECTRIC_SPARK, tile);
875  AddAnimatedTile(tile);
876  }
877  break;
878 
879  case GFX_COPPER_MINE_CHIMNEY:
881  break;
882 
883 
884  case GFX_TOY_FACTORY: {
885  Industry *i = Industry::GetByTile(tile);
886  if (i->was_cargo_delivered) {
887  i->was_cargo_delivered = false;
888  SetIndustryAnimationLoop(tile, 0);
889  AddAnimatedTile(tile);
890  }
891  }
892  break;
893 
894  case GFX_BUBBLE_GENERATOR:
895  TileLoopIndustry_BubbleGenerator(tile);
896  break;
897 
898  case GFX_TOFFEE_QUARY:
899  AddAnimatedTile(tile);
900  break;
901 
902  case GFX_SUGAR_MINE_SIEVE:
903  if (Chance16(1, 3)) AddAnimatedTile(tile);
904  break;
905  }
906 }
907 
908 static bool ClickTile_Industry(TileIndex tile)
909 {
910  ShowIndustryViewWindow(GetIndustryIndex(tile));
911  return true;
912 }
913 
914 static TrackStatus GetTileTrackStatus_Industry(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
915 {
916  return 0;
917 }
918 
919 static void ChangeTileOwner_Industry(TileIndex tile, Owner old_owner, Owner new_owner)
920 {
921  /* If the founder merges, the industry was created by the merged company */
922  Industry *i = Industry::GetByTile(tile);
923  if (i->founder == old_owner) i->founder = (new_owner == INVALID_OWNER) ? OWNER_NONE : new_owner;
924 }
925 
932 {
933  /* Check for industry tile */
934  if (!IsTileType(tile, MP_INDUSTRY)) return false;
935 
936  const Industry *ind = Industry::GetByTile(tile);
937 
938  /* Check for organic industry (i.e. not processing or extractive) */
939  if ((GetIndustrySpec(ind->type)->life_type & INDUSTRYLIFE_ORGANIC) == 0) return false;
940 
941  /* Check for wood production */
942  for (uint i = 0; i < lengthof(ind->produced_cargo); i++) {
943  /* The industry produces wood. */
944  if (ind->produced_cargo[i] != CT_INVALID && CargoSpec::Get(ind->produced_cargo[i])->label == 'WOOD') return true;
945  }
946 
947  return false;
948 }
949 
950 static const byte _plantfarmfield_type[] = {1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6};
951 
959 static bool IsSuitableForFarmField(TileIndex tile, bool allow_fields)
960 {
961  switch (GetTileType(tile)) {
962  case MP_CLEAR: return !IsClearGround(tile, CLEAR_SNOW) && !IsClearGround(tile, CLEAR_DESERT) && (allow_fields || !IsClearGround(tile, CLEAR_FIELDS));
963  case MP_TREES: return GetTreeGround(tile) != TREE_GROUND_SHORE;
964  default: return false;
965  }
966 }
967 
975 static void SetupFarmFieldFence(TileIndex tile, int size, byte type, DiagDirection side)
976 {
977  TileIndexDiff diff = (DiagDirToAxis(side) == AXIS_Y ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
978 
979  do {
980  tile = TILE_MASK(tile);
981 
982  if (IsTileType(tile, MP_CLEAR) && IsClearGround(tile, CLEAR_FIELDS)) {
983  byte or_ = type;
984 
985  if (or_ == 1 && Chance16(1, 7)) or_ = 2;
986 
987  SetFence(tile, side, or_);
988  }
989 
990  tile += diff;
991  } while (--size);
992 }
993 
994 static void PlantFarmField(TileIndex tile, IndustryID industry)
995 {
996  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
997  if (GetTileZ(tile) + 2 >= GetSnowLine()) return;
998  }
999 
1000  /* determine field size */
1001  uint32 r = (Random() & 0x303) + 0x404;
1002  if (_settings_game.game_creation.landscape == LT_ARCTIC) r += 0x404;
1003  uint size_x = GB(r, 0, 8);
1004  uint size_y = GB(r, 8, 8);
1005 
1006  TileArea ta(tile - TileDiffXY(min(TileX(tile), size_x / 2), min(TileY(tile), size_y / 2)), size_x, size_y);
1007  ta.ClampToMap();
1008 
1009  if (ta.w == 0 || ta.h == 0) return;
1010 
1011  /* check the amount of bad tiles */
1012  int count = 0;
1013  TILE_AREA_LOOP(cur_tile, ta) {
1014  assert(cur_tile < MapSize());
1015  count += IsSuitableForFarmField(cur_tile, false);
1016  }
1017  if (count * 2 < ta.w * ta.h) return;
1018 
1019  /* determine type of field */
1020  r = Random();
1021  uint counter = GB(r, 5, 3);
1022  uint field_type = GB(r, 8, 8) * 9 >> 8;
1023 
1024  /* make field */
1025  TILE_AREA_LOOP(cur_tile, ta) {
1026  assert(cur_tile < MapSize());
1027  if (IsSuitableForFarmField(cur_tile, true)) {
1028  MakeField(cur_tile, field_type, industry);
1029  SetClearCounter(cur_tile, counter);
1030  MarkTileDirtyByTile(cur_tile);
1031  }
1032  }
1033 
1034  int type = 3;
1035  if (_settings_game.game_creation.landscape != LT_ARCTIC && _settings_game.game_creation.landscape != LT_TROPIC) {
1036  type = _plantfarmfield_type[Random() & 0xF];
1037  }
1038 
1039  SetupFarmFieldFence(ta.tile, ta.h, type, DIAGDIR_NE);
1040  SetupFarmFieldFence(ta.tile, ta.w, type, DIAGDIR_NW);
1041  SetupFarmFieldFence(ta.tile + TileDiffXY(ta.w - 1, 0), ta.h, type, DIAGDIR_SW);
1042  SetupFarmFieldFence(ta.tile + TileDiffXY(0, ta.h - 1), ta.w, type, DIAGDIR_SE);
1043 }
1044 
1045 void PlantRandomFarmField(const Industry *i)
1046 {
1047  int x = i->location.w / 2 + Random() % 31 - 16;
1048  int y = i->location.h / 2 + Random() % 31 - 16;
1049 
1050  TileIndex tile = TileAddWrap(i->location.tile, x, y);
1051 
1052  if (tile != INVALID_TILE) PlantFarmField(tile, i->index);
1053 }
1054 
1061 static bool SearchLumberMillTrees(TileIndex tile, void *user_data)
1062 {
1063  if (IsTileType(tile, MP_TREES) && GetTreeGrowth(tile) > 2) {
1064  /* found a tree */
1065 
1066  Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
1067 
1068  _industry_sound_ctr = 1;
1069  _industry_sound_tile = tile;
1070  if (_settings_client.sound.ambient) SndPlayTileFx(SND_38_CHAINSAW, tile);
1071 
1072  DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
1073 
1074  cur_company.Restore();
1075  return true;
1076  }
1077  return false;
1078 }
1079 
1085 {
1086  /* We only want to cut trees if all tiles are completed. */
1087  TILE_AREA_LOOP(tile_cur, i->location) {
1088  if (i->TileBelongsToIndustry(tile_cur)) {
1089  if (!IsIndustryCompleted(tile_cur)) return;
1090  }
1091  }
1092 
1093  TileIndex tile = i->location.tile;
1094  if (CircularTileSearch(&tile, 40, SearchLumberMillTrees, NULL)) { // 40x40 tiles to search.
1095  i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + 45); // Found a tree, add according value to waiting cargo.
1096  }
1097 }
1098 
1099 static void ProduceIndustryGoods(Industry *i)
1100 {
1101  const IndustrySpec *indsp = GetIndustrySpec(i->type);
1102 
1103  /* play a sound? */
1104  if ((i->counter & 0x3F) == 0) {
1105  uint32 r;
1106  uint num;
1107  if (Chance16R(1, 14, r) && (num = indsp->number_of_sounds) != 0 && _settings_client.sound.ambient) {
1108  SndPlayTileFx(
1109  (SoundFx)(indsp->random_sounds[((r >> 16) * num) >> 16]),
1110  i->location.tile);
1111  }
1112  }
1113 
1114  i->counter--;
1115 
1116  /* produce some cargo */
1117  if ((i->counter % INDUSTRY_PRODUCE_TICKS) == 0) {
1119 
1120  IndustryBehaviour indbehav = indsp->behaviour;
1121  i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + i->production_rate[0]);
1122  i->produced_cargo_waiting[1] = min(0xffff, i->produced_cargo_waiting[1] + i->production_rate[1]);
1123 
1124  if ((indbehav & INDUSTRYBEH_PLANT_FIELDS) != 0) {
1125  uint16 cb_res = CALLBACK_FAILED;
1127  cb_res = GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 0, i, i->type, i->location.tile);
1128  }
1129 
1130  bool plant;
1131  if (cb_res != CALLBACK_FAILED) {
1133  } else {
1134  plant = Chance16(1, 8);
1135  }
1136 
1137  if (plant) PlantRandomFarmField(i);
1138  }
1139  if ((indbehav & INDUSTRYBEH_CUT_TREES) != 0) {
1140  uint16 cb_res = CALLBACK_FAILED;
1142  cb_res = GetIndustryCallback(CBID_INDUSTRY_SPECIAL_EFFECT, Random(), 1, i, i->type, i->location.tile);
1143  }
1144 
1145  bool cut;
1146  if (cb_res != CALLBACK_FAILED) {
1148  } else {
1149  cut = ((i->counter % INDUSTRY_CUT_TREE_TICKS) == 0);
1150  }
1151 
1152  if (cut) ChopLumberMillTrees(i);
1153  }
1154 
1156  StartStopIndustryTileAnimation(i, IAT_INDUSTRY_TICK);
1157  }
1158 }
1159 
1160 void OnTick_Industry()
1161 {
1162  if (_industry_sound_ctr != 0) {
1163  _industry_sound_ctr++;
1164 
1165  if (_industry_sound_ctr == 75) {
1166  if (_settings_client.sound.ambient) SndPlayTileFx(SND_37_BALLOON_SQUEAK, _industry_sound_tile);
1167  } else if (_industry_sound_ctr == 160) {
1168  _industry_sound_ctr = 0;
1169  if (_settings_client.sound.ambient) SndPlayTileFx(SND_36_CARTOON_CRASH, _industry_sound_tile);
1170  }
1171  }
1172 
1173  if (_game_mode == GM_EDITOR) return;
1174 
1175  Industry *i;
1176  FOR_ALL_INDUSTRIES(i) {
1177  ProduceIndustryGoods(i);
1178  }
1179 }
1180 
1187 {
1188  return CommandCost();
1189 }
1190 
1197 {
1198  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
1199  if (GetTileZ(tile) < HighestSnowLine() + 2) {
1200  return_cmd_error(STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED);
1201  }
1202  }
1203  return CommandCost();
1204 }
1205 
1212 {
1213  if (_game_mode == GM_EDITOR) return CommandCost();
1215 
1216  return_cmd_error(STR_ERROR_CAN_ONLY_BE_POSITIONED);
1217 }
1218 
1219 extern bool _ignore_restrictions;
1220 
1227 {
1228  if (_game_mode == GM_EDITOR && _ignore_restrictions) return CommandCost();
1229  if (TileHeight(tile) == 0 &&
1231 
1232  return_cmd_error(STR_ERROR_CAN_ONLY_BE_POSITIONED);
1233 }
1234 
1241 {
1242  if (_settings_game.game_creation.landscape == LT_ARCTIC) {
1243  if (GetTileZ(tile) + 2 >= HighestSnowLine()) {
1244  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1245  }
1246  }
1247  return CommandCost();
1248 }
1249 
1256 {
1257  if (GetTropicZone(tile) == TROPICZONE_DESERT) {
1258  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1259  }
1260  return CommandCost();
1261 }
1262 
1269 {
1270  if (GetTropicZone(tile) != TROPICZONE_DESERT) {
1271  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT);
1272  }
1273  return CommandCost();
1274 }
1275 
1282 {
1283  if (GetTropicZone(tile) != TROPICZONE_RAINFOREST) {
1284  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST);
1285  }
1286  return CommandCost();
1287 }
1288 
1295 {
1296  if (GetTileZ(tile) > 4) {
1297  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_LOW_AREAS);
1298  }
1299  return CommandCost();
1300 }
1301 
1308 
1320 };
1321 
1333 {
1334  *t = ClosestTownFromTile(tile, UINT_MAX);
1335 
1337 
1338  const Industry *i;
1339  FOR_ALL_INDUSTRIES(i) {
1340  if (i->type == (byte)type && i->town == *t) {
1341  *t = NULL;
1342  return_cmd_error(STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN);
1343  }
1344  }
1345 
1346  return CommandCost();
1347 }
1348 
1349 bool IsSlopeRefused(Slope current, Slope refused)
1350 {
1351  if (IsSteepSlope(current)) return true;
1352  if (current != SLOPE_FLAT) {
1353  if (IsSteepSlope(refused)) return true;
1354 
1355  Slope t = ComplementSlope(current);
1356 
1357  if ((refused & SLOPE_W) && (t & SLOPE_NW)) return true;
1358  if ((refused & SLOPE_S) && (t & SLOPE_NE)) return true;
1359  if ((refused & SLOPE_E) && (t & SLOPE_SW)) return true;
1360  if ((refused & SLOPE_N) && (t & SLOPE_SE)) return true;
1361  }
1362 
1363  return false;
1364 }
1365 
1378 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)
1379 {
1380  bool refused_slope = false;
1381  bool custom_shape = false;
1382 
1383  do {
1384  IndustryGfx gfx = GetTranslatedIndustryTileID(it->gfx);
1385  TileIndex cur_tile = TileAddWrap(tile, it->ti.x, it->ti.y);
1386 
1387  if (!IsValidTile(cur_tile)) {
1388  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1389  }
1390 
1391  if (gfx == GFX_WATERTILE_SPECIALCHECK) {
1392  if (!IsWaterTile(cur_tile) ||
1393  !IsTileFlat(cur_tile)) {
1394  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1395  }
1396  } else {
1397  CommandCost ret = EnsureNoVehicleOnGround(cur_tile);
1398  if (ret.Failed()) return ret;
1399  if (IsBridgeAbove(cur_tile)) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1400 
1401  const IndustryTileSpec *its = GetIndustryTileSpec(gfx);
1402 
1403  IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
1404 
1405  /* Perform land/water check if not disabled */
1406  if (!HasBit(its->slopes_refused, 5) && ((HasTileWaterClass(cur_tile) && IsTileOnWater(cur_tile)) == !(ind_behav & INDUSTRYBEH_BUILT_ONWATER))) return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1407 
1409  custom_shape = true;
1410  CommandCost ret = PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index, initial_random_bits, founder, creation_type);
1411  if (ret.Failed()) return ret;
1412  } else {
1413  Slope tileh = GetTileSlope(cur_tile);
1414  refused_slope |= IsSlopeRefused(tileh, its->slopes_refused);
1415  }
1416 
1417  if ((ind_behav & (INDUSTRYBEH_ONLY_INTOWN | INDUSTRYBEH_TOWN1200_MORE)) || // Tile must be a house
1418  ((ind_behav & INDUSTRYBEH_ONLY_NEARTOWN) && IsTileType(cur_tile, MP_HOUSE))) { // Tile is allowed to be a house (and it is a house)
1419  if (!IsTileType(cur_tile, MP_HOUSE)) {
1420  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS);
1421  }
1422 
1423  /* Clear the tiles as OWNER_TOWN to not affect town rating, and to not clear protected buildings */
1424  Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
1425  CommandCost ret = DoCommand(cur_tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR);
1426  cur_company.Restore();
1427 
1428  if (ret.Failed()) return ret;
1429  } else {
1430  /* Clear the tiles, but do not affect town ratings */
1432 
1433  if (ret.Failed()) return ret;
1434  }
1435  }
1436  } while ((++it)->ti.x != -0x80);
1437 
1438  if (custom_shape_check != NULL) *custom_shape_check = custom_shape;
1439 
1440  /* It is almost impossible to have a fully flat land in TG, so what we
1441  * do is that we check if we can make the land flat later on. See
1442  * CheckIfCanLevelIndustryPlatform(). */
1443  if (!refused_slope || (_settings_game.game_creation.land_generator == LG_TERRAGENESIS && _generating_world && !custom_shape && !_ignore_restrictions)) {
1444  return CommandCost();
1445  }
1446  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1447 }
1448 
1457 {
1458  if ((GetIndustrySpec(type)->behaviour & INDUSTRYBEH_TOWN1200_MORE) && t->cache.population < 1200) {
1459  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200);
1460  }
1461 
1462  if ((GetIndustrySpec(type)->behaviour & INDUSTRYBEH_ONLY_NEARTOWN) && DistanceMax(t->xy, tile) > 9) {
1463  return_cmd_error(STR_ERROR_CAN_ONLY_BE_BUILT_NEAR_TOWN_CENTER);
1464  }
1465 
1466  return CommandCost();
1467 }
1468 
1469 static bool CheckCanTerraformSurroundingTiles(TileIndex tile, uint height, int internal)
1470 {
1471  /* Check if we don't leave the map */
1472  if (TileX(tile) == 0 || TileY(tile) == 0 || GetTileType(tile) == MP_VOID) return false;
1473 
1474  TileArea ta(tile - TileDiffXY(1, 1), 2, 2);
1475  TILE_AREA_LOOP(tile_walk, ta) {
1476  uint curh = TileHeight(tile_walk);
1477  /* Is the tile clear? */
1478  if ((GetTileType(tile_walk) != MP_CLEAR) && (GetTileType(tile_walk) != MP_TREES)) return false;
1479 
1480  /* Don't allow too big of a change if this is the sub-tile check */
1481  if (internal != 0 && Delta(curh, height) > 1) return false;
1482 
1483  /* Different height, so the surrounding tiles of this tile
1484  * has to be correct too (in level, or almost in level)
1485  * else you get a chain-reaction of terraforming. */
1486  if (internal == 0 && curh != height) {
1487  if (TileX(tile_walk) == 0 || TileY(tile_walk) == 0 || !CheckCanTerraformSurroundingTiles(tile_walk + TileDiffXY(-1, -1), height, internal + 1)) {
1488  return false;
1489  }
1490  }
1491  }
1492 
1493  return true;
1494 }
1495 
1501 {
1502  const int MKEND = -0x80; // used for last element in an IndustryTileTable (see build_industry.h)
1503  int max_x = 0;
1504  int max_y = 0;
1505 
1506  /* Finds dimensions of largest variant of this industry */
1507  do {
1508  if (it->gfx == 0xFF) continue; // FF been a marquer for a check on clear water, skip it
1509  if (it->ti.x > max_x) max_x = it->ti.x;
1510  if (it->ti.y > max_y) max_y = it->ti.y;
1511  } while ((++it)->ti.x != MKEND);
1512 
1513  /* Remember level height */
1514  uint h = TileHeight(tile);
1515 
1516  if (TileX(tile) <= _settings_game.construction.industry_platform + 1U || TileY(tile) <= _settings_game.construction.industry_platform + 1U) return false;
1517  /* Check that all tiles in area and surrounding are clear
1518  * this determines that there are no obstructing items */
1519 
1522 
1523  if (TileX(ta.tile) + ta.w >= MapMaxX() || TileY(ta.tile) + ta.h >= MapMaxY()) return false;
1524 
1525  /* _current_company is OWNER_NONE for randomly generated industries and in editor, or the company who funded or prospected the industry.
1526  * Perform terraforming as OWNER_TOWN to disable autoslope and town ratings. */
1527  Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
1528 
1529  TILE_AREA_LOOP(tile_walk, ta) {
1530  uint curh = TileHeight(tile_walk);
1531  if (curh != h) {
1532  /* This tile needs terraforming. Check if we can do that without
1533  * damaging the surroundings too much. */
1534  if (!CheckCanTerraformSurroundingTiles(tile_walk, h, 0)) {
1535  cur_company.Restore();
1536  return false;
1537  }
1538  /* This is not 100% correct check, but the best we can do without modifying the map.
1539  * What is missing, is if the difference in height is more than 1.. */
1540  if (DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags & ~DC_EXEC, CMD_TERRAFORM_LAND).Failed()) {
1541  cur_company.Restore();
1542  return false;
1543  }
1544  }
1545  }
1546 
1547  if (flags & DC_EXEC) {
1548  /* Terraform the land under the industry */
1549  TILE_AREA_LOOP(tile_walk, ta) {
1550  uint curh = TileHeight(tile_walk);
1551  while (curh != h) {
1552  /* We give the terraforming for free here, because we can't calculate
1553  * exact cost in the test-round, and as we all know, that will cause
1554  * a nice assert if they don't match ;) */
1555  DoCommand(tile_walk, SLOPE_N, (curh > h) ? 0 : 1, flags, CMD_TERRAFORM_LAND);
1556  curh += (curh > h) ? -1 : 1;
1557  }
1558  }
1559  }
1560 
1561  cur_company.Restore();
1562  return true;
1563 }
1564 
1565 
1573 {
1574  const IndustrySpec *indspec = GetIndustrySpec(type);
1575  const Industry *i = NULL;
1576 
1577  /* On a large map with many industries, it may be faster to check an area. */
1578  static const int dmax = 14;
1579  if (Industry::GetNumItems() > (size_t) (dmax * dmax * 2)) {
1580  const int tx = TileX(tile);
1581  const int ty = TileY(tile);
1582  TileArea tile_area = TileArea(TileXY(max(0, tx - dmax), max(0, ty - dmax)), TileXY(min(MapMaxX(), tx + dmax), min(MapMaxY(), ty + dmax)));
1583  TILE_AREA_LOOP(atile, tile_area) {
1584  if (GetTileType(atile) == MP_INDUSTRY) {
1585  const Industry *i2 = Industry::GetByTile(atile);
1586  if (i == i2) continue;
1587  i = i2;
1588  if (DistanceMax(tile, i->location.tile) > (uint)dmax) continue;
1589  if (i->type == indspec->conflicting[0] ||
1590  i->type == indspec->conflicting[1] ||
1591  i->type == indspec->conflicting[2]) {
1592  return_cmd_error(STR_ERROR_INDUSTRY_TOO_CLOSE);
1593  }
1594  }
1595  }
1596  return CommandCost();
1597  }
1598 
1599  FOR_ALL_INDUSTRIES(i) {
1600  /* Within 14 tiles from another industry is considered close */
1601  if (DistanceMax(tile, i->location.tile) > 14) continue;
1602 
1603  /* check if there are any conflicting industry types around */
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  return CommandCost();
1611 }
1612 
1617 static void AdvertiseIndustryOpening(const Industry *ind)
1618 {
1619  const IndustrySpec *ind_spc = GetIndustrySpec(ind->type);
1620  SetDParam(0, ind_spc->name);
1621  if (ind_spc->new_industry_text > STR_LAST_STRINGID) {
1622  SetDParam(1, STR_TOWN_NAME);
1623  SetDParam(2, ind->town->index);
1624  } else {
1625  SetDParam(1, ind->town->index);
1626  }
1627  AddIndustryNewsItem(ind_spc->new_industry_text, NT_INDUSTRY_OPEN, ind->index);
1628  AI::BroadcastNewEvent(new ScriptEventIndustryOpen(ind->index));
1629  Game::NewEvent(new ScriptEventIndustryOpen(ind->index));
1630 }
1631 
1643 static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, const IndustryTileTable *it, byte layout, Town *t, Owner founder, uint16 initial_random_bits)
1644 {
1645  const IndustrySpec *indspec = GetIndustrySpec(type);
1646 
1647  i->location = TileArea(tile, 1, 1);
1648  i->type = type;
1650 
1651  i->produced_cargo[0] = indspec->produced_cargo[0];
1652  i->produced_cargo[1] = indspec->produced_cargo[1];
1653  i->accepts_cargo[0] = indspec->accepts_cargo[0];
1654  i->accepts_cargo[1] = indspec->accepts_cargo[1];
1655  i->accepts_cargo[2] = indspec->accepts_cargo[2];
1656  i->production_rate[0] = indspec->production_rate[0];
1657  i->production_rate[1] = indspec->production_rate[1];
1658 
1659  /* don't use smooth economy for industries using production related callbacks */
1660  if (indspec->UsesSmoothEconomy()) {
1661  i->production_rate[0] = min((RandomRange(256) + 128) * i->production_rate[0] >> 8, 255);
1662  i->production_rate[1] = min((RandomRange(256) + 128) * i->production_rate[1] >> 8, 255);
1663  }
1664 
1665  i->town = t;
1666  i->owner = OWNER_NONE;
1667 
1668  uint16 r = Random();
1669  i->random_colour = GB(r, 0, 4);
1670  i->counter = GB(r, 4, 12);
1671  i->random = initial_random_bits;
1672  i->produced_cargo_waiting[0] = 0;
1673  i->produced_cargo_waiting[1] = 0;
1674  i->incoming_cargo_waiting[0] = 0;
1675  i->incoming_cargo_waiting[1] = 0;
1676  i->incoming_cargo_waiting[2] = 0;
1677  i->this_month_production[0] = 0;
1678  i->this_month_production[1] = 0;
1679  i->this_month_transported[0] = 0;
1680  i->this_month_transported[1] = 0;
1681  i->last_month_pct_transported[0] = 0;
1682  i->last_month_pct_transported[1] = 0;
1683  i->last_month_transported[0] = 0;
1684  i->last_month_transported[1] = 0;
1685  i->was_cargo_delivered = false;
1687  i->founder = founder;
1688 
1689  i->construction_date = _date;
1690  i->construction_type = (_game_mode == GM_EDITOR) ? ICT_SCENARIO_EDITOR :
1692 
1693  /* Adding 1 here makes it conform to specs of var44 of varaction2 for industries
1694  * 0 = created prior of newindustries
1695  * else, chosen layout + 1 */
1696  i->selected_layout = layout + 1;
1697 
1699 
1700  /* Call callbacks after the regular fields got initialised. */
1701 
1703  uint16 res = GetIndustryCallback(CBID_INDUSTRY_PROD_CHANGE_BUILD, 0, Random(), i, type, INVALID_TILE);
1704  if (res != CALLBACK_FAILED) {
1705  if (res < PRODLEVEL_MINIMUM || res > PRODLEVEL_MAXIMUM) {
1707  } else {
1708  i->prod_level = res;
1710  }
1711  }
1712  }
1713 
1714  if (_generating_world) {
1715  i->last_month_production[0] = i->production_rate[0] * 8;
1716  i->last_month_production[1] = i->production_rate[1] * 8;
1717  } else {
1718  i->last_month_production[0] = i->last_month_production[1] = 0;
1719  }
1720 
1721  if (HasBit(indspec->callback_mask, CBM_IND_DECIDE_COLOUR)) {
1722  uint16 res = GetIndustryCallback(CBID_INDUSTRY_DECIDE_COLOUR, 0, 0, i, type, INVALID_TILE);
1723  if (res != CALLBACK_FAILED) {
1724  if (GB(res, 4, 11) != 0) ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_DECIDE_COLOUR, res);
1725  i->random_colour = GB(res, 0, 4);
1726  }
1727  }
1728 
1730  for (uint j = 0; j < lengthof(i->accepts_cargo); j++) i->accepts_cargo[j] = CT_INVALID;
1731  for (uint j = 0; j < lengthof(i->accepts_cargo); j++) {
1733  if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
1734  if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) {
1736  break;
1737  }
1738  i->accepts_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
1739  }
1740  }
1741 
1743  for (uint j = 0; j < lengthof(i->produced_cargo); j++) i->produced_cargo[j] = CT_INVALID;
1744  for (uint j = 0; j < lengthof(i->produced_cargo); j++) {
1746  if (res == CALLBACK_FAILED || GB(res, 0, 8) == CT_INVALID) break;
1747  if (indspec->grf_prop.grffile->grf_version >= 8 && res >= 0x100) {
1749  break;
1750  }
1751  i->produced_cargo[j] = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile);
1752  }
1753  }
1754 
1755  /* Plant the tiles */
1756 
1757  do {
1758  TileIndex cur_tile = tile + ToTileIndexDiff(it->ti);
1759 
1760  if (it->gfx != GFX_WATERTILE_SPECIALCHECK) {
1761  i->location.Add(cur_tile);
1762 
1763  WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID);
1764 
1766 
1767  MakeIndustry(cur_tile, i->index, it->gfx, Random(), wc);
1768 
1769  if (_generating_world) {
1770  SetIndustryConstructionCounter(cur_tile, 3);
1771  SetIndustryConstructionStage(cur_tile, 2);
1772  }
1773 
1774  /* it->gfx is stored in the map. But the translated ID cur_gfx is the interesting one */
1775  IndustryGfx cur_gfx = GetTranslatedIndustryTileID(it->gfx);
1776  const IndustryTileSpec *its = GetIndustryTileSpec(cur_gfx);
1778  }
1779  } while ((++it)->ti.x != -0x80);
1780 
1782  for (uint j = 0; j != 50; j++) PlantRandomFarmField(i);
1783  }
1785 
1787 }
1788 
1805 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)
1806 {
1807  assert(itspec_index < indspec->num_table);
1808  const IndustryTileTable *it = indspec->table[itspec_index];
1809  bool custom_shape_check = false;
1810 
1811  *ip = NULL;
1812 
1813  SmallVector<ClearedObjectArea, 1> object_areas(_cleared_object_areas);
1814  CommandCost ret = CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, random_initial_bits, founder, creation_type, &custom_shape_check);
1815  _cleared_object_areas = object_areas;
1816  if (ret.Failed()) return ret;
1817 
1818  if (HasBit(GetIndustrySpec(type)->callback_mask, CBM_IND_LOCATION)) {
1819  ret = CheckIfCallBackAllowsCreation(tile, type, itspec_index, random_var8f, random_initial_bits, founder, creation_type);
1820  } else {
1821  ret = _check_new_industry_procs[indspec->check_proc](tile);
1822  }
1823  if (ret.Failed()) return ret;
1824 
1826  !_ignore_restrictions && !CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER, it, type)) {
1827  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
1828  }
1829 
1830  ret = CheckIfFarEnoughFromConflictingIndustry(tile, type);
1831  if (ret.Failed()) return ret;
1832 
1833  Town *t = NULL;
1834  ret = FindTownForIndustry(tile, type, &t);
1835  if (ret.Failed()) return ret;
1836  assert(t != NULL);
1837 
1838  ret = CheckIfIndustryIsAllowed(tile, type, t);
1839  if (ret.Failed()) return ret;
1840 
1841  if (!Industry::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_INDUSTRIES);
1842 
1843  if (flags & DC_EXEC) {
1844  *ip = new Industry(tile);
1845  if (!custom_shape_check) CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER | DC_EXEC, it, type);
1846  DoCreateNewIndustry(*ip, tile, type, it, itspec_index, t, founder, random_initial_bits);
1847  }
1848 
1849  return CommandCost();
1850 }
1851 
1864 CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
1865 {
1866  IndustryType it = GB(p1, 0, 8);
1867  if (it >= NUM_INDUSTRYTYPES) return CMD_ERROR;
1868 
1869  const IndustrySpec *indspec = GetIndustrySpec(it);
1870 
1871  /* Check if the to-be built/founded industry is available for this climate. */
1872  if (!indspec->enabled || indspec->num_table == 0) return CMD_ERROR;
1873 
1874  /* If the setting for raw-material industries is not on, you cannot build raw-material industries.
1875  * Raw material industries are industries that do not accept cargo (at least for now) */
1876  if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 0 && indspec->IsRawIndustry()) {
1877  return CMD_ERROR;
1878  }
1879 
1880  if (_game_mode != GM_EDITOR && GetIndustryProbabilityCallback(it, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, 1) == 0) {
1881  return CMD_ERROR;
1882  }
1883 
1884  Randomizer randomizer;
1885  randomizer.SetSeed(p2);
1886  uint16 random_initial_bits = GB(p2, 0, 16);
1887  uint32 random_var8f = randomizer.Next();
1888  int num_layouts = indspec->num_table;
1889  CommandCost ret = CommandCost(STR_ERROR_SITE_UNSUITABLE);
1890  const bool deity_prospect = _current_company == OWNER_DEITY && !HasBit(p1, 16);
1891 
1892  Industry *ind = NULL;
1893  if (deity_prospect || (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry())) {
1894  if (flags & DC_EXEC) {
1895  /* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */
1896  Backup<CompanyByte> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
1897  /* Prospecting has a chance to fail, however we cannot guarantee that something can
1898  * be built on the map, so the chance gets lower when the map is fuller, but there
1899  * is nothing we can really do about that. */
1900  if (deity_prospect || Random() <= indspec->prospecting_chance) {
1901  for (int i = 0; i < 5000; i++) {
1902  /* We should not have more than one Random() in a function call
1903  * because parameter evaluation order is not guaranteed in the c++ standard
1904  */
1905  tile = RandomTile();
1906  /* Start with a random layout */
1907  int layout = RandomRange(num_layouts);
1908  /* Check now each layout, starting with the random one */
1909  for (int j = 0; j < num_layouts; j++) {
1910  layout = (layout + 1) % num_layouts;
1911  ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, cur_company.GetOriginalValue(), _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_PROSPECTCREATION, &ind);
1912  if (ret.Succeeded()) break;
1913  }
1914  if (ret.Succeeded()) break;
1915  }
1916  }
1917  cur_company.Restore();
1918  }
1919  } else {
1920  int layout = GB(p1, 8, 8);
1921  if (layout >= num_layouts) return CMD_ERROR;
1922 
1923  /* Check subsequently each layout, starting with the given layout in p1 */
1924  for (int i = 0; i < num_layouts; i++) {
1925  layout = (layout + 1) % num_layouts;
1926  ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, _current_company, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, &ind);
1927  if (ret.Succeeded()) break;
1928  }
1929 
1930  /* If it still failed, there's no suitable layout to build here, return the error */
1931  if (ret.Failed()) return ret;
1932  }
1933 
1934  if ((flags & DC_EXEC) && ind != NULL && _game_mode != GM_EDITOR) {
1936  }
1937 
1938  return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
1939 }
1940 
1941 
1949 static Industry *CreateNewIndustry(TileIndex tile, IndustryType type, IndustryAvailabilityCallType creation_type)
1950 {
1951  const IndustrySpec *indspec = GetIndustrySpec(type);
1952 
1953  uint32 seed = Random();
1954  uint32 seed2 = Random();
1955  Industry *i = NULL;
1956  CommandCost ret = CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, RandomRange(indspec->num_table), seed, GB(seed2, 0, 16), OWNER_NONE, creation_type, &i);
1957  assert(i != NULL || ret.Failed());
1958  return i;
1959 }
1960 
1967 static uint32 GetScaledIndustryGenerationProbability(IndustryType it, bool *force_at_least_one)
1968 {
1969  const IndustrySpec *ind_spc = GetIndustrySpec(it);
1970  uint32 chance = ind_spc->appear_creation[_settings_game.game_creation.landscape] * 16; // * 16 to increase precision
1971  if (!ind_spc->enabled || ind_spc->num_table == 0 ||
1972  (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) ||
1973  (chance = GetIndustryProbabilityCallback(it, IACT_MAPGENERATION, chance)) == 0) {
1974  *force_at_least_one = false;
1975  return 0;
1976  } else {
1977  /* We want industries appearing at coast to appear less often on bigger maps, as length of coast increases slower than map area.
1978  * For simplicity we scale in both cases, though scaling the probabilities of all industries has no effect. */
1979  chance = (ind_spc->check_proc == CHECK_REFINERY || ind_spc->check_proc == CHECK_OIL_RIG) ? ScaleByMapSize1D(chance) : ScaleByMapSize(chance);
1980 
1981  *force_at_least_one = (chance > 0) && !(ind_spc->behaviour & INDUSTRYBEH_NOBUILT_MAPCREATION) && (_game_mode != GM_EDITOR);
1982  return chance;
1983  }
1984 }
1985 
1992 static uint16 GetIndustryGamePlayProbability(IndustryType it, byte *min_number)
1993 {
1995  *min_number = 0;
1996  return 0;
1997  }
1998 
1999  const IndustrySpec *ind_spc = GetIndustrySpec(it);
2000  byte chance = ind_spc->appear_ingame[_settings_game.game_creation.landscape];
2001  if (!ind_spc->enabled || ind_spc->num_table == 0 ||
2002  ((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && _cur_year > 1950) ||
2003  ((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && _cur_year < 1960) ||
2004  (chance = GetIndustryProbabilityCallback(it, IACT_RANDOMCREATION, chance)) == 0) {
2005  *min_number = 0;
2006  return 0;
2007  }
2008  *min_number = (ind_spc->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) ? 1 : 0;
2009  return chance;
2010 }
2011 
2017 {
2018  /* Number of industries on a 256x256 map. */
2019  static const uint16 numof_industry_table[] = {
2020  0, // none
2021  0, // minimal
2022  10, // very low
2023  25, // low
2024  55, // normal
2025  80, // high
2026  };
2027 
2028  assert(lengthof(numof_industry_table) == ID_END);
2029  uint difficulty = (_game_mode != GM_EDITOR) ? _settings_game.difficulty.industry_density : (uint)ID_VERY_LOW;
2030  return min(IndustryPool::MAX_SIZE, ScaleByMapSize(numof_industry_table[difficulty]));
2031 }
2032 
2041 static Industry *PlaceIndustry(IndustryType type, IndustryAvailabilityCallType creation_type, bool try_hard)
2042 {
2043  uint tries = try_hard ? 10000u : 2000u;
2044  for (; tries > 0; tries--) {
2045  Industry *ind = CreateNewIndustry(RandomTile(), type, creation_type);
2046  if (ind != NULL) return ind;
2047  }
2048  return NULL;
2049 }
2050 
2056 static void PlaceInitialIndustry(IndustryType type, bool try_hard)
2057 {
2058  Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2059 
2061  PlaceIndustry(type, IACT_MAPGENERATION, try_hard);
2062 
2063  cur_company.Restore();
2064 }
2065 
2071 {
2072  int total = 0;
2073  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) total += Industry::GetIndustryTypeCount(it);
2074  return total;
2075 }
2076 
2077 
2080 {
2081  this->probability = 0;
2082  this->min_number = 0;
2083  this->target_count = 0;
2084  this->max_wait = 1;
2085  this->wait_count = 0;
2086 }
2087 
2090 {
2091  this->wanted_inds = GetCurrentTotalNumberOfIndustries() << 16;
2092 
2093  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2094  this->builddata[it].Reset();
2095  }
2096 }
2097 
2100 {
2101  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.
2102  if (_settings_game.difficulty.industry_density == ID_FUND_ONLY) return; // 'no industries' setting.
2103 
2104  /* To prevent running out of unused industries for the player to connect,
2105  * add a fraction of new industries each month, but only if the manager can keep up. */
2106  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).
2107  if (GetCurrentTotalNumberOfIndustries() + max_behind >= (this->wanted_inds >> 16)) {
2108  this->wanted_inds += ScaleByMapSize(NEWINDS_PER_MONTH);
2109  }
2110 }
2111 
2117 {
2118  if (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) return; // No industries in the game.
2119 
2120  uint32 industry_probs[NUM_INDUSTRYTYPES];
2121  bool force_at_least_one[NUM_INDUSTRYTYPES];
2122  uint32 total_prob = 0;
2123  uint num_forced = 0;
2124 
2125  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2126  industry_probs[it] = GetScaledIndustryGenerationProbability(it, force_at_least_one + it);
2127  total_prob += industry_probs[it];
2128  if (force_at_least_one[it]) num_forced++;
2129  }
2130 
2131  uint total_amount = GetNumberOfIndustries();
2132  if (total_prob == 0 || total_amount < num_forced) {
2133  /* Only place the forced ones */
2134  total_amount = num_forced;
2135  }
2136 
2138 
2139  /* Try to build one industry per type independent of any probabilities */
2140  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2141  if (force_at_least_one[it]) {
2142  assert(total_amount > 0);
2143  total_amount--;
2144  PlaceInitialIndustry(it, true);
2145  }
2146  }
2147 
2148  /* Add the remaining industries according to their probabilities */
2149  for (uint i = 0; i < total_amount; i++) {
2150  uint32 r = RandomRange(total_prob);
2151  IndustryType it = 0;
2152  while (r >= industry_probs[it]) {
2153  r -= industry_probs[it];
2154  it++;
2155  assert(it < NUM_INDUSTRYTYPES);
2156  }
2157  assert(industry_probs[it] > 0);
2158  PlaceInitialIndustry(it, false);
2159  }
2160  _industry_builder.Reset();
2161 }
2162 
2168 {
2169  for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
2170  if (i->produced_cargo[j] != CT_INVALID) {
2171  byte pct = 0;
2172  if (i->this_month_production[j] != 0) {
2174  pct = min(i->this_month_transported[j] * 256 / i->this_month_production[j], 255);
2175  }
2176  i->last_month_pct_transported[j] = pct;
2177 
2179  i->this_month_production[j] = 0;
2180 
2182  i->this_month_transported[j] = 0;
2183  }
2184  }
2185 }
2186 
2192 {
2193  const IndustrySpec *indspec = GetIndustrySpec(this->type);
2194  assert(!indspec->UsesSmoothEconomy());
2195 
2196  /* Rates are rounded up, so e.g. oilrig always produces some passengers */
2197  this->production_rate[0] = min(CeilDiv(indspec->production_rate[0] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF);
2198  this->production_rate[1] = min(CeilDiv(indspec->production_rate[1] * this->prod_level, PRODLEVEL_DEFAULT), 0xFF);
2199 }
2200 
2201 
2208 {
2209  byte min_number;
2210  uint32 probability = GetIndustryGamePlayProbability(it, &min_number);
2211  bool changed = min_number != this->min_number || probability != this->probability;
2212  this->min_number = min_number;
2213  this->probability = probability;
2214  return changed;
2215 }
2216 
2219 {
2220  bool changed = false;
2221  uint num_planned = 0; // Number of industries planned in the industry build data.
2222  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2223  changed |= this->builddata[it].GetIndustryTypeData(it);
2224  num_planned += this->builddata[it].target_count;
2225  }
2226  uint total_amount = this->wanted_inds >> 16; // Desired total number of industries.
2227  changed |= num_planned != total_amount;
2228  if (!changed) return; // All industries are still the same, no need to re-randomize.
2229 
2230  /* Initialize the target counts. */
2231  uint force_build = 0; // Number of industries that should always be available.
2232  uint32 total_prob = 0; // Sum of probabilities.
2233  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2234  IndustryTypeBuildData *ibd = this->builddata + it;
2235  force_build += ibd->min_number;
2236  ibd->target_count = ibd->min_number;
2237  total_prob += ibd->probability;
2238  }
2239 
2240  if (total_prob == 0) return; // No buildable industries.
2241 
2242  /* Subtract forced industries from the number of industries available for construction. */
2243  total_amount = (total_amount <= force_build) ? 0 : total_amount - force_build;
2244 
2245  /* Assign number of industries that should be aimed for, by using the probability as a weight. */
2246  while (total_amount > 0) {
2247  uint32 r = RandomRange(total_prob);
2248  IndustryType it = 0;
2249  while (r >= this->builddata[it].probability) {
2250  r -= this->builddata[it].probability;
2251  it++;
2252  assert(it < NUM_INDUSTRYTYPES);
2253  }
2254  assert(this->builddata[it].probability > 0);
2255  this->builddata[it].target_count++;
2256  total_amount--;
2257  }
2258 }
2259 
2264 {
2265  this->SetupTargetCount();
2266 
2267  int missing = 0; // Number of industries that need to be build.
2268  uint count = 0; // Number of industry types eligible for build.
2269  uint32 total_prob = 0; // Sum of probabilities.
2270  IndustryType forced_build = NUM_INDUSTRYTYPES; // Industry type that should be forcibly build.
2271  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2272  int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
2273  missing += difference;
2274  if (this->builddata[it].wait_count > 0) continue; // This type may not be built now.
2275  if (difference > 0) {
2276  if (Industry::GetIndustryTypeCount(it) == 0 && this->builddata[it].min_number > 0) {
2277  /* An industry that should exist at least once, is not available. Force it, trying the most needed one first. */
2278  if (forced_build == NUM_INDUSTRYTYPES ||
2279  difference > this->builddata[forced_build].target_count - Industry::GetIndustryTypeCount(forced_build)) {
2280  forced_build = it;
2281  }
2282  }
2283  total_prob += difference;
2284  count++;
2285  }
2286  }
2287 
2288  if (EconomyIsInRecession() || (forced_build == NUM_INDUSTRYTYPES && (missing <= 0 || total_prob == 0))) count = 0; // Skip creation of an industry.
2289 
2290  if (count >= 1) {
2291  /* If not forced, pick a weighted random industry to build.
2292  * For the case that count == 1, there is no need to draw a random number. */
2293  IndustryType it;
2294  if (forced_build != NUM_INDUSTRYTYPES) {
2295  it = forced_build;
2296  } else {
2297  /* Non-forced, select an industry type to build (weighted random). */
2298  uint32 r = 0; // Initialized to silence the compiler.
2299  if (count > 1) r = RandomRange(total_prob);
2300  for (it = 0; it < NUM_INDUSTRYTYPES; it++) {
2301  if (this->builddata[it].wait_count > 0) continue; // Type may not be built now.
2302  int difference = this->builddata[it].target_count - Industry::GetIndustryTypeCount(it);
2303  if (difference <= 0) continue; // Too many of this kind.
2304  if (count == 1) break;
2305  if (r < (uint)difference) break;
2306  r -= difference;
2307  }
2308  assert(it < NUM_INDUSTRYTYPES && this->builddata[it].target_count > Industry::GetIndustryTypeCount(it));
2309  }
2310 
2311  /* Try to create the industry. */
2312  const Industry *ind = PlaceIndustry(it, IACT_RANDOMCREATION, false);
2313  if (ind == NULL) {
2314  this->builddata[it].wait_count = this->builddata[it].max_wait + 1; // Compensate for decrementing below.
2315  this->builddata[it].max_wait = min(1000, this->builddata[it].max_wait + 2);
2316  } else {
2318  this->builddata[it].max_wait = max(this->builddata[it].max_wait / 2, 1); // Reduce waiting time of the industry type.
2319  }
2320  }
2321 
2322  /* Decrement wait counters. */
2323  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2324  if (this->builddata[it].wait_count > 0) this->builddata[it].wait_count--;
2325  }
2326 }
2327 
2336 static bool CheckIndustryCloseDownProtection(IndustryType type)
2337 {
2338  const IndustrySpec *indspec = GetIndustrySpec(type);
2339 
2340  /* oil wells (or the industries with that flag set) are always allowed to closedown */
2341  if ((indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE) return false;
2342  return (indspec->behaviour & INDUSTRYBEH_CANCLOSE_LASTINSTANCE) == 0 && Industry::GetIndustryTypeCount(type) <= 1;
2343 }
2344 
2354 static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accepts, bool *c_produces)
2355 {
2356  if (cargo == CT_INVALID) return;
2357 
2358  /* Check for acceptance of cargo */
2359  for (byte j = 0; j < lengthof(ind->accepts_cargo); j++) {
2360  if (cargo == ind->accepts_cargo[j] && !IndustryTemporarilyRefusesCargo(ind, cargo)) {
2361  *c_accepts = true;
2362  break;
2363  }
2364  }
2365 
2366  /* Check for produced cargo */
2367  for (byte j = 0; j < lengthof(ind->produced_cargo); j++) {
2368  if (cargo == ind->produced_cargo[j]) {
2369  *c_produces = true;
2370  break;
2371  }
2372  }
2373 }
2374 
2389 {
2390  /* Find all stations within reach of the industry */
2391  StationList stations;
2392  FindStationsAroundTiles(ind->location, &stations);
2393 
2394  if (stations.Length() == 0) return 0; // No stations found at all => nobody services
2395 
2396  const Vehicle *v;
2397  int result = 0;
2398  FOR_ALL_VEHICLES(v) {
2399  /* Is it worthwhile to try this vehicle? */
2400  if (v->owner != _local_company && result != 0) continue;
2401 
2402  /* Check whether it accepts the right kind of cargo */
2403  bool c_accepts = false;
2404  bool c_produces = false;
2405  if (v->type == VEH_TRAIN && v->IsFrontEngine()) {
2406  for (const Vehicle *u = v; u != NULL; u = u->Next()) {
2407  CanCargoServiceIndustry(u->cargo_type, ind, &c_accepts, &c_produces);
2408  }
2409  } else if (v->type == VEH_ROAD || v->type == VEH_SHIP || v->type == VEH_AIRCRAFT) {
2410  CanCargoServiceIndustry(v->cargo_type, ind, &c_accepts, &c_produces);
2411  } else {
2412  continue;
2413  }
2414  if (!c_accepts && !c_produces) continue; // Wrong cargo
2415 
2416  /* Check orders of the vehicle.
2417  * We cannot check the first of shared orders only, since the first vehicle in such a chain
2418  * may have a different cargo type.
2419  */
2420  const Order *o;
2421  FOR_VEHICLE_ORDERS(v, o) {
2422  if (o->IsType(OT_GOTO_STATION) && !(o->GetUnloadType() & OUFB_TRANSFER)) {
2423  /* Vehicle visits a station to load or unload */
2424  Station *st = Station::Get(o->GetDestination());
2425  assert(st != NULL);
2426 
2427  /* Same cargo produced by industry is dropped here => not serviced by vehicle v */
2428  if ((o->GetUnloadType() & OUFB_UNLOAD) && !c_accepts) break;
2429 
2430  if (stations.Contains(st)) {
2431  if (v->owner == _local_company) return 2; // Company services industry
2432  result = 1; // Competitor services industry
2433  }
2434  }
2435  }
2436  }
2437  return result;
2438 }
2439 
2448 {
2449  NewsType nt;
2450 
2451  switch (WhoCanServiceIndustry(ind)) {
2452  case 0: nt = NT_INDUSTRY_NOBODY; break;
2453  case 1: nt = NT_INDUSTRY_OTHER; break;
2454  case 2: nt = NT_INDUSTRY_COMPANY; break;
2455  default: NOT_REACHED();
2456  }
2457  SetDParam(2, abs(percent));
2458  SetDParam(0, CargoSpec::Get(type)->name);
2459  SetDParam(1, ind->index);
2460  AddIndustryNewsItem(
2461  percent >= 0 ? STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH : STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH,
2462  nt,
2463  ind->index
2464  );
2465 }
2466 
2467 static const uint PERCENT_TRANSPORTED_60 = 153;
2468 static const uint PERCENT_TRANSPORTED_80 = 204;
2469 
2475 static void ChangeIndustryProduction(Industry *i, bool monthly)
2476 {
2477  StringID str = STR_NULL;
2478  bool closeit = false;
2479  const IndustrySpec *indspec = GetIndustrySpec(i->type);
2480  bool standard = false;
2481  bool suppress_message = false;
2482  bool recalculate_multipliers = false;
2483  /* don't use smooth economy for industries using production related callbacks */
2484  bool smooth_economy = indspec->UsesSmoothEconomy();
2485  byte div = 0;
2486  byte mul = 0;
2487  int8 increment = 0;
2488 
2489  bool callback_enabled = HasBit(indspec->callback_mask, monthly ? CBM_IND_MONTHLYPROD_CHANGE : CBM_IND_PRODUCTION_CHANGE);
2490  if (callback_enabled) {
2492  if (res != CALLBACK_FAILED) { // failed callback means "do nothing"
2493  suppress_message = HasBit(res, 7);
2494  /* Get the custom message if any */
2495  if (HasBit(res, 8)) str = MapGRFStringID(indspec->grf_prop.grffile->grfid, GB(GetRegister(0x100), 0, 16));
2496  res = GB(res, 0, 4);
2497  switch (res) {
2498  default: NOT_REACHED();
2499  case 0x0: break; // Do nothing, but show the custom message if any
2500  case 0x1: div = 1; break; // Halve industry production. If production reaches the quarter of the default, the industry is closed instead.
2501  case 0x2: mul = 1; break; // Double industry production if it hasn't reached eight times of the original yet.
2502  case 0x3: closeit = true; break; // The industry announces imminent closure, and is physically removed from the map next month.
2503  case 0x4: standard = true; break; // Do the standard random production change as if this industry was a primary one.
2504  case 0x5: case 0x6: case 0x7: // Divide production by 4, 8, 16
2505  case 0x8: div = res - 0x3; break; // Divide production by 32
2506  case 0x9: case 0xA: case 0xB: // Multiply production by 4, 8, 16
2507  case 0xC: mul = res - 0x7; break; // Multiply production by 32
2508  case 0xD: // decrement production
2509  case 0xE: // increment production
2510  increment = res == 0x0D ? -1 : 1;
2511  break;
2512  case 0xF: // Set production to third byte of register 0x100
2514  recalculate_multipliers = true;
2515  break;
2516  }
2517  }
2518  } else {
2519  if (monthly != smooth_economy) return;
2520  if (indspec->life_type == INDUSTRYLIFE_BLACK_HOLE) return;
2521  }
2522 
2523  if (standard || (!callback_enabled && (indspec->life_type & (INDUSTRYLIFE_ORGANIC | INDUSTRYLIFE_EXTRACTIVE)) != 0)) {
2524  /* decrease or increase */
2525  bool only_decrease = (indspec->behaviour & INDUSTRYBEH_DONT_INCR_PROD) && _settings_game.game_creation.landscape == LT_TEMPERATE;
2526 
2527  if (smooth_economy) {
2528  closeit = true;
2529  for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
2530  if (i->produced_cargo[j] == CT_INVALID) continue;
2531  uint32 r = Random();
2532  int old_prod, new_prod, percent;
2533  /* If over 60% is transported, mult is 1, else mult is -1. */
2534  int mult = (i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_60) ? 1 : -1;
2535 
2536  new_prod = old_prod = i->production_rate[j];
2537 
2538  /* For industries with only_decrease flags (temperate terrain Oil Wells),
2539  * the multiplier will always be -1 so they will only decrease. */
2540  if (only_decrease) {
2541  mult = -1;
2542  /* For normal industries, if over 60% is transported, 33% chance for decrease.
2543  * Bonus for very high station ratings (over 80%): 16% chance for decrease. */
2544  } else if (Chance16I(1, ((i->last_month_pct_transported[j] > PERCENT_TRANSPORTED_80) ? 6 : 3), r)) {
2545  mult *= -1;
2546  }
2547 
2548  /* 4.5% chance for 3-23% (or 1 unit for very low productions) production change,
2549  * determined by mult value. If mult = 1 prod. increases, else (-1) it decreases. */
2550  if (Chance16I(1, 22, r >> 16)) {
2551  new_prod += mult * (max(((RandomRange(50) + 10) * old_prod) >> 8, 1U));
2552  }
2553 
2554  /* Prevent production to overflow or Oil Rig passengers to be over-"produced" */
2555  new_prod = Clamp(new_prod, 1, 255);
2556 
2557  if (((indspec->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) && j == 1) {
2558  new_prod = Clamp(new_prod, 0, 16);
2559  }
2560 
2561  /* Do not stop closing the industry when it has the lowest possible production rate */
2562  if (new_prod == old_prod && old_prod > 1) {
2563  closeit = false;
2564  continue;
2565  }
2566 
2567  percent = (old_prod == 0) ? 100 : (new_prod * 100 / old_prod - 100);
2568  i->production_rate[j] = new_prod;
2569 
2570  /* Close the industry when it has the lowest possible production rate */
2571  if (new_prod > 1) closeit = false;
2572 
2573  if (abs(percent) >= 10) {
2575  }
2576  }
2577  } else {
2578  if (only_decrease || Chance16(1, 3)) {
2579  /* If more than 60% transported, 66% chance of increase, else 33% chance of increase */
2580  if (!only_decrease && (i->last_month_pct_transported[0] > PERCENT_TRANSPORTED_60) != Chance16(1, 3)) {
2581  mul = 1; // Increase production
2582  } else {
2583  div = 1; // Decrease production
2584  }
2585  }
2586  }
2587  }
2588 
2589  if (!callback_enabled && (indspec->life_type & INDUSTRYLIFE_PROCESSING)) {
2590  if ( (byte)(_cur_year - i->last_prod_year) >= 5 && Chance16(1, smooth_economy ? 180 : 2)) {
2591  closeit = true;
2592  }
2593  }
2594 
2595  /* Increase if needed */
2596  while (mul-- != 0 && i->prod_level < PRODLEVEL_MAXIMUM) {
2598  recalculate_multipliers = true;
2599  if (str == STR_NULL) str = indspec->production_up_text;
2600  }
2601 
2602  /* Decrease if needed */
2603  while (div-- != 0 && !closeit) {
2604  if (i->prod_level == PRODLEVEL_MINIMUM) {
2605  closeit = true;
2606  } else {
2607  i->prod_level = max(i->prod_level / 2, (int)PRODLEVEL_MINIMUM); // typecast to int required to please MSVC
2608  recalculate_multipliers = true;
2609  if (str == STR_NULL) str = indspec->production_down_text;
2610  }
2611  }
2612 
2613  /* Increase or Decreasing the production level if needed */
2614  if (increment != 0) {
2615  if (increment < 0 && i->prod_level == PRODLEVEL_MINIMUM) {
2616  closeit = true;
2617  } else {
2619  recalculate_multipliers = true;
2620  }
2621  }
2622 
2623  /* Recalculate production_rate
2624  * For non-smooth economy these should always be synchronized with prod_level */
2625  if (recalculate_multipliers) i->RecomputeProductionMultipliers();
2626 
2627  /* Close if needed and allowed */
2628  if (closeit && !CheckIndustryCloseDownProtection(i->type)) {
2631  str = indspec->closure_text;
2632  }
2633 
2634  if (!suppress_message && str != STR_NULL) {
2635  NewsType nt;
2636  /* Compute news category */
2637  if (closeit) {
2638  nt = NT_INDUSTRY_CLOSE;
2639  AI::BroadcastNewEvent(new ScriptEventIndustryClose(i->index));
2640  Game::NewEvent(new ScriptEventIndustryClose(i->index));
2641  } else {
2642  switch (WhoCanServiceIndustry(i)) {
2643  case 0: nt = NT_INDUSTRY_NOBODY; break;
2644  case 1: nt = NT_INDUSTRY_OTHER; break;
2645  case 2: nt = NT_INDUSTRY_COMPANY; break;
2646  default: NOT_REACHED();
2647  }
2648  }
2649  /* Set parameters of news string */
2650  if (str > STR_LAST_STRINGID) {
2651  SetDParam(0, STR_TOWN_NAME);
2652  SetDParam(1, i->town->index);
2653  SetDParam(2, indspec->name);
2654  } else if (closeit) {
2655  SetDParam(0, STR_FORMAT_INDUSTRY_NAME);
2656  SetDParam(1, i->town->index);
2657  SetDParam(2, indspec->name);
2658  } else {
2659  SetDParam(0, i->index);
2660  }
2661  /* and report the news to the user */
2662  if (closeit) {
2663  AddTileNewsItem(str, nt, i->location.tile + TileDiffXY(1, 1));
2664  } else {
2665  AddIndustryNewsItem(str, nt, i->index);
2666  }
2667  }
2668 }
2669 
2678 {
2680 
2681  /* Bits 16-31 of industry_construction_counter contain the number of industries to change/create today,
2682  * the lower 16 bit are a fractional part that might accumulate over several days until it
2683  * is sufficient for an industry. */
2684  uint16 change_loop = _economy.industry_daily_change_counter >> 16;
2685 
2686  /* Reset the active part of the counter, just keeping the "fractional part" */
2687  _economy.industry_daily_change_counter &= 0xFFFF;
2688 
2689  if (change_loop == 0) {
2690  return; // Nothing to do? get out
2691  }
2692 
2693  Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2694 
2695  /* perform the required industry changes for the day */
2696 
2697  uint perc = 3; // Between 3% and 9% chance of creating a new industry.
2698  if ((_industry_builder.wanted_inds >> 16) > GetCurrentTotalNumberOfIndustries()) {
2699  perc = min(9u, perc + (_industry_builder.wanted_inds >> 16) - GetCurrentTotalNumberOfIndustries());
2700  }
2701  for (uint16 j = 0; j < change_loop; j++) {
2702  if (Chance16(perc, 100)) {
2703  _industry_builder.TryBuildNewIndustry();
2704  } else {
2706  if (i != NULL) {
2707  ChangeIndustryProduction(i, false);
2709  }
2710  }
2711  }
2712 
2713  cur_company.Restore();
2714 
2715  /* production-change */
2717 }
2718 
2719 void IndustryMonthlyLoop()
2720 {
2721  Backup<CompanyByte> cur_company(_current_company, OWNER_NONE, FILE_LINE);
2722 
2723  _industry_builder.MonthlyLoop();
2724 
2725  Industry *i;
2726  FOR_ALL_INDUSTRIES(i) {
2728  if (i->prod_level == PRODLEVEL_CLOSURE) {
2729  delete i;
2730  } else {
2731  ChangeIndustryProduction(i, true);
2733  }
2734  }
2735 
2736  cur_company.Restore();
2737 
2738  /* production-change */
2740 }
2741 
2742 
2743 void InitializeIndustries()
2744 {
2746  _industry_sound_tile = 0;
2747 
2748  _industry_builder.Reset();
2749 }
2750 
2753 {
2754  int count = 0;
2755  for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) {
2756  if (Industry::GetIndustryTypeCount(it) > 0) continue; // Types of existing industries can be skipped.
2757 
2758  bool force_at_least_one;
2759  uint32 chance = GetScaledIndustryGenerationProbability(it, &force_at_least_one);
2760  if (chance == 0 || !force_at_least_one) continue; // Types that are not available can be skipped.
2761 
2762  const IndustrySpec *is = GetIndustrySpec(it);
2763  SetDParam(0, is->name);
2764  ShowErrorMessage(STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES, STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION, WL_WARNING);
2765 
2766  count++;
2767  if (count >= 3) break; // Don't swamp the user with errors.
2768  }
2769 }
2770 
2776 {
2777  return (this->life_type & (INDUSTRYLIFE_EXTRACTIVE | INDUSTRYLIFE_ORGANIC)) != 0;
2778 }
2779 
2785 {
2786  /* Lumber mills are neither raw nor processing */
2787  return (this->life_type & INDUSTRYLIFE_PROCESSING) != 0 &&
2788  (this->behaviour & INDUSTRYBEH_CUT_TREES) == 0;
2789 }
2790 
2796 {
2797  /* Building raw industries like secondary uses different price base */
2798  return (_price[(_settings_game.construction.raw_industry_construction == 1 && this->IsRawIndustry()) ?
2799  PR_BUILD_INDUSTRY_RAW : PR_BUILD_INDUSTRY] * this->cost_multiplier) >> 8;
2800 }
2801 
2809 {
2810  return (_price[PR_CLEAR_INDUSTRY] * this->removal_cost_multiplier) >> 8;
2811 }
2812 
2818 {
2820  !(HasBit(this->callback_mask, CBM_IND_PRODUCTION_256_TICKS) || HasBit(this->callback_mask, CBM_IND_PRODUCTION_CARGO_ARRIVAL)) && // production callbacks
2821  !(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
2822 }
2823 
2824 static CommandCost TerraformTile_Industry(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
2825 {
2826  if (AutoslopeEnabled()) {
2827  /* We imitate here TTDP's behaviour:
2828  * - Both new and old slope must not be steep.
2829  * - TileMaxZ must not be changed.
2830  * - Allow autoslope by default.
2831  * - Disallow autoslope if callback succeeds and returns non-zero.
2832  */
2833  Slope tileh_old = GetTileSlope(tile);
2834  /* TileMaxZ must not be changed. Slopes must not be steep. */
2835  if (!IsSteepSlope(tileh_old) && !IsSteepSlope(tileh_new) && (GetTileMaxZ(tile) == z_new + GetSlopeMaxZ(tileh_new))) {
2836  const IndustryGfx gfx = GetIndustryGfx(tile);
2837  const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx);
2838 
2839  /* Call callback 3C 'disable autosloping for industry tiles'. */
2840  if (HasBit(itspec->callback_mask, CBM_INDT_AUTOSLOPE)) {
2841  /* If the callback fails, allow autoslope. */
2842  uint16 res = GetIndustryTileCallback(CBID_INDTILE_AUTOSLOPE, 0, 0, gfx, Industry::GetByTile(tile), tile);
2843  if (res == CALLBACK_FAILED || !ConvertBooleanCallback(itspec->grf_prop.grffile, CBID_INDTILE_AUTOSLOPE, res)) return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2844  } else {
2845  /* allow autoslope */
2846  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_FOUNDATION]);
2847  }
2848  }
2849  }
2850  return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
2851 }
2852 
2853 extern const TileTypeProcs _tile_type_industry_procs = {
2854  DrawTile_Industry, // draw_tile_proc
2855  GetSlopePixelZ_Industry, // get_slope_z_proc
2856  ClearTile_Industry, // clear_tile_proc
2857  AddAcceptedCargo_Industry, // add_accepted_cargo_proc
2858  GetTileDesc_Industry, // get_tile_desc_proc
2859  GetTileTrackStatus_Industry, // get_tile_track_status_proc
2860  ClickTile_Industry, // click_tile_proc
2861  AnimateTile_Industry, // animate_tile_proc
2862  TileLoop_Industry, // tile_loop_proc
2863  ChangeTileOwner_Industry, // change_tile_owner_proc
2864  NULL, // add_produced_cargo_proc
2865  NULL, // vehicle_enter_tile_proc
2866  GetFoundation_Industry, // get_foundation_proc
2867  TerraformTile_Industry, // terraform_tile_proc
2868 };
static void ResetIndustryCounts()
Resets industry counts.
Definition: industry.h:136
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:89
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:343
Closing of industries.
Definition: news_type.h:42
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:352
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:425
void ClampToMap()
Clamp the tile area to map borders.
Definition: tilearea.cpp:123
byte image_2
image offset 2
Definition: industry_land.h:23
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:77
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition: game_core.cpp:134
uint8 acceptance[3]
Level of acceptance per cargo type.
Definition: industrytype.h:150
Trigger whenever the construction state changes.
bool enabled
entity still available (by default true).newgrf can disable it, though
Definition: industrytype.h:135
void SetupTargetCount()
Decide how many industries of each type are needed.
static TropicZone GetTropicZone(TileIndex tile)
Get the tropic zone.
Definition: tile_map.h:231
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:255
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:3120
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:53
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition: vehicle.cpp:538
below this level, the industry is set to be closing
Definition: industry.h:31
void DeleteIndustryNews(IndustryID iid)
Remove news regarding given industry.
Definition: news_gui.cpp:824
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:63
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:41
uint16 last_month_production[2]
total units produced per cargo in the last full month
Definition: industry.h:51
uint16 this_month_transported[2]
stats of this month&#39;s transport per cargo
Definition: industry.h:49
uint32 prospecting_chance
Chance prospecting succeeds.
Definition: industrytype.h:106
static byte GetAnimationFrame(TileIndex t)
Get the current animation frame.
Definition: tile_map.h:243
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:67
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:65
no flag is set
Definition: command_type.h:341
from the Fund/build window
default level set when the industry is created
Definition: industry.h:32
Other industry production changes.
Definition: news_type.h:46
IndustryLifeType life_type
This is also known as Industry production flag, in newgrf specs.
Definition: industrytype.h:118
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:133
CargoID accepts_cargo[3]
Cargo accepted by this tile.
Definition: industrytype.h:149
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:41
signal set to actually close the industry
Definition: industry.h:30
Defines the internal data of a functional industry.
Definition: industry.h:39
during random map creation
Definition: industrytype.h:57
demolish a tile
Definition: command_type.h:182
Tile description for the &#39;land area information&#39; tool.
Definition: tile_cmd.h:53
DifficultySettings difficulty
settings related to the difficulty
static void BroadcastNewEvent(ScriptEvent *event, CompanyID skip_company=MAX_COMPANIES)
Broadcast a new event to all active AIs.
Definition: ai_core.cpp:258
bool ambient
Play ambient, industry and town sounds.
Tindex index
Index of this pool item.
Definition: pool_type.hpp:147
the east corner of the tile is raised
Definition: slope_type.h:54
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.
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:59
const IndustryTileTable *const * table
List of the tiles composing the industry.
Definition: industrytype.h:102
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:69
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:33
uint32 population
Current population of people.
Definition: town.h:47
Year _cur_year
Current year, starting at 0.
Definition: date.cpp:26
uint16 incoming_cargo_waiting[3]
incoming cargo waiting to be processed
Definition: industry.h:44
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:159
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:126
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:57
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:390
Owner owner[4]
Name of the owner(s)
Definition: tile_cmd.h:55
StringID name
Displayed name of the industry.
Definition: industrytype.h:122
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.
can only be built in towns (arctic/tropic banks, water tower)
Definition: industrytype.h:68
north and east corner are raised
Definition: slope_type.h:60
static uint ClampU(const uint a, const uint min, const uint max)
Clamp an unsigned integer between an interval.
Definition: math_func.hpp:184
Do not force one instance of this type to appear on map generation.
Definition: industrytype.h:81
not really a tile, but rather a very special check
Definition: industry_map.h:56
static bool IsIndustryCompleted(TileIndex t)
Is this industry tile fully built?
Definition: industry_map.h:77
static uint GetTreeGrowth(TileIndex t)
Returns the tree growth status.
Definition: tree_map.h:181
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:23
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition: tile_map.cpp:182
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:64
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:186
Data for managing the number and type of industries in the game.
Definition: industry.h:170
int16 y
The y value of the coordinate.
Definition: map_type.h:60
decides allowance of autosloping
Slope GetTileSlope(TileIndex tile, int *h)
Return the slope of a given tile inside the map.
Definition: tile_map.cpp:115
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:154
Slope slopes_refused
slope pattern on which this tile cannot be built
Definition: industrytype.h:151
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:131
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:3239
Aircraft vehicle type.
Definition: vehicle_type.h:27
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 give tiletype.
Definition: tile_map.h:143
static void MakeField(TileIndex t, uint field_type, IndustryID industry)
Make a (farm) field tile.
Definition: clear_map.h:281
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:436
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:71
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
uint16 produced_cargo_waiting[2]
amount of cargo produced per cargo
Definition: industry.h:43
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.
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:58
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:340
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.
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.
uint16 this_month_production[2]
stats of this month&#39;s production per cargo
Definition: industry.h:48
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:59
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:55
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:123
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
CargoID accepts_cargo[3]
3 input cargo slots
Definition: industry.h:47
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:152
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:40
static int WhoCanServiceIndustry(Industry *ind)
Compute who can service the industry.
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
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:882
don&#39;t allow building on water
Definition: command_type.h:345
Defines the data structure for constructing industry.
Definition: industrytype.h:101
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:129
Smoke at copper mine.
The tile has no ownership.
Definition: company_type.h:27
Northwest.
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:164
CargoID produced_cargo[2]
2 production cargo slots
Definition: industry.h:42
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.
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.
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:25
Invalid cargo type.
Definition: cargo_type.h:70
IndustryBehaviour behaviour
How this industry will behave, and how others entities can use it.
Definition: industrytype.h:120
byte prod_level
general production level
Definition: industry.h:46
byte appear_ingame[NUM_LANDSCAPE]
Probability of appearance in game.
Definition: industrytype.h:128
GRFFileProps grf_prop
properties related to the grf file
Definition: industrytype.h:136
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:515
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:155
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.
byte last_month_pct_transported[2]
percentage transported per cargo in the last full month
Definition: industry.h:50
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:688
uint16 last_month_transported[2]
total units transported per cargo in the last full month
Definition: industry.h:52
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:107
Base class for all pools.
Definition: pool_type.hpp:83
Ship vehicle type.
Definition: vehicle_type.h:26
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.
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:160
bool IsTileForestIndustry(TileIndex tile)
Check whether the tile is a forest.
TileIndex tile
The base tile of the area.
Definition: tilearea_type.h:19
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset)
Mark a tile given by its index dirty for repaint.
Definition: viewport.cpp:1904
uint16 _tick_counter
Ever incrementing (and sometimes wrapping) tick counter for setting off various events.
Definition: date.cpp:30
uint64 dparam[2]
Parameters of the str string.
Definition: tile_cmd.h:64
static uint ScaleByMapSize1D(uint n)
Scales the given value by the maps circumference, where the given value is for a 256 by 256 map...
Definition: map_func.h:138
EffectVehicle * CreateEffectVehicle(int x, int y, int z, EffectVehicleType type)
Create an effect vehicle at a particular location.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don&#39;t get linker errors.
Definition: pool_func.hpp:224
static uint16 GetIndustryGamePlayProbability(IndustryType it, byte *min_number)
Compute the probability for constructing a new industry during game play.
void DeleteWindowById(WindowClass cls, WindowNumber number, bool force)
Delete a window by its class and window number (if it is open).
Definition: window.cpp:1137
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:103
execute the given command
Definition: command_type.h:342
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.
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:74
bool _generating_world
Whether we are generating the map or not.
Definition: genworld.cpp:61
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:115
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:129
Production changes of industry serviced by local company.
Definition: news_type.h:44
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:215
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:161
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:582
void RecomputeProductionMultipliers()
Recompute production_rate for current prod_level.
static TreeGround GetTreeGround(TileIndex t)
Returns the groundtype for tree tiles.
Definition: tree_map.h:89
north and west corner are raised
Definition: slope_type.h:57
static const IndustryType NUM_INDUSTRYTYPES
total number of industry types, new and old; limited to 240 because we need some special ids like INV...
Definition: industry_type.h:28
Source/destination is an industry.
Definition: cargo_type.h:140
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:124
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:153
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
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
static void DecIndustryTypeCount(IndustryType type)
Decrement the count of industries for this type.
Definition: industry.h:118
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:380
byte production_rate[2]
production rate for each cargo
Definition: industry.h:45
Base functions for all Games.
static uint32 GetScaledIndustryGenerationProbability(IndustryType it, bool *force_at_least_one)
Compute the appearance probability for an industry during map creation.
Functions related to commands.
IndustryBehaviour
Various industry behaviours mostly to represent original TTD specialities.
Definition: industrytype.h:62
uint32 probability
Relative probability of building this industry.
Definition: industry.h:156
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:142
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:604
IndustryType conflicting[3]
Industries this industry cannot be close to.
Definition: industrytype.h:107
byte GetSnowLine()
Get the current snow line, either variable or static.
Definition: landscape.cpp:564
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:172
Fields are planted around when built (all farms)
Definition: industrytype.h:70
Smoke of power plant (industry).
Allow closing down the last instance of this type.
Definition: industrytype.h:82
ConstructionSettings construction
construction of things in-game
CargoID accepts_cargo[3]
3 accepted cargoes.
Definition: industrytype.h:116
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:843
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:130
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:157
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:125
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:986
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:108
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:83
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:148
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:94
Very few industries at game start.
Definition: settings_type.h:46
uint16 target_count
Desired number of industries of this type.
Definition: industry.h:158
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:347
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:45
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.
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:56
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:36
Functions related to news.
The tile of the industry has been triggered during the tileloop.
Like forests.
Definition: industrytype.h:32
Structure contains cached list of stations nearby.
Definition: station_type.h:104
void FindStationsAroundTiles(const TileArea &location, StationList *stations)
Find all stations around a rectangular producer (industry, house, headquarter, ...)
industries
Definition: transparency.h:28
Base classes/functions for stations.
call production callback every 256 ticks
Called when industry is built to set initial production level.
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
static Station * Get(size_t index)
Gets station with given index.
Date _date
Current date in days (day counter)
Definition: date.cpp:28
static T Delta(const T a, const T b)
Returns the (absolute) difference between two (scalar) variables.
Definition: math_func.hpp:232
uint16 h
The height of the area.
Definition: tilearea_type.h:21
static void MakeIndustry(TileIndex t, IndustryID index, IndustryGfx gfx, uint8 random, WaterClass wc)
Make the given tile an industry tile.
Definition: industry_map.h:280
static const int INDUSTRY_PRODUCE_TICKS
cycle duration for industry production
Definition: date_type.h:38
can only be built before 1950 (oil wells)
Definition: industrytype.h:72
the south corner of the tile is raised
Definition: slope_type.h:53
static const IndustryGfx INDUSTRYTILE_NOANIM
flag to mark industry tiles as having no animation
Definition: industry_type.h:33
The tile/execution is done by "water".
Definition: company_type.h:28
static bool TransportIndustryGoods(TileIndex tile)
Move produced cargo from industry to nearby stations.
void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index)
Delete inspect window for a given feature and index.
static void UpdateIndustryStatistics(Industry *i)
Monthly update of industry statistics.
VehicleTypeByte type
Type of vehicle.
Definition: vehicle_type.h:54
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:3220
byte HighestSnowLine()
Get the highest possible snow line height, either variable or static.
Definition: landscape.cpp:578
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:158
give a custom colour to newly build industries
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:299
Train vehicle type.
Definition: vehicle_type.h:24
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