OpenTTD
landscape.cpp
Go to the documentation of this file.
1 /* $Id: landscape.cpp 27009 2014-10-13 14:22:48Z rubidium $ */
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 
14 #include "stdafx.h"
15 #include "heightmap.h"
16 #include "clear_map.h"
17 #include "spritecache.h"
18 #include "viewport_func.h"
19 #include "command_func.h"
20 #include "landscape.h"
21 #include "void_map.h"
22 #include "tgp.h"
23 #include "genworld.h"
24 #include "fios.h"
25 #include "date_func.h"
26 #include "water.h"
27 #include "effectvehicle_func.h"
28 #include "landscape_type.h"
29 #include "animated_tile_func.h"
30 #include "core/random_func.hpp"
31 #include "object_base.h"
32 #include "company_func.h"
33 #include "pathfinder/npf/aystar.h"
34 #include <list>
35 #include <set>
36 
37 #include "table/strings.h"
38 #include "table/sprites.h"
39 
40 #include "safeguards.h"
41 
42 extern const TileTypeProcs
43  _tile_type_clear_procs,
44  _tile_type_rail_procs,
45  _tile_type_road_procs,
46  _tile_type_town_procs,
47  _tile_type_trees_procs,
48  _tile_type_station_procs,
49  _tile_type_water_procs,
50  _tile_type_void_procs,
51  _tile_type_industry_procs,
52  _tile_type_tunnelbridge_procs,
53  _tile_type_object_procs;
54 
60 const TileTypeProcs * const _tile_type_procs[16] = {
61  &_tile_type_clear_procs,
62  &_tile_type_rail_procs,
63  &_tile_type_road_procs,
64  &_tile_type_town_procs,
65  &_tile_type_trees_procs,
66  &_tile_type_station_procs,
67  &_tile_type_water_procs,
68  &_tile_type_void_procs,
69  &_tile_type_industry_procs,
70  &_tile_type_tunnelbridge_procs,
71  &_tile_type_object_procs,
72 };
73 
75 extern const byte _slope_to_sprite_offset[32] = {
76  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0,
77  0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 17, 0, 15, 18, 0,
78 };
79 
88 static SnowLine *_snow_line = NULL;
89 
99 {
100  if (!IsFoundation(f)) return 0;
101 
102  if (IsLeveledFoundation(f)) {
103  uint dz = 1 + (IsSteepSlope(*s) ? 1 : 0);
104  *s = SLOPE_FLAT;
105  return dz;
106  }
107 
110  return 0;
111  }
112 
113  if (IsSpecialRailFoundation(f)) {
115  return 0;
116  }
117 
118  uint dz = IsSteepSlope(*s) ? 1 : 0;
119  Corner highest_corner = GetHighestSlopeCorner(*s);
120 
121  switch (f) {
123  *s = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? SLOPE_SW : SLOPE_NE);
124  break;
125 
127  *s = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? SLOPE_SE : SLOPE_NW);
128  break;
129 
131  *s = SlopeWithOneCornerRaised(highest_corner);
132  break;
133 
135  *s = HalftileSlope(SlopeWithOneCornerRaised(highest_corner), highest_corner);
136  break;
137 
138  default: NOT_REACHED();
139  }
140  return dz;
141 }
142 
143 
151 uint GetPartialPixelZ(int x, int y, Slope corners)
152 {
153  if (IsHalftileSlope(corners)) {
154  switch (GetHalftileSlopeCorner(corners)) {
155  case CORNER_W:
156  if (x - y >= 0) return GetSlopeMaxPixelZ(corners);
157  break;
158 
159  case CORNER_S:
160  if (x - (y ^ 0xF) >= 0) return GetSlopeMaxPixelZ(corners);
161  break;
162 
163  case CORNER_E:
164  if (y - x >= 0) return GetSlopeMaxPixelZ(corners);
165  break;
166 
167  case CORNER_N:
168  if ((y ^ 0xF) - x >= 0) return GetSlopeMaxPixelZ(corners);
169  break;
170 
171  default: NOT_REACHED();
172  }
173  }
174 
175  int z = 0;
176 
177  switch (RemoveHalftileSlope(corners)) {
178  case SLOPE_W:
179  if (x - y >= 0) {
180  z = (x - y) >> 1;
181  }
182  break;
183 
184  case SLOPE_S:
185  y ^= 0xF;
186  if ((x - y) >= 0) {
187  z = (x - y) >> 1;
188  }
189  break;
190 
191  case SLOPE_SW:
192  z = (x >> 1) + 1;
193  break;
194 
195  case SLOPE_E:
196  if (y - x >= 0) {
197  z = (y - x) >> 1;
198  }
199  break;
200 
201  case SLOPE_EW:
202  case SLOPE_NS:
203  case SLOPE_ELEVATED:
204  z = 4;
205  break;
206 
207  case SLOPE_SE:
208  z = (y >> 1) + 1;
209  break;
210 
211  case SLOPE_WSE:
212  z = 8;
213  y ^= 0xF;
214  if (x - y < 0) {
215  z += (x - y) >> 1;
216  }
217  break;
218 
219  case SLOPE_N:
220  y ^= 0xF;
221  if (y - x >= 0) {
222  z = (y - x) >> 1;
223  }
224  break;
225 
226  case SLOPE_NW:
227  z = (y ^ 0xF) >> 1;
228  break;
229 
230  case SLOPE_NWS:
231  z = 8;
232  if (x - y < 0) {
233  z += (x - y) >> 1;
234  }
235  break;
236 
237  case SLOPE_NE:
238  z = (x ^ 0xF) >> 1;
239  break;
240 
241  case SLOPE_ENW:
242  z = 8;
243  y ^= 0xF;
244  if (y - x < 0) {
245  z += (y - x) >> 1;
246  }
247  break;
248 
249  case SLOPE_SEN:
250  z = 8;
251  if (y - x < 0) {
252  z += (y - x) >> 1;
253  }
254  break;
255 
256  case SLOPE_STEEP_S:
257  z = 1 + ((x + y) >> 1);
258  break;
259 
260  case SLOPE_STEEP_W:
261  z = 1 + ((x + (y ^ 0xF)) >> 1);
262  break;
263 
264  case SLOPE_STEEP_N:
265  z = 1 + (((x ^ 0xF) + (y ^ 0xF)) >> 1);
266  break;
267 
268  case SLOPE_STEEP_E:
269  z = 1 + (((x ^ 0xF) + y) >> 1);
270  break;
271 
272  default: break;
273  }
274 
275  return z;
276 }
277 
278 int GetSlopePixelZ(int x, int y)
279 {
280  TileIndex tile = TileVirtXY(x, y);
281 
282  return _tile_type_procs[GetTileType(tile)]->get_slope_z_proc(tile, x, y);
283 }
284 
294 int GetSlopeZInCorner(Slope tileh, Corner corner)
295 {
296  assert(!IsHalftileSlope(tileh));
297  return ((tileh & SlopeWithOneCornerRaised(corner)) != 0 ? 1 : 0) + (tileh == SteepSlope(corner) ? 1 : 0);
298 }
299 
312 void GetSlopePixelZOnEdge(Slope tileh, DiagDirection edge, int *z1, int *z2)
313 {
314  static const Slope corners[4][4] = {
315  /* corner | steep slope
316  * z1 z2 | z1 z2 */
317  {SLOPE_E, SLOPE_N, SLOPE_STEEP_E, SLOPE_STEEP_N}, // DIAGDIR_NE, z1 = E, z2 = N
318  {SLOPE_S, SLOPE_E, SLOPE_STEEP_S, SLOPE_STEEP_E}, // DIAGDIR_SE, z1 = S, z2 = E
319  {SLOPE_S, SLOPE_W, SLOPE_STEEP_S, SLOPE_STEEP_W}, // DIAGDIR_SW, z1 = S, z2 = W
320  {SLOPE_W, SLOPE_N, SLOPE_STEEP_W, SLOPE_STEEP_N}, // DIAGDIR_NW, z1 = W, z2 = N
321  };
322 
323  int halftile_test = (IsHalftileSlope(tileh) ? SlopeWithOneCornerRaised(GetHalftileSlopeCorner(tileh)) : 0);
324  if (halftile_test == corners[edge][0]) *z2 += TILE_HEIGHT; // The slope is non-continuous in z2. z2 is on the upper side.
325  if (halftile_test == corners[edge][1]) *z1 += TILE_HEIGHT; // The slope is non-continuous in z1. z1 is on the upper side.
326 
327  if ((tileh & corners[edge][0]) != 0) *z1 += TILE_HEIGHT; // z1 is raised
328  if ((tileh & corners[edge][1]) != 0) *z2 += TILE_HEIGHT; // z2 is raised
329  if (RemoveHalftileSlope(tileh) == corners[edge][2]) *z1 += TILE_HEIGHT; // z1 is highest corner of a steep slope
330  if (RemoveHalftileSlope(tileh) == corners[edge][3]) *z2 += TILE_HEIGHT; // z2 is highest corner of a steep slope
331 }
332 
342 {
343  Slope tileh = GetTileSlope(tile, z);
344  Foundation f = _tile_type_procs[GetTileType(tile)]->get_foundation_proc(tile, tileh);
345  uint z_inc = ApplyFoundationToSlope(f, &tileh);
346  if (z != NULL) *z += z_inc;
347  return tileh;
348 }
349 
350 
351 bool HasFoundationNW(TileIndex tile, Slope slope_here, uint z_here)
352 {
353  int z;
354 
355  int z_W_here = z_here;
356  int z_N_here = z_here;
357  GetSlopePixelZOnEdge(slope_here, DIAGDIR_NW, &z_W_here, &z_N_here);
358 
359  Slope slope = GetFoundationPixelSlope(TILE_ADDXY(tile, 0, -1), &z);
360  int z_W = z;
361  int z_N = z;
362  GetSlopePixelZOnEdge(slope, DIAGDIR_SE, &z_W, &z_N);
363 
364  return (z_N_here > z_N) || (z_W_here > z_W);
365 }
366 
367 
368 bool HasFoundationNE(TileIndex tile, Slope slope_here, uint z_here)
369 {
370  int z;
371 
372  int z_E_here = z_here;
373  int z_N_here = z_here;
374  GetSlopePixelZOnEdge(slope_here, DIAGDIR_NE, &z_E_here, &z_N_here);
375 
376  Slope slope = GetFoundationPixelSlope(TILE_ADDXY(tile, -1, 0), &z);
377  int z_E = z;
378  int z_N = z;
379  GetSlopePixelZOnEdge(slope, DIAGDIR_SW, &z_E, &z_N);
380 
381  return (z_N_here > z_N) || (z_E_here > z_E);
382 }
383 
390 {
391  if (!IsFoundation(f)) return;
392 
393  /* Two part foundations must be drawn separately */
394  assert(f != FOUNDATION_STEEP_BOTH);
395 
396  uint sprite_block = 0;
397  int z;
398  Slope slope = GetFoundationPixelSlope(ti->tile, &z);
399 
400  /* Select the needed block of foundations sprites
401  * Block 0: Walls at NW and NE edge
402  * Block 1: Wall at NE edge
403  * Block 2: Wall at NW edge
404  * Block 3: No walls at NW or NE edge
405  */
406  if (!HasFoundationNW(ti->tile, slope, z)) sprite_block += 1;
407  if (!HasFoundationNE(ti->tile, slope, z)) sprite_block += 2;
408 
409  /* Use the original slope sprites if NW and NE borders should be visible */
410  SpriteID leveled_base = (sprite_block == 0 ? (int)SPR_FOUNDATION_BASE : (SPR_SLOPES_VIRTUAL_BASE + sprite_block * SPR_TRKFOUND_BLOCK_SIZE));
411  SpriteID inclined_base = SPR_SLOPES_VIRTUAL_BASE + SPR_SLOPES_INCLINED_OFFSET + sprite_block * SPR_TRKFOUND_BLOCK_SIZE;
412  SpriteID halftile_base = SPR_HALFTILE_FOUNDATION_BASE + sprite_block * SPR_HALFTILE_BLOCK_SIZE;
413 
414  if (IsSteepSlope(ti->tileh)) {
415  if (!IsNonContinuousFoundation(f)) {
416  /* Lower part of foundation */
418  leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z
419  );
420  }
421 
422  Corner highest_corner = GetHighestSlopeCorner(ti->tileh);
423  ti->z += ApplyPixelFoundationToSlope(f, &ti->tileh);
424 
425  if (IsInclinedFoundation(f)) {
426  /* inclined foundation */
427  byte inclined = highest_corner * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
428 
429  AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y,
430  f == FOUNDATION_INCLINED_X ? 16 : 1,
431  f == FOUNDATION_INCLINED_Y ? 16 : 1,
432  TILE_HEIGHT, ti->z
433  );
434  OffsetGroundSprite(31, 9);
435  } else if (IsLeveledFoundation(f)) {
436  AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z - TILE_HEIGHT);
437  OffsetGroundSprite(31, 1);
438  } else if (f == FOUNDATION_STEEP_LOWER) {
439  /* one corner raised */
440  OffsetGroundSprite(31, 1);
441  } else {
442  /* halftile foundation */
443  int x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? 8 : 0);
444  int y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? 8 : 0);
445 
446  AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z + TILE_HEIGHT);
447  OffsetGroundSprite(31, 9);
448  }
449  } else {
450  if (IsLeveledFoundation(f)) {
451  /* leveled foundation */
452  AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
453  OffsetGroundSprite(31, 1);
454  } else if (IsNonContinuousFoundation(f)) {
455  /* halftile foundation */
456  Corner halftile_corner = GetHalftileFoundationCorner(f);
457  int x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? 8 : 0);
458  int y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? 8 : 0);
459 
460  AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z);
461  OffsetGroundSprite(31, 9);
462  } else if (IsSpecialRailFoundation(f)) {
463  /* anti-zig-zag foundation */
464  SpriteID spr;
465  if (ti->tileh == SLOPE_NS || ti->tileh == SLOPE_EW) {
466  /* half of leveled foundation under track corner */
467  spr = leveled_base + SlopeWithThreeCornersRaised(GetRailFoundationCorner(f));
468  } else {
469  /* tile-slope = sloped along X/Y, foundation-slope = three corners raised */
470  spr = inclined_base + 2 * GetRailFoundationCorner(f) + ((ti->tileh == SLOPE_SW || ti->tileh == SLOPE_NE) ? 1 : 0);
471  }
472  AddSortableSpriteToDraw(spr, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
473  OffsetGroundSprite(31, 9);
474  } else {
475  /* inclined foundation */
476  byte inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
477 
478  AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y,
479  f == FOUNDATION_INCLINED_X ? 16 : 1,
480  f == FOUNDATION_INCLINED_Y ? 16 : 1,
481  TILE_HEIGHT, ti->z
482  );
483  OffsetGroundSprite(31, 9);
484  }
485  ti->z += ApplyPixelFoundationToSlope(f, &ti->tileh);
486  }
487 }
488 
489 void DoClearSquare(TileIndex tile)
490 {
491  /* If the tile can have animation and we clear it, delete it from the animated tile list. */
492  if (_tile_type_procs[GetTileType(tile)]->animate_tile_proc != NULL) DeleteAnimatedTile(tile);
493 
494  MakeClear(tile, CLEAR_GRASS, _generating_world ? 3 : 0);
495  MarkTileDirtyByTile(tile);
496 }
497 
508 TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
509 {
510  return _tile_type_procs[GetTileType(tile)]->get_tile_track_status_proc(tile, mode, sub_mode, side);
511 }
512 
519 void ChangeTileOwner(TileIndex tile, Owner old_owner, Owner new_owner)
520 {
521  _tile_type_procs[GetTileType(tile)]->change_tile_owner_proc(tile, old_owner, new_owner);
522 }
523 
524 void GetTileDesc(TileIndex tile, TileDesc *td)
525 {
526  _tile_type_procs[GetTileType(tile)]->get_tile_desc_proc(tile, td);
527 }
528 
535 {
536  return _snow_line != NULL;
537 }
538 
545 {
546  _snow_line = CallocT<SnowLine>(1);
547  _snow_line->lowest_value = 0xFF;
548  memcpy(_snow_line->table, table, sizeof(_snow_line->table));
549 
550  for (uint i = 0; i < SNOW_LINE_MONTHS; i++) {
551  for (uint j = 0; j < SNOW_LINE_DAYS; j++) {
552  _snow_line->highest_value = max(_snow_line->highest_value, table[i][j]);
553  _snow_line->lowest_value = min(_snow_line->lowest_value, table[i][j]);
554  }
555  }
556 }
557 
564 {
565  if (_snow_line == NULL) return _settings_game.game_creation.snow_line_height;
566 
567  YearMonthDay ymd;
568  ConvertDateToYMD(_date, &ymd);
569  return _snow_line->table[ymd.month][ymd.day];
570 }
571 
578 {
579  return _snow_line == NULL ? _settings_game.game_creation.snow_line_height : _snow_line->highest_value;
580 }
581 
588 {
589  return _snow_line == NULL ? _settings_game.game_creation.snow_line_height : _snow_line->lowest_value;
590 }
591 
597 {
598  free(_snow_line);
599  _snow_line = NULL;
600 }
601 
611 CommandCost CmdLandscapeClear(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
612 {
614  bool do_clear = false;
615  /* Test for stuff which results in water when cleared. Then add the cost to also clear the water. */
616  if ((flags & DC_FORCE_CLEAR_TILE) && HasTileWaterClass(tile) && IsTileOnWater(tile) && !IsWaterTile(tile) && !IsCoastTile(tile)) {
617  if ((flags & DC_AUTO) && GetWaterClass(tile) == WATER_CLASS_CANAL) return_cmd_error(STR_ERROR_MUST_DEMOLISH_CANAL_FIRST);
618  do_clear = true;
619  cost.AddCost(GetWaterClass(tile) == WATER_CLASS_CANAL ? _price[PR_CLEAR_CANAL] : _price[PR_CLEAR_WATER]);
620  }
621 
622  Company *c = (flags & (DC_AUTO | DC_BANKRUPT)) ? NULL : Company::GetIfValid(_current_company);
623  if (c != NULL && (int)GB(c->clear_limit, 16, 16) < 1) {
624  return_cmd_error(STR_ERROR_CLEARING_LIMIT_REACHED);
625  }
626 
627  const ClearedObjectArea *coa = FindClearedObject(tile);
628 
629  /* If this tile was the first tile which caused object destruction, always
630  * pass it on to the tile_type_proc. That way multiple test runs and the exec run stay consistent. */
631  if (coa != NULL && coa->first_tile != tile) {
632  /* If this tile belongs to an object which was already cleared via another tile, pretend it has been
633  * already removed.
634  * However, we need to check stuff, which is not the same for all object tiles. (e.g. being on water or not) */
635 
636  /* If a object is removed, it leaves either bare land or water. */
637  if ((flags & DC_NO_WATER) && HasTileWaterClass(tile) && IsTileOnWater(tile)) {
638  return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
639  }
640  } else {
641  cost.AddCost(_tile_type_procs[GetTileType(tile)]->clear_tile_proc(tile, flags));
642  }
643 
644  if (flags & DC_EXEC) {
645  if (c != NULL) c->clear_limit -= 1 << 16;
646  if (do_clear) DoClearSquare(tile);
647  }
648  return cost;
649 }
650 
661 CommandCost CmdClearArea(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
662 {
663  if (p1 >= MapSize()) return CMD_ERROR;
664 
667  CommandCost last_error = CMD_ERROR;
668  bool had_success = false;
669 
670  const Company *c = (flags & (DC_AUTO | DC_BANKRUPT)) ? NULL : Company::GetIfValid(_current_company);
671  int limit = (c == NULL ? INT32_MAX : GB(c->clear_limit, 16, 16));
672 
673  TileIterator *iter = HasBit(p2, 0) ? (TileIterator *)new DiagonalTileIterator(tile, p1) : new OrthogonalTileIterator(tile, p1);
674  for (; *iter != INVALID_TILE; ++(*iter)) {
675  TileIndex t = *iter;
676  CommandCost ret = DoCommand(t, 0, 0, flags & ~DC_EXEC, CMD_LANDSCAPE_CLEAR);
677  if (ret.Failed()) {
678  last_error = ret;
679 
680  /* We may not clear more tiles. */
681  if (c != NULL && GB(c->clear_limit, 16, 16) < 1) break;
682  continue;
683  }
684 
685  had_success = true;
686  if (flags & DC_EXEC) {
687  money -= ret.GetCost();
688  if (ret.GetCost() > 0 && money < 0) {
689  _additional_cash_required = ret.GetCost();
690  delete iter;
691  return cost;
692  }
693  DoCommand(t, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
694 
695  /* draw explosion animation...
696  * Disable explosions when game is paused. Looks silly and blocks the view. */
697  if ((t == tile || t == p1) && _pause_mode == PM_UNPAUSED) {
698  /* big explosion in two corners, or small explosion for single tiles */
700  TileX(tile) == TileX(p1) && TileY(tile) == TileY(p1) ? EV_EXPLOSION_SMALL : EV_EXPLOSION_LARGE
701  );
702  }
703  } else {
704  /* When we're at the clearing limit we better bail (unneed) testing as well. */
705  if (ret.GetCost() != 0 && --limit <= 0) break;
706  }
707  cost.AddCost(ret);
708  }
709 
710  delete iter;
711  return had_success ? cost : last_error;
712 }
713 
714 
715 TileIndex _cur_tileloop_tile;
716 
721 {
722  /* The pseudorandom sequence of tiles is generated using a Galois linear feedback
723  * shift register (LFSR). This allows a deterministic pseudorandom ordering, but
724  * still with minimal state and fast iteration. */
725 
726  /* Maximal length LFSR feedback terms, from 12-bit (for 64x64 maps) to 24-bit (for 4096x4096 maps).
727  * Extracted from http://www.ece.cmu.edu/~koopman/lfsr/ */
728  static const uint32 feedbacks[] = {
729  0xD8F, 0x1296, 0x2496, 0x4357, 0x8679, 0x1030E, 0x206CD, 0x403FE, 0x807B8, 0x1004B2, 0x2006A8, 0x4004B2, 0x800B87
730  };
731  assert_compile(lengthof(feedbacks) == 2 * MAX_MAP_SIZE_BITS - 2 * MIN_MAP_SIZE_BITS + 1);
732  const uint32 feedback = feedbacks[MapLogX() + MapLogY() - 2 * MIN_MAP_SIZE_BITS];
733 
734  /* We update every tile every 256 ticks, so divide the map size by 2^8 = 256 */
735  uint count = 1 << (MapLogX() + MapLogY() - 8);
736 
737  TileIndex tile = _cur_tileloop_tile;
738  /* The LFSR cannot have a zeroed state. */
739  assert(tile != 0);
740 
741  /* Manually update tile 0 every 256 ticks - the LFSR never iterates over it itself. */
742  if (_tick_counter % 256 == 0) {
743  _tile_type_procs[GetTileType(0)]->tile_loop_proc(0);
744  count--;
745  }
746 
747  while (count--) {
748  _tile_type_procs[GetTileType(tile)]->tile_loop_proc(tile);
749 
750  /* Get the next tile in sequence using a Galois LFSR. */
751  tile = (tile >> 1) ^ (-(int32)(tile & 1) & feedback);
752  }
753 
754  _cur_tileloop_tile = tile;
755 }
756 
757 void InitializeLandscape()
758 {
759  uint maxx = MapMaxX();
760  uint maxy = MapMaxY();
761  uint sizex = MapSizeX();
762 
763  uint y;
764  for (y = _settings_game.construction.freeform_edges ? 1 : 0; y < maxy; y++) {
765  uint x;
766  for (x = _settings_game.construction.freeform_edges ? 1 : 0; x < maxx; x++) {
767  MakeClear(sizex * y + x, CLEAR_GRASS, 3);
768  SetTileHeight(sizex * y + x, 0);
769  SetTropicZone(sizex * y + x, TROPICZONE_NORMAL);
770  ClearBridgeMiddle(sizex * y + x);
771  }
772  MakeVoid(sizex * y + x);
773  }
774  for (uint x = 0; x < sizex; x++) MakeVoid(sizex * y + x);
775 }
776 
777 static const byte _genterrain_tbl_1[5] = { 10, 22, 33, 37, 4 };
778 static const byte _genterrain_tbl_2[5] = { 0, 0, 0, 0, 33 };
779 
780 static void GenerateTerrain(int type, uint flag)
781 {
782  uint32 r = Random();
783 
784  const Sprite *templ = GetSprite((((r >> 24) * _genterrain_tbl_1[type]) >> 8) + _genterrain_tbl_2[type] + 4845, ST_MAPGEN);
785  if (templ == NULL) usererror("Map generator sprites could not be loaded");
786 
787  uint x = r & MapMaxX();
788  uint y = (r >> MapLogX()) & MapMaxY();
789 
790  if (x < 2 || y < 2) return;
791 
792  DiagDirection direction = (DiagDirection)GB(r, 22, 2);
793  uint w = templ->width;
794  uint h = templ->height;
795 
796  if (DiagDirToAxis(direction) == AXIS_Y) Swap(w, h);
797 
798  const byte *p = templ->data;
799 
800  if ((flag & 4) != 0) {
801  uint xw = x * MapSizeY();
802  uint yw = y * MapSizeX();
803  uint bias = (MapSizeX() + MapSizeY()) * 16;
804 
805  switch (flag & 3) {
806  default: NOT_REACHED();
807  case 0:
808  if (xw + yw > MapSize() - bias) return;
809  break;
810 
811  case 1:
812  if (yw < xw + bias) return;
813  break;
814 
815  case 2:
816  if (xw + yw < MapSize() + bias) return;
817  break;
818 
819  case 3:
820  if (xw < yw + bias) return;
821  break;
822  }
823  }
824 
825  if (x + w >= MapMaxX() - 1) return;
826  if (y + h >= MapMaxY() - 1) return;
827 
828  TileIndex tile = TileXY(x, y);
829 
830  switch (direction) {
831  default: NOT_REACHED();
832  case DIAGDIR_NE:
833  do {
834  TileIndex tile_cur = tile;
835 
836  for (uint w_cur = w; w_cur != 0; --w_cur) {
837  if (GB(*p, 0, 4) >= TileHeight(tile_cur)) SetTileHeight(tile_cur, GB(*p, 0, 4));
838  p++;
839  tile_cur++;
840  }
841  tile += TileDiffXY(0, 1);
842  } while (--h != 0);
843  break;
844 
845  case DIAGDIR_SE:
846  do {
847  TileIndex tile_cur = tile;
848 
849  for (uint h_cur = h; h_cur != 0; --h_cur) {
850  if (GB(*p, 0, 4) >= TileHeight(tile_cur)) SetTileHeight(tile_cur, GB(*p, 0, 4));
851  p++;
852  tile_cur += TileDiffXY(0, 1);
853  }
854  tile += TileDiffXY(1, 0);
855  } while (--w != 0);
856  break;
857 
858  case DIAGDIR_SW:
859  tile += TileDiffXY(w - 1, 0);
860  do {
861  TileIndex tile_cur = tile;
862 
863  for (uint w_cur = w; w_cur != 0; --w_cur) {
864  if (GB(*p, 0, 4) >= TileHeight(tile_cur)) SetTileHeight(tile_cur, GB(*p, 0, 4));
865  p++;
866  tile_cur--;
867  }
868  tile += TileDiffXY(0, 1);
869  } while (--h != 0);
870  break;
871 
872  case DIAGDIR_NW:
873  tile += TileDiffXY(0, h - 1);
874  do {
875  TileIndex tile_cur = tile;
876 
877  for (uint h_cur = h; h_cur != 0; --h_cur) {
878  if (GB(*p, 0, 4) >= TileHeight(tile_cur)) SetTileHeight(tile_cur, GB(*p, 0, 4));
879  p++;
880  tile_cur -= TileDiffXY(0, 1);
881  }
882  tile += TileDiffXY(1, 0);
883  } while (--w != 0);
884  break;
885  }
886 }
887 
888 
889 #include "table/genland.h"
890 
891 static void CreateDesertOrRainForest()
892 {
893  TileIndex update_freq = MapSize() / 4;
894  const TileIndexDiffC *data;
895  uint max_desert_height = CeilDiv(_settings_game.construction.max_heightlevel, 4);
896 
897  for (TileIndex tile = 0; tile != MapSize(); ++tile) {
898  if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
899 
900  if (!IsValidTile(tile)) continue;
901 
902  for (data = _make_desert_or_rainforest_data;
903  data != endof(_make_desert_or_rainforest_data); ++data) {
904  TileIndex t = AddTileIndexDiffCWrap(tile, *data);
905  if (t != INVALID_TILE && (TileHeight(t) >= max_desert_height || IsTileType(t, MP_WATER))) break;
906  }
907  if (data == endof(_make_desert_or_rainforest_data)) {
909  }
910  }
911 
912  for (uint i = 0; i != 256; i++) {
914 
915  RunTileLoop();
916  }
917 
918  for (TileIndex tile = 0; tile != MapSize(); ++tile) {
919  if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
920 
921  if (!IsValidTile(tile)) continue;
922 
923  for (data = _make_desert_or_rainforest_data;
924  data != endof(_make_desert_or_rainforest_data); ++data) {
925  TileIndex t = AddTileIndexDiffCWrap(tile, *data);
926  if (t != INVALID_TILE && IsTileType(t, MP_CLEAR) && IsClearGround(t, CLEAR_DESERT)) break;
927  }
928  if (data == endof(_make_desert_or_rainforest_data)) {
930  }
931  }
932 }
933 
940 static bool FindSpring(TileIndex tile, void *user_data)
941 {
942  int referenceHeight;
943  if (!IsTileFlat(tile, &referenceHeight) || IsWaterTile(tile)) return false;
944 
945  /* In the tropics rivers start in the rainforest. */
946  if (_settings_game.game_creation.landscape == LT_TROPIC && GetTropicZone(tile) != TROPICZONE_RAINFOREST) return false;
947 
948  /* Are there enough higher tiles to warrant a 'spring'? */
949  uint num = 0;
950  for (int dx = -1; dx <= 1; dx++) {
951  for (int dy = -1; dy <= 1; dy++) {
952  TileIndex t = TileAddWrap(tile, dx, dy);
953  if (t != INVALID_TILE && GetTileMaxZ(t) > referenceHeight) num++;
954  }
955  }
956 
957  if (num < 4) return false;
958 
959  /* Are we near the top of a hill? */
960  for (int dx = -16; dx <= 16; dx++) {
961  for (int dy = -16; dy <= 16; dy++) {
962  TileIndex t = TileAddWrap(tile, dx, dy);
963  if (t != INVALID_TILE && GetTileMaxZ(t) > referenceHeight + 2) return false;
964  }
965  }
966 
967  return true;
968 }
969 
976 static bool MakeLake(TileIndex tile, void *user_data)
977 {
978  uint height = *(uint*)user_data;
979  if (!IsValidTile(tile) || TileHeight(tile) != height || !IsTileFlat(tile)) return false;
980  if (_settings_game.game_creation.landscape == LT_TROPIC && GetTropicZone(tile) == TROPICZONE_DESERT) return false;
981 
982  for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
983  TileIndex t2 = tile + TileOffsByDiagDir(d);
984  if (IsWaterTile(t2)) {
985  MakeRiver(tile, Random());
986  return false;
987  }
988  }
989 
990  return false;
991 }
992 
999 static bool FlowsDown(TileIndex begin, TileIndex end)
1000 {
1001  assert(DistanceManhattan(begin, end) == 1);
1002 
1003  int heightBegin;
1004  int heightEnd;
1005  Slope slopeBegin = GetTileSlope(begin, &heightBegin);
1006  Slope slopeEnd = GetTileSlope(end, &heightEnd);
1007 
1008  return heightEnd <= heightBegin &&
1009  /* Slope either is inclined or flat; rivers don't support other slopes. */
1010  (slopeEnd == SLOPE_FLAT || IsInclinedSlope(slopeEnd)) &&
1011  /* Slope continues, then it must be lower... or either end must be flat. */
1012  ((slopeEnd == slopeBegin && heightEnd < heightBegin) || slopeEnd == SLOPE_FLAT || slopeBegin == SLOPE_FLAT);
1013 }
1014 
1015 /* AyStar callback for checking whether we reached our destination. */
1016 static int32 River_EndNodeCheck(AyStar *aystar, OpenListNode *current)
1017 {
1018  return current->path.node.tile == *(TileIndex*)aystar->user_target ? AYSTAR_FOUND_END_NODE : AYSTAR_DONE;
1019 }
1020 
1021 /* AyStar callback for getting the cost of the current node. */
1022 static int32 River_CalculateG(AyStar *aystar, AyStarNode *current, OpenListNode *parent)
1023 {
1025 }
1026 
1027 /* AyStar callback for getting the estimated cost to the destination. */
1028 static int32 River_CalculateH(AyStar *aystar, AyStarNode *current, OpenListNode *parent)
1029 {
1030  return DistanceManhattan(*(TileIndex*)aystar->user_target, current->tile);
1031 }
1032 
1033 /* AyStar callback for getting the neighbouring nodes of the given node. */
1034 static void River_GetNeighbours(AyStar *aystar, OpenListNode *current)
1035 {
1036  TileIndex tile = current->path.node.tile;
1037 
1038  aystar->num_neighbours = 0;
1039  for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
1040  TileIndex t2 = tile + TileOffsByDiagDir(d);
1041  if (IsValidTile(t2) && FlowsDown(tile, t2)) {
1042  aystar->neighbours[aystar->num_neighbours].tile = t2;
1043  aystar->neighbours[aystar->num_neighbours].direction = INVALID_TRACKDIR;
1044  aystar->num_neighbours++;
1045  }
1046  }
1047 }
1048 
1049 /* AyStar callback when an route has been found. */
1050 static void River_FoundEndNode(AyStar *aystar, OpenListNode *current)
1051 {
1052  for (PathNode *path = &current->path; path != NULL; path = path->parent) {
1053  TileIndex tile = path->node.tile;
1054  if (!IsWaterTile(tile)) {
1055  MakeRiver(tile, Random());
1056  /* Remove desert directly around the river tile. */
1057  CircularTileSearch(&tile, 5, RiverModifyDesertZone, NULL);
1058  }
1059  }
1060 }
1061 
1062 static const uint RIVER_HASH_SIZE = 8;
1063 
1070 static uint River_Hash(uint tile, uint dir)
1071 {
1072  return GB(TileHash(TileX(tile), TileY(tile)), 0, RIVER_HASH_SIZE);
1073 }
1074 
1080 static void BuildRiver(TileIndex begin, TileIndex end)
1081 {
1082  AyStar finder;
1083  MemSetT(&finder, 0);
1084  finder.CalculateG = River_CalculateG;
1085  finder.CalculateH = River_CalculateH;
1086  finder.GetNeighbours = River_GetNeighbours;
1087  finder.EndNodeCheck = River_EndNodeCheck;
1088  finder.FoundEndNode = River_FoundEndNode;
1089  finder.user_target = &end;
1090 
1091  finder.Init(River_Hash, 1 << RIVER_HASH_SIZE);
1092 
1093  AyStarNode start;
1094  start.tile = begin;
1095  start.direction = INVALID_TRACKDIR;
1096  finder.AddStartNode(&start, 0);
1097  finder.Main();
1098  finder.Free();
1099 }
1100 
1107 static bool FlowRiver(TileIndex spring, TileIndex begin)
1108 {
1109  #define SET_MARK(x) marks.insert(x)
1110  #define IS_MARKED(x) (marks.find(x) != marks.end())
1111 
1112  uint height = TileHeight(begin);
1113  if (IsWaterTile(begin)) return DistanceManhattan(spring, begin) > _settings_game.game_creation.min_river_length;
1114 
1115  std::set<TileIndex> marks;
1116  SET_MARK(begin);
1117 
1118  /* Breadth first search for the closest tile we can flow down to. */
1119  std::list<TileIndex> queue;
1120  queue.push_back(begin);
1121 
1122  bool found = false;
1123  uint count = 0; // Number of tiles considered; to be used for lake location guessing.
1124  TileIndex end;
1125  do {
1126  end = queue.front();
1127  queue.pop_front();
1128 
1129  uint height2 = TileHeight(end);
1130  if (IsTileFlat(end) && (height2 < height || (height2 == height && IsWaterTile(end)))) {
1131  found = true;
1132  break;
1133  }
1134 
1135  for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
1136  TileIndex t2 = end + TileOffsByDiagDir(d);
1137  if (IsValidTile(t2) && !IS_MARKED(t2) && FlowsDown(end, t2)) {
1138  SET_MARK(t2);
1139  count++;
1140  queue.push_back(t2);
1141  }
1142  }
1143  } while (!queue.empty());
1144 
1145  if (found) {
1146  /* Flow further down hill. */
1147  found = FlowRiver(spring, end);
1148  } else if (count > 32) {
1149  /* Maybe we can make a lake. Find the Nth of the considered tiles. */
1150  TileIndex lakeCenter = 0;
1151  int i = RandomRange(count - 1) + 1;
1152  std::set<TileIndex>::const_iterator cit = marks.begin();
1153  while (--i) cit++;
1154  lakeCenter = *cit;
1155 
1156  if (IsValidTile(lakeCenter) &&
1157  /* A river, or lake, can only be built on flat slopes. */
1158  IsTileFlat(lakeCenter) &&
1159  /* We want the lake to be built at the height of the river. */
1160  TileHeight(begin) == TileHeight(lakeCenter) &&
1161  /* We don't want the lake at the entry of the valley. */
1162  lakeCenter != begin &&
1163  /* We don't want lakes in the desert. */
1164  (_settings_game.game_creation.landscape != LT_TROPIC || GetTropicZone(lakeCenter) != TROPICZONE_DESERT) &&
1165  /* We only want a lake if the river is long enough. */
1167  end = lakeCenter;
1168  MakeRiver(lakeCenter, Random());
1169  uint range = RandomRange(8) + 3;
1170  CircularTileSearch(&lakeCenter, range, MakeLake, &height);
1171  /* Call the search a second time so artefacts from going circular in one direction get (mostly) hidden. */
1172  lakeCenter = end;
1173  CircularTileSearch(&lakeCenter, range, MakeLake, &height);
1174  found = true;
1175  }
1176  }
1177 
1178  marks.clear();
1179  if (found) BuildRiver(begin, end);
1180  return found;
1181 }
1182 
1186 static void CreateRivers()
1187 {
1189  if (amount == 0) return;
1190 
1192  SetGeneratingWorldProgress(GWP_RIVER, wells + 256 / 64); // Include the tile loop calls below.
1193 
1194  for (; wells != 0; wells--) {
1196  for (int tries = 0; tries < 128; tries++) {
1197  TileIndex t = RandomTile();
1198  if (!CircularTileSearch(&t, 8, FindSpring, NULL)) continue;
1199  if (FlowRiver(t, t)) break;
1200  }
1201  }
1202 
1203  /* Run tile loop to update the ground density. */
1204  for (uint i = 0; i != 256; i++) {
1205  if (i % 64 == 0) IncreaseGeneratingWorldProgress(GWP_RIVER);
1206  RunTileLoop();
1207  }
1208 }
1209 
1210 void GenerateLandscape(byte mode)
1211 {
1213  enum GenLandscapeSteps {
1214  GLS_HEIGHTMAP = 3,
1215  GLS_TERRAGENESIS = 5,
1216  GLS_ORIGINAL = 2,
1217  GLS_TROPIC = 12,
1218  GLS_OTHER = 0,
1219  };
1220  uint steps = (_settings_game.game_creation.landscape == LT_TROPIC) ? GLS_TROPIC : GLS_OTHER;
1221 
1222  if (mode == GWM_HEIGHTMAP) {
1223  SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_HEIGHTMAP);
1224  LoadHeightmap(_file_to_saveload.name);
1227  SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_TERRAGENESIS);
1229  } else {
1230  SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_ORIGINAL);
1232  for (uint x = 0; x < MapSizeX(); x++) MakeVoid(TileXY(x, 0));
1233  for (uint y = 0; y < MapSizeY(); y++) MakeVoid(TileXY(0, y));
1234  }
1236  case LT_ARCTIC: {
1237  uint32 r = Random();
1238 
1239  for (uint i = ScaleByMapSize(GB(r, 0, 7) + 950); i != 0; --i) {
1240  GenerateTerrain(2, 0);
1241  }
1242 
1243  uint flag = GB(r, 7, 2) | 4;
1244  for (uint i = ScaleByMapSize(GB(r, 9, 7) + 450); i != 0; --i) {
1245  GenerateTerrain(4, flag);
1246  }
1247  break;
1248  }
1249 
1250  case LT_TROPIC: {
1251  uint32 r = Random();
1252 
1253  for (uint i = ScaleByMapSize(GB(r, 0, 7) + 170); i != 0; --i) {
1254  GenerateTerrain(0, 0);
1255  }
1256 
1257  uint flag = GB(r, 7, 2) | 4;
1258  for (uint i = ScaleByMapSize(GB(r, 9, 8) + 1700); i != 0; --i) {
1259  GenerateTerrain(0, flag);
1260  }
1261 
1262  flag ^= 2;
1263 
1264  for (uint i = ScaleByMapSize(GB(r, 17, 7) + 410); i != 0; --i) {
1265  GenerateTerrain(3, flag);
1266  }
1267  break;
1268  }
1269 
1270  default: {
1271  uint32 r = Random();
1272 
1274  uint i = ScaleByMapSize(GB(r, 0, 7) + (3 - _settings_game.difficulty.quantity_sea_lakes) * 256 + 100);
1275  for (; i != 0; --i) {
1276  /* Make sure we do not overflow. */
1277  GenerateTerrain(Clamp(_settings_game.difficulty.terrain_type, 0, 3), 0);
1278  }
1279  break;
1280  }
1281  }
1282  }
1283 
1284  /* Do not call IncreaseGeneratingWorldProgress() before FixSlopes(),
1285  * it allows screen redraw. Drawing of broken slopes crashes the game */
1286  FixSlopes();
1288  ConvertGroundTilesIntoWaterTiles();
1290 
1291  if (_settings_game.game_creation.landscape == LT_TROPIC) CreateDesertOrRainForest();
1292 
1293  CreateRivers();
1294 }
1295 
1296 void OnTick_Town();
1297 void OnTick_Trees();
1298 void OnTick_Station();
1299 void OnTick_Industry();
1300 
1301 void OnTick_Companies();
1302 void OnTick_LinkGraph();
1303 
1304 void CallLandscapeTick()
1305 {
1306  OnTick_Town();
1307  OnTick_Trees();
1308  OnTick_Station();
1309  OnTick_Industry();
1310 
1311  OnTick_Companies();
1312  OnTick_LinkGraph();
1313 }