OpenTTD Source: src/landscape.cpp Source File

OpenTTD Source 15.0-RC2

landscape.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
12#include "stdafx.h"
13#include "heightmap.h"
14#include "clear_map.h"
15#include "spritecache.h"
16#include "viewport_func.h"
17#include "command_func.h"
18#include "landscape.h"
19#include "void_map.h"
20#include "tgp.h"
21#include "genworld.h"
22#include "fios.h"
23#include "error_func.h"
24#include "timer/timer_game_calendar.h"
25#include "timer/timer_game_tick.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 "tree_cmd.h"
33#include "company_func.h"
34#include "company_gui.h"
35#include "saveload/saveload.h"
36#include "framerate_type.h"
37#include "landscape_cmd.h"
38#include "terraform_cmd.h"
39#include "station_func.h"
40#include "pathfinder/water_regions.h"
41#include "pathfinder/yapf/yapf_river_builder.h"
42
43#include "table/strings.h"
44#include "table/sprites.h"
45
46#include <unordered_set>
47
48#include "safeguards.h"
49
50extern const TileTypeProcs
51 _tile_type_clear_procs,
52 _tile_type_rail_procs,
53 _tile_type_road_procs,
54 _tile_type_town_procs,
55 _tile_type_trees_procs,
56 _tile_type_station_procs,
57 _tile_type_water_procs,
58 _tile_type_void_procs,
59 _tile_type_industry_procs,
60 _tile_type_tunnelbridge_procs,
61 _tile_type_object_procs;
62
68 const TileTypeProcs * const _tile_type_procs[16] = {
69 &_tile_type_clear_procs,
70 &_tile_type_rail_procs,
71 &_tile_type_road_procs,
72 &_tile_type_town_procs,
73 &_tile_type_trees_procs,
74 &_tile_type_station_procs,
75 &_tile_type_water_procs,
76 &_tile_type_void_procs,
77 &_tile_type_industry_procs,
78 &_tile_type_tunnelbridge_procs,
79 &_tile_type_object_procs,
80};
81
83extern const uint8_t _slope_to_sprite_offset[32] = {
84 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0,
85 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 17, 0, 15, 18, 0,
86};
87
88 static const uint TILE_UPDATE_FREQUENCY_LOG = 8;
89 static const uint TILE_UPDATE_FREQUENCY = 1 << TILE_UPDATE_FREQUENCY_LOG;
90
99 static std::unique_ptr<SnowLine> _snow_line;
100
114 Point InverseRemapCoords2(int x, int y, bool clamp_to_map, bool *clamped)
115{
116 if (clamped != nullptr) *clamped = false; // Not clamping yet.
117
118 /* Initial x/y world coordinate is like if the landscape
119 * was completely flat on height 0. */
120 Point pt = InverseRemapCoords(x, y);
121
122 const uint min_coord = _settings_game.construction.freeform_edges ? TILE_SIZE : 0;
123 const uint max_x = Map::MaxX() * TILE_SIZE - 1;
124 const uint max_y = Map::MaxY() * TILE_SIZE - 1;
125
126 if (clamp_to_map) {
127 /* Bring the coordinates near to a valid range. At the top we allow a number
128 * of extra tiles. This is mostly due to the tiles on the north side of
129 * the map possibly being drawn higher due to the extra height levels. */
130 int extra_tiles = CeilDiv(_settings_game.construction.map_height_limit * TILE_HEIGHT, TILE_PIXELS);
131 Point old_pt = pt;
132 pt.x = Clamp(pt.x, -extra_tiles * TILE_SIZE, max_x);
133 pt.y = Clamp(pt.y, -extra_tiles * TILE_SIZE, max_y);
134 if (clamped != nullptr) *clamped = (pt.x != old_pt.x) || (pt.y != old_pt.y);
135 }
136
137 /* Now find the Z-world coordinate by fix point iteration.
138 * This is a bit tricky because the tile height is non-continuous at foundations.
139 * The clicked point should be approached from the back, otherwise there are regions that are not clickable.
140 * (FOUNDATION_HALFTILE_LOWER on SLOPE_STEEP_S hides north halftile completely)
141 * So give it a z-malus of 4 in the first iterations. */
142 int z = 0;
143 if (clamp_to_map) {
144 for (int i = 0; i < 5; i++) z = GetSlopePixelZ(Clamp(pt.x + std::max(z, 4) - 4, min_coord, max_x), Clamp(pt.y + std::max(z, 4) - 4, min_coord, max_y)) / 2;
145 for (int m = 3; m > 0; m--) z = GetSlopePixelZ(Clamp(pt.x + std::max(z, m) - m, min_coord, max_x), Clamp(pt.y + std::max(z, m) - m, min_coord, max_y)) / 2;
146 for (int i = 0; i < 5; i++) z = GetSlopePixelZ(Clamp(pt.x + z, min_coord, max_x), Clamp(pt.y + z, min_coord, max_y)) / 2;
147 } else {
148 for (int i = 0; i < 5; i++) z = GetSlopePixelZOutsideMap(pt.x + std::max(z, 4) - 4, pt.y + std::max(z, 4) - 4) / 2;
149 for (int m = 3; m > 0; m--) z = GetSlopePixelZOutsideMap(pt.x + std::max(z, m) - m, pt.y + std::max(z, m) - m) / 2;
150 for (int i = 0; i < 5; i++) z = GetSlopePixelZOutsideMap(pt.x + z, pt.y + z ) / 2;
151 }
152
153 pt.x += z;
154 pt.y += z;
155 if (clamp_to_map) {
156 Point old_pt = pt;
157 pt.x = Clamp(pt.x, min_coord, max_x);
158 pt.y = Clamp(pt.y, min_coord, max_y);
159 if (clamped != nullptr) *clamped = *clamped || (pt.x != old_pt.x) || (pt.y != old_pt.y);
160 }
161
162 return pt;
163}
164
173uint ApplyFoundationToSlope(Foundation f, Slope &s)
174{
175 if (!IsFoundation(f)) return 0;
176
177 if (IsLeveledFoundation(f)) {
178 uint dz = 1 + (IsSteepSlope(s) ? 1 : 0);
179 s = SLOPE_FLAT;
180 return dz;
181 }
182
183 if (f != FOUNDATION_STEEP_BOTH && IsNonContinuousFoundation(f)) {
184 s = HalftileSlope(s, GetHalftileFoundationCorner(f));
185 return 0;
186 }
187
188 if (IsSpecialRailFoundation(f)) {
189 s = SlopeWithThreeCornersRaised(OppositeCorner(GetRailFoundationCorner(f)));
190 return 0;
191 }
192
193 uint dz = IsSteepSlope(s) ? 1 : 0;
194 Corner highest_corner = GetHighestSlopeCorner(s);
195
196 switch (f) {
197 case FOUNDATION_INCLINED_X:
198 s = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? SLOPE_SW : SLOPE_NE);
199 break;
200
201 case FOUNDATION_INCLINED_Y:
202 s = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? SLOPE_SE : SLOPE_NW);
203 break;
204
205 case FOUNDATION_STEEP_LOWER:
206 s = SlopeWithOneCornerRaised(highest_corner);
207 break;
208
209 case FOUNDATION_STEEP_BOTH:
210 s = HalftileSlope(SlopeWithOneCornerRaised(highest_corner), highest_corner);
211 break;
212
213 default: NOT_REACHED();
214 }
215 return dz;
216}
217
218
231uint GetPartialPixelZ(int x, int y, Slope corners)
232{
233 if (IsHalftileSlope(corners)) {
234 /* A foundation is placed on half the tile at a specific corner. This means that,
235 * depending on the corner, that one half of the tile is at the maximum height. */
236 switch (GetHalftileSlopeCorner(corners)) {
237 case CORNER_W:
238 if (x > y) return GetSlopeMaxPixelZ(corners);
239 break;
240
241 case CORNER_S:
242 if (x + y >= (int)TILE_SIZE) return GetSlopeMaxPixelZ(corners);
243 break;
244
245 case CORNER_E:
246 if (x <= y) return GetSlopeMaxPixelZ(corners);
247 break;
248
249 case CORNER_N:
250 if (x + y < (int)TILE_SIZE) return GetSlopeMaxPixelZ(corners);
251 break;
252
253 default: NOT_REACHED();
254 }
255 }
256
257 switch (RemoveHalftileSlope(corners)) {
258 case SLOPE_FLAT: return 0;
259
260 /* One corner is up.*/
261 case SLOPE_N: return x + y <= (int)TILE_SIZE ? (TILE_SIZE - x - y) >> 1 : 0;
262 case SLOPE_E: return y >= x ? (1 + y - x) >> 1 : 0;
263 case SLOPE_S: return x + y >= (int)TILE_SIZE ? (1 + x + y - TILE_SIZE) >> 1 : 0;
264 case SLOPE_W: return x >= y ? (x - y) >> 1 : 0;
265
266 /* Two corners next to each other are up. */
267 case SLOPE_NE: return (TILE_SIZE - x) >> 1;
268 case SLOPE_SE: return (y + 1) >> 1;
269 case SLOPE_SW: return (x + 1) >> 1;
270 case SLOPE_NW: return (TILE_SIZE - y) >> 1;
271
272 /* Three corners are up on the same level. */
273 case SLOPE_ENW: return x + y >= (int)TILE_SIZE ? TILE_HEIGHT - ((1 + x + y - TILE_SIZE) >> 1) : TILE_HEIGHT;
274 case SLOPE_SEN: return y < x ? TILE_HEIGHT - ((x - y) >> 1) : TILE_HEIGHT;
275 case SLOPE_WSE: return x + y <= (int)TILE_SIZE ? TILE_HEIGHT - ((TILE_SIZE - x - y) >> 1) : TILE_HEIGHT;
276 case SLOPE_NWS: return x < y ? TILE_HEIGHT - ((1 + y - x) >> 1) : TILE_HEIGHT;
277
278 /* Two corners at opposite sides are up. */
279 case SLOPE_NS: return x + y < (int)TILE_SIZE ? (TILE_SIZE - x - y) >> 1 : (1 + x + y - TILE_SIZE) >> 1;
280 case SLOPE_EW: return x >= y ? (x - y) >> 1 : (1 + y - x) >> 1;
281
282 /* Very special cases. */
283 case SLOPE_ELEVATED: return TILE_HEIGHT;
284
285 /* Steep slopes. The top is at 2 * TILE_HEIGHT. */
286 case SLOPE_STEEP_N: return (TILE_SIZE - x + TILE_SIZE - y) >> 1;
287 case SLOPE_STEEP_E: return (TILE_SIZE + 1 + y - x) >> 1;
288 case SLOPE_STEEP_S: return (1 + x + y) >> 1;
289 case SLOPE_STEEP_W: return (TILE_SIZE + x - y) >> 1;
290
291 default: NOT_REACHED();
292 }
293}
294
306 int GetSlopePixelZ(int x, int y, bool ground_vehicle)
307{
308 TileIndex tile = TileVirtXY(x, y);
309
310 return _tile_type_procs[GetTileType(tile)]->get_slope_z_proc(tile, x, y, ground_vehicle);
311}
312
321 int GetSlopePixelZOutsideMap(int x, int y)
322{
323 if (IsInsideBS(x, 0, Map::SizeX() * TILE_SIZE) && IsInsideBS(y, 0, Map::SizeY() * TILE_SIZE)) {
324 return GetSlopePixelZ(x, y, false);
325 } else {
326 return _tile_type_procs[MP_VOID]->get_slope_z_proc(INVALID_TILE, x, y, false);
327 }
328}
329
339 int GetSlopeZInCorner(Slope tileh, Corner corner)
340{
341 assert(!IsHalftileSlope(tileh));
342 return ((tileh & SlopeWithOneCornerRaised(corner)) != 0 ? 1 : 0) + (tileh == SteepSlope(corner) ? 1 : 0);
343}
344
357 void GetSlopePixelZOnEdge(Slope tileh, DiagDirection edge, int &z1, int &z2)
358{
359 static const Slope corners[4][4] = {
360 /* corner | steep slope
361 * z1 z2 | z1 z2 */
362 {SLOPE_E, SLOPE_N, SLOPE_STEEP_E, SLOPE_STEEP_N}, // DIAGDIR_NE, z1 = E, z2 = N
363 {SLOPE_S, SLOPE_E, SLOPE_STEEP_S, SLOPE_STEEP_E}, // DIAGDIR_SE, z1 = S, z2 = E
364 {SLOPE_S, SLOPE_W, SLOPE_STEEP_S, SLOPE_STEEP_W}, // DIAGDIR_SW, z1 = S, z2 = W
365 {SLOPE_W, SLOPE_N, SLOPE_STEEP_W, SLOPE_STEEP_N}, // DIAGDIR_NW, z1 = W, z2 = N
366 };
367
368 int halftile_test = (IsHalftileSlope(tileh) ? SlopeWithOneCornerRaised(GetHalftileSlopeCorner(tileh)) : 0);
369 if (halftile_test == corners[edge][0]) z2 += TILE_HEIGHT; // The slope is non-continuous in z2. z2 is on the upper side.
370 if (halftile_test == corners[edge][1]) z1 += TILE_HEIGHT; // The slope is non-continuous in z1. z1 is on the upper side.
371
372 if ((tileh & corners[edge][0]) != 0) z1 += TILE_HEIGHT; // z1 is raised
373 if ((tileh & corners[edge][1]) != 0) z2 += TILE_HEIGHT; // z2 is raised
374 if (RemoveHalftileSlope(tileh) == corners[edge][2]) z1 += TILE_HEIGHT; // z1 is highest corner of a steep slope
375 if (RemoveHalftileSlope(tileh) == corners[edge][3]) z2 += TILE_HEIGHT; // z2 is highest corner of a steep slope
376}
377
385std::tuple<Slope, int> GetFoundationSlope(TileIndex tile)
386{
387 auto [tileh, z] = GetTileSlopeZ(tile);
388 Foundation f = _tile_type_procs[GetTileType(tile)]->get_foundation_proc(tile, tileh);
389 z += ApplyFoundationToSlope(f, tileh);
390 return {tileh, z};
391}
392
393
394bool HasFoundationNW(TileIndex tile, Slope slope_here, uint z_here)
395{
396 int z_W_here = z_here;
397 int z_N_here = z_here;
398 GetSlopePixelZOnEdge(slope_here, DIAGDIR_NW, z_W_here, z_N_here);
399
400 auto [slope, z] = GetFoundationPixelSlope(TileAddXY(tile, 0, -1));
401 int z_W = z;
402 int z_N = z;
403 GetSlopePixelZOnEdge(slope, DIAGDIR_SE, z_W, z_N);
404
405 return (z_N_here > z_N) || (z_W_here > z_W);
406}
407
408
409bool HasFoundationNE(TileIndex tile, Slope slope_here, uint z_here)
410{
411 int z_E_here = z_here;
412 int z_N_here = z_here;
413 GetSlopePixelZOnEdge(slope_here, DIAGDIR_NE, z_E_here, z_N_here);
414
415 auto [slope, z] = GetFoundationPixelSlope(TileAddXY(tile, -1, 0));
416 int z_E = z;
417 int z_N = z;
418 GetSlopePixelZOnEdge(slope, DIAGDIR_SW, z_E, z_N);
419
420 return (z_N_here > z_N) || (z_E_here > z_E);
421}
422
428 void DrawFoundation(TileInfo *ti, Foundation f)
429{
430 if (!IsFoundation(f)) return;
431
432 /* Two part foundations must be drawn separately */
433 assert(f != FOUNDATION_STEEP_BOTH);
434
435 uint sprite_block = 0;
436 auto [slope, z] = GetFoundationPixelSlope(ti->tile);
437
438 /* Select the needed block of foundations sprites
439 * Block 0: Walls at NW and NE edge
440 * Block 1: Wall at NE edge
441 * Block 2: Wall at NW edge
442 * Block 3: No walls at NW or NE edge
443 */
444 if (!HasFoundationNW(ti->tile, slope, z)) sprite_block += 1;
445 if (!HasFoundationNE(ti->tile, slope, z)) sprite_block += 2;
446
447 /* Use the original slope sprites if NW and NE borders should be visible */
448 SpriteID leveled_base = (sprite_block == 0 ? (int)SPR_FOUNDATION_BASE : (SPR_SLOPES_VIRTUAL_BASE + sprite_block * TRKFOUND_BLOCK_SIZE));
449 SpriteID inclined_base = SPR_SLOPES_VIRTUAL_BASE + SLOPES_INCLINED_OFFSET + sprite_block * TRKFOUND_BLOCK_SIZE;
450 SpriteID halftile_base = SPR_HALFTILE_FOUNDATION_BASE + sprite_block * HALFTILE_BLOCK_SIZE;
451
452 if (IsSteepSlope(ti->tileh)) {
453 if (!IsNonContinuousFoundation(f)) {
454 /* Lower part of foundation */
455 static constexpr SpriteBounds bounds{{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1}, {}};
456 AddSortableSpriteToDraw(leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, *ti, bounds);
457 }
458
459 Corner highest_corner = GetHighestSlopeCorner(ti->tileh);
460 ti->z += ApplyPixelFoundationToSlope(f, ti->tileh);
461
462 if (IsInclinedFoundation(f)) {
463 /* inclined foundation */
464 uint8_t inclined = highest_corner * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
465
466 SpriteBounds bounds{{}, {1, 1, TILE_HEIGHT}, {}};
467 if (f == FOUNDATION_INCLINED_X) bounds.extent.x = TILE_SIZE;
468 if (f == FOUNDATION_INCLINED_Y) bounds.extent.y = TILE_SIZE;
469 AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, *ti, bounds);
470 OffsetGroundSprite(0, 0);
471 } else if (IsLeveledFoundation(f)) {
472 static constexpr SpriteBounds bounds{{0, 0, -(int)TILE_HEIGHT}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1}, {}};
473 AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, *ti, bounds);
474 OffsetGroundSprite(0, -(int)TILE_HEIGHT);
475 } else if (f == FOUNDATION_STEEP_LOWER) {
476 /* one corner raised */
477 OffsetGroundSprite(0, -(int)TILE_HEIGHT);
478 } else {
479 /* halftile foundation */
480 int8_t x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? TILE_SIZE / 2 : 0);
481 int8_t y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? TILE_SIZE / 2 : 0);
482
483 SpriteBounds bounds{{x_bb, y_bb, TILE_HEIGHT}, {TILE_SIZE / 2, TILE_SIZE / 2, TILE_HEIGHT - 1}, {}};
484 AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, *ti, bounds);
485 /* Reposition ground sprite back to original position after bounding box change above. This is similar to
486 * RemapCoords() but without zoom scaling. */
487 Point pt = {(y_bb - x_bb) * 2, y_bb + x_bb};
488 OffsetGroundSprite(-pt.x, -pt.y);
489 }
490 } else {
491 if (IsLeveledFoundation(f)) {
492 /* leveled foundation */
493 static constexpr SpriteBounds bounds{{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1}, {}};
494 AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, *ti, bounds);
495 OffsetGroundSprite(0, -(int)TILE_HEIGHT);
496 } else if (IsNonContinuousFoundation(f)) {
497 /* halftile foundation */
498 Corner halftile_corner = GetHalftileFoundationCorner(f);
499 int8_t x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? TILE_SIZE / 2 : 0);
500 int8_t y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? TILE_SIZE / 2 : 0);
501
502 SpriteBounds bounds{{x_bb, y_bb, 0}, {TILE_SIZE / 2, TILE_SIZE / 2, TILE_HEIGHT - 1}, {}};
503 AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, *ti, bounds);
504 /* Reposition ground sprite back to original position after bounding box change above. This is similar to
505 * RemapCoords() but without zoom scaling. */
506 Point pt = {(y_bb - x_bb) * 2, y_bb + x_bb};
507 OffsetGroundSprite(-pt.x, -pt.y);
508 } else if (IsSpecialRailFoundation(f)) {
509 /* anti-zig-zag foundation */
510 SpriteID spr;
511 if (ti->tileh == SLOPE_NS || ti->tileh == SLOPE_EW) {
512 /* half of leveled foundation under track corner */
513 spr = leveled_base + SlopeWithThreeCornersRaised(GetRailFoundationCorner(f));
514 } else {
515 /* tile-slope = sloped along X/Y, foundation-slope = three corners raised */
516 spr = inclined_base + 2 * GetRailFoundationCorner(f) + ((ti->tileh == SLOPE_SW || ti->tileh == SLOPE_NE) ? 1 : 0);
517 }
518 static constexpr SpriteBounds bounds{{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1}, {}};
519 AddSortableSpriteToDraw(spr, PAL_NONE, *ti, bounds);
520 OffsetGroundSprite(0, 0);
521 } else {
522 /* inclined foundation */
523 uint8_t inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
524
525 SpriteBounds bounds{{}, {1, 1, TILE_HEIGHT}, {}};
526 if (f == FOUNDATION_INCLINED_X) bounds.extent.x = TILE_SIZE;
527 if (f == FOUNDATION_INCLINED_Y) bounds.extent.y = TILE_SIZE;
528 AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, *ti, bounds);
529 OffsetGroundSprite(0, 0);
530 }
531 ti->z += ApplyPixelFoundationToSlope(f, ti->tileh);
532 }
533}
534
535void DoClearSquare(TileIndex tile)
536{
537 /* If the tile can have animation and we clear it, delete it from the animated tile list. */
538 if (MayAnimateTile(tile)) DeleteAnimatedTile(tile, true);
539
540 bool remove = IsDockingTile(tile);
541 MakeClear(tile, CLEAR_GRASS, _generating_world ? 3 : 0);
542 MarkTileDirtyByTile(tile);
543 if (remove) RemoveDockingTile(tile);
544
545 ClearNeighbourNonFloodingStates(tile);
546 InvalidateWaterRegion(tile);
547}
548
559TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
560{
561 return _tile_type_procs[GetTileType(tile)]->get_tile_track_status_proc(tile, mode, sub_mode, side);
562}
563
570 void ChangeTileOwner(TileIndex tile, Owner old_owner, Owner new_owner)
571{
572 _tile_type_procs[GetTileType(tile)]->change_tile_owner_proc(tile, old_owner, new_owner);
573}
574
575void GetTileDesc(TileIndex tile, TileDesc &td)
576{
577 _tile_type_procs[GetTileType(tile)]->get_tile_desc_proc(tile, td);
578}
579
585 bool IsSnowLineSet()
586{
587 return _snow_line != nullptr;
588}
589
595 void SetSnowLine(std::unique_ptr<SnowLine> &&snow_line)
596{
597 _snow_line = std::move(snow_line);
598}
599
605uint8_t GetSnowLine()
606{
607 if (_snow_line == nullptr) return _settings_game.game_creation.snow_line_height;
608
609 TimerGameCalendar::YearMonthDay ymd = TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date);
610 return _snow_line->table[ymd.month][ymd.day];
611}
612
618uint8_t HighestSnowLine()
619{
620 return _snow_line == nullptr ? _settings_game.game_creation.snow_line_height : _snow_line->highest_value;
621}
622
628uint8_t LowestSnowLine()
629{
630 return _snow_line == nullptr ? _settings_game.game_creation.snow_line_height : _snow_line->lowest_value;
631}
632
637 void ClearSnowLine()
638{
639 _snow_line = nullptr;
640}
641
646 bool IsMapSurroundedByWater()
647{
648 auto check_tile = [](uint x, uint y) -> bool {
649 auto [slope, h] = GetTilePixelSlopeOutsideMap(x, y);
650 return ((slope == SLOPE_FLAT) && (h == 0));
651 };
652
653 /* Check the map corners. */
654 if (!check_tile(0, 0)) return false;
655 if (!check_tile(0, Map::SizeY())) return false;
656 if (!check_tile(Map::SizeX(), 0)) return false;
657 if (!check_tile(Map::SizeX(), Map::SizeY())) return false;
658
659 /* Check the map edges.*/
660 for (uint x = 0; x <= Map::SizeX(); x++) {
661 if (!check_tile(x, 0)) return false;
662 if (!check_tile(x, Map::SizeY())) return false;
663 }
664 for (uint y = 1; y < Map::SizeY(); y++) {
665 if (!check_tile(0, y)) return false;
666 if (!check_tile(Map::SizeX(), y)) return false;
667 }
668
669 return true;
670}
671
678 CommandCost CmdLandscapeClear(DoCommandFlags flags, TileIndex tile)
679{
680 CommandCost cost(EXPENSES_CONSTRUCTION);
681 bool do_clear = false;
682 /* Test for stuff which results in water when cleared. Then add the cost to also clear the water. */
683 if (flags.Test(DoCommandFlag::ForceClearTile) && HasTileWaterClass(tile) && IsTileOnWater(tile) && !IsWaterTile(tile) && !IsCoastTile(tile)) {
684 if (flags.Test(DoCommandFlag::Auto) && GetWaterClass(tile) == WaterClass::Canal) return CommandCost(STR_ERROR_MUST_DEMOLISH_CANAL_FIRST);
685 do_clear = true;
686 cost.AddCost(GetWaterClass(tile) == WaterClass::Canal ? _price[PR_CLEAR_CANAL] : _price[PR_CLEAR_WATER]);
687 }
688
689 Company *c = flags.Any({DoCommandFlag::Auto, DoCommandFlag::Bankrupt}) ? nullptr : Company::GetIfValid(_current_company);
690 if (c != nullptr && (int)GB(c->clear_limit, 16, 16) < 1) {
691 return CommandCost(STR_ERROR_CLEARING_LIMIT_REACHED);
692 }
693
694 const ClearedObjectArea *coa = FindClearedObject(tile);
695
696 /* If this tile was the first tile which caused object destruction, always
697 * pass it on to the tile_type_proc. That way multiple test runs and the exec run stay consistent. */
698 if (coa != nullptr && coa->first_tile != tile) {
699 /* If this tile belongs to an object which was already cleared via another tile, pretend it has been
700 * already removed.
701 * However, we need to check stuff, which is not the same for all object tiles. (e.g. being on water or not) */
702
703 /* If a object is removed, it leaves either bare land or water. */
704 if (flags.Test(DoCommandFlag::NoWater) && HasTileWaterClass(tile) && IsTileOnWater(tile)) {
705 return CommandCost(STR_ERROR_CAN_T_BUILD_ON_WATER);
706 }
707 } else {
708 cost.AddCost(_tile_type_procs[GetTileType(tile)]->clear_tile_proc(tile, flags));
709 }
710
711 if (flags.Test(DoCommandFlag::Execute)) {
712 if (c != nullptr) c->clear_limit -= 1 << 16;
713 if (do_clear) {
714 if (IsWaterTile(tile) && IsCanal(tile)) {
715 Owner owner = GetTileOwner(tile);
716 if (Company::IsValidID(owner)) {
717 Company::Get(owner)->infrastructure.water--;
718 DirtyCompanyInfrastructureWindows(owner);
719 }
720 }
721 DoClearSquare(tile);
722 ClearNeighbourNonFloodingStates(tile);
723 }
724 }
725 return cost;
726}
727
736std::tuple<CommandCost, Money> CmdClearArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, bool diagonal)
737{
738 if (start_tile >= Map::Size()) return { CMD_ERROR, 0 };
739
740 Money money = GetAvailableMoneyForCommand();
741 CommandCost cost(EXPENSES_CONSTRUCTION);
742 CommandCost last_error = CMD_ERROR;
743 bool had_success = false;
744
745 const Company *c = flags.Any({DoCommandFlag::Auto, DoCommandFlag::Bankrupt}) ? nullptr : Company::GetIfValid(_current_company);
746 int limit = (c == nullptr ? INT32_MAX : GB(c->clear_limit, 16, 16));
747
748 if (tile != start_tile) flags.Set(DoCommandFlag::ForceClearTile);
749
750 std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
751 for (; *iter != INVALID_TILE; ++(*iter)) {
752 TileIndex t = *iter;
753 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(DoCommandFlags{flags}.Reset(DoCommandFlag::Execute), t);
754 if (ret.Failed()) {
755 last_error = std::move(ret);
756
757 /* We may not clear more tiles. */
758 if (c != nullptr && GB(c->clear_limit, 16, 16) < 1) break;
759 continue;
760 }
761
762 had_success = true;
763 if (flags.Test(DoCommandFlag::Execute)) {
764 money -= ret.GetCost();
765 if (ret.GetCost() > 0 && money < 0) {
766 return { cost, ret.GetCost() };
767 }
768 Command<CMD_LANDSCAPE_CLEAR>::Do(flags, t);
769
770 /* draw explosion animation...
771 * Disable explosions when game is paused. Looks silly and blocks the view. */
772 if ((t == tile || t == start_tile) && _pause_mode.None()) {
773 /* big explosion in two corners, or small explosion for single tiles */
774 CreateEffectVehicleAbove(TileX(t) * TILE_SIZE + TILE_SIZE / 2, TileY(t) * TILE_SIZE + TILE_SIZE / 2, 2,
775 TileX(tile) == TileX(start_tile) && TileY(tile) == TileY(start_tile) ? EV_EXPLOSION_SMALL : EV_EXPLOSION_LARGE
776 );
777 }
778 } else {
779 /* When we're at the clearing limit we better bail (unneed) testing as well. */
780 if (ret.GetCost() != 0 && --limit <= 0) break;
781 }
782 cost.AddCost(ret.GetCost());
783 }
784
785 return { had_success ? cost : last_error, 0 };
786}
787
788
789 TileIndex _cur_tileloop_tile;
790
794 void RunTileLoop()
795{
796 PerformanceAccumulator framerate(PFE_GL_LANDSCAPE);
797
798 /* The pseudorandom sequence of tiles is generated using a Galois linear feedback
799 * shift register (LFSR). This allows a deterministic pseudorandom ordering, but
800 * still with minimal state and fast iteration. */
801
802 /* Maximal length LFSR feedback terms, from 12-bit (for 64x64 maps) to 24-bit (for 4096x4096 maps).
803 * Extracted from http://www.ece.cmu.edu/~koopman/lfsr/ */
804 static const uint32_t feedbacks[] = {
805 0xD8F, 0x1296, 0x2496, 0x4357, 0x8679, 0x1030E, 0x206CD, 0x403FE, 0x807B8, 0x1004B2, 0x2006A8, 0x4004B2, 0x800B87
806 };
807 static_assert(lengthof(feedbacks) == 2 * MAX_MAP_SIZE_BITS - 2 * MIN_MAP_SIZE_BITS + 1);
808 const uint32_t feedback = feedbacks[Map::LogX() + Map::LogY() - 2 * MIN_MAP_SIZE_BITS];
809
810 /* We update every tile every TILE_UPDATE_FREQUENCY ticks, so divide the map size by 2^TILE_UPDATE_FREQUENCY_LOG = TILE_UPDATE_FREQUENCY */
811 static_assert(2 * MIN_MAP_SIZE_BITS >= TILE_UPDATE_FREQUENCY_LOG);
812 uint count = 1 << (Map::LogX() + Map::LogY() - TILE_UPDATE_FREQUENCY_LOG);
813
814 TileIndex tile = _cur_tileloop_tile;
815 /* The LFSR cannot have a zeroed state. */
816 assert(tile != 0);
817
818 /* Manually update tile 0 every TILE_UPDATE_FREQUENCY ticks - the LFSR never iterates over it itself. */
819 if (TimerGameTick::counter % TILE_UPDATE_FREQUENCY == 0) {
820 _tile_type_procs[GetTileType(0)]->tile_loop_proc(TileIndex{});
821 count--;
822 }
823
824 while (count--) {
825 _tile_type_procs[GetTileType(tile)]->tile_loop_proc(tile);
826
827 /* Get the next tile in sequence using a Galois LFSR. */
828 tile = TileIndex{(tile.base() >> 1) ^ (-(int32_t)(tile.base() & 1) & feedback)};
829 }
830
831 _cur_tileloop_tile = tile;
832}
833
834void InitializeLandscape()
835{
836 for (uint y = _settings_game.construction.freeform_edges ? 1 : 0; y < Map::MaxY(); y++) {
837 for (uint x = _settings_game.construction.freeform_edges ? 1 : 0; x < Map::MaxX(); x++) {
838 MakeClear(TileXY(x, y), CLEAR_GRASS, 3);
839 SetTileHeight(TileXY(x, y), 0);
840 SetTropicZone(TileXY(x, y), TROPICZONE_NORMAL);
841 ClearBridgeMiddle(TileXY(x, y));
842 }
843 }
844
845 for (uint x = 0; x < Map::SizeX(); x++) MakeVoid(TileXY(x, Map::MaxY()));
846 for (uint y = 0; y < Map::SizeY(); y++) MakeVoid(TileXY(Map::MaxX(), y));
847}
848
849static const uint8_t _genterrain_tbl_1[5] = { 10, 22, 33, 37, 4 };
850static const uint8_t _genterrain_tbl_2[5] = { 0, 0, 0, 0, 33 };
851
852static void GenerateTerrain(int type, uint flag)
853{
854 uint32_t r = Random();
855
856 /* Choose one of the templates from the graphics file. */
857 const Sprite *templ = GetSprite((((r >> 24) * _genterrain_tbl_1[type]) >> 8) + _genterrain_tbl_2[type] + SPR_MAPGEN_BEGIN, SpriteType::MapGen);
858 if (templ == nullptr) UserError("Map generator sprites could not be loaded");
859
860 /* Chose a random location to apply the template to. */
861 uint x = r & Map::MaxX();
862 uint y = (r >> Map::LogX()) & Map::MaxY();
863
864 /* Make sure the template is not too close to the upper edges; bottom edges are checked later. */
865 uint edge_distance = 1 + (_settings_game.construction.freeform_edges ? 1 : 0);
866 if (x <= edge_distance || y <= edge_distance) return;
867
868 DiagDirection direction = (DiagDirection)GB(r, 22, 2);
869 uint w = templ->width;
870 uint h = templ->height;
871
872 if (DiagDirToAxis(direction) == AXIS_Y) std::swap(w, h);
873
874 const uint8_t *p = reinterpret_cast<const uint8_t *>(templ->data);
875
876 if ((flag & 4) != 0) {
877 /* This is only executed in secondary/tertiary loops to generate the terrain for arctic and tropic.
878 * It prevents the templates to be applied to certain parts of the map based on the flags, thus
879 * creating regions with different elevations/topography. */
880 uint xw = x * Map::SizeY();
881 uint yw = y * Map::SizeX();
882 uint bias = (Map::SizeX() + Map::SizeY()) * 16;
883
884 switch (flag & 3) {
885 default: NOT_REACHED();
886 case 0:
887 if (xw + yw > Map::Size() - bias) return;
888 break;
889
890 case 1:
891 if (yw < xw + bias) return;
892 break;
893
894 case 2:
895 if (xw + yw < Map::Size() + bias) return;
896 break;
897
898 case 3:
899 if (xw < yw + bias) return;
900 break;
901 }
902 }
903
904 /* Ensure the template does not overflow at the bottom edges of the map; upper edges were checked before. */
905 if (x + w >= Map::MaxX()) return;
906 if (y + h >= Map::MaxY()) return;
907
908 TileIndex tile = TileXY(x, y);
909
910 /* Get the template and overlay in a particular direction over the map's height from the given
911 * origin point (tile), and update the map's height everywhere where the height from the template
912 * is higher than the height of the map. In other words, this only raises the tile heights. */
913 switch (direction) {
914 default: NOT_REACHED();
915 case DIAGDIR_NE:
916 do {
917 TileIndex tile_cur = tile;
918
919 for (uint w_cur = w; w_cur != 0; --w_cur) {
920 if (GB(*p, 0, 4) >= TileHeight(tile_cur)) SetTileHeight(tile_cur, GB(*p, 0, 4));
921 p++;
922 tile_cur += TileDiffXY(1, 0);
923 }
924 tile += TileDiffXY(0, 1);
925 } while (--h != 0);
926 break;
927
928 case DIAGDIR_SE:
929 do {
930 TileIndex tile_cur = tile;
931
932 for (uint h_cur = h; h_cur != 0; --h_cur) {
933 if (GB(*p, 0, 4) >= TileHeight(tile_cur)) SetTileHeight(tile_cur, GB(*p, 0, 4));
934 p++;
935 tile_cur += TileDiffXY(0, 1);
936 }
937 tile += TileDiffXY(1, 0);
938 } while (--w != 0);
939 break;
940
941 case DIAGDIR_SW:
942 tile += TileDiffXY(w - 1, 0);
943 do {
944 TileIndex tile_cur = tile;
945
946 for (uint w_cur = w; w_cur != 0; --w_cur) {
947 if (GB(*p, 0, 4) >= TileHeight(tile_cur)) SetTileHeight(tile_cur, GB(*p, 0, 4));
948 p++;
949 tile_cur -= TileDiffXY(1, 0);
950 }
951 tile += TileDiffXY(0, 1);
952 } while (--h != 0);
953 break;
954
955 case DIAGDIR_NW:
956 tile += TileDiffXY(0, h - 1);
957 do {
958 TileIndex tile_cur = tile;
959
960 for (uint h_cur = h; h_cur != 0; --h_cur) {
961 if (GB(*p, 0, 4) >= TileHeight(tile_cur)) SetTileHeight(tile_cur, GB(*p, 0, 4));
962 p++;
963 tile_cur -= TileDiffXY(0, 1);
964 }
965 tile += TileDiffXY(1, 0);
966 } while (--w != 0);
967 break;
968 }
969}
970
971
972#include "table/genland.h"
973
974static void CreateDesertOrRainForest(uint desert_tropic_line)
975{
976 uint update_freq = Map::Size() / 4;
977
978 for (const auto tile : Map::Iterate()) {
979 if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
980
981 if (!IsValidTile(tile)) continue;
982
983 auto allows_desert = [tile, desert_tropic_line](auto &offset) {
984 TileIndex t = AddTileIndexDiffCWrap(tile, offset);
985 return t == INVALID_TILE || (TileHeight(t) < desert_tropic_line && !IsTileType(t, MP_WATER));
986 };
987 if (std::all_of(std::begin(_make_desert_or_rainforest_data), std::end(_make_desert_or_rainforest_data), allows_desert)) {
988 SetTropicZone(tile, TROPICZONE_DESERT);
989 }
990 }
991
992 for (uint i = 0; i != TILE_UPDATE_FREQUENCY; i++) {
993 if ((i % 64) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
994
995 RunTileLoop();
996 }
997
998 for (const auto tile : Map::Iterate()) {
999 if ((tile % update_freq) == 0) IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
1000
1001 if (!IsValidTile(tile)) continue;
1002
1003 auto allows_rainforest = [tile](auto &offset) {
1004 TileIndex t = AddTileIndexDiffCWrap(tile, offset);
1005 return t == INVALID_TILE || !IsTileType(t, MP_CLEAR) || !IsClearGround(t, CLEAR_DESERT);
1006 };
1007 if (std::all_of(std::begin(_make_desert_or_rainforest_data), std::end(_make_desert_or_rainforest_data), allows_rainforest)) {
1008 SetTropicZone(tile, TROPICZONE_RAINFOREST);
1009 }
1010 }
1011}
1012
1018 static bool FindSpring(TileIndex tile)
1019{
1020 int reference_height;
1021 if (!IsTileFlat(tile, &reference_height) || IsWaterTile(tile)) return false;
1022
1023 /* In the tropics rivers start in the rainforest. */
1024 if (_settings_game.game_creation.landscape == LandscapeType::Tropic && GetTropicZone(tile) != TROPICZONE_RAINFOREST) return false;
1025
1026 /* Are there enough higher tiles to warrant a 'spring'? */
1027 uint num = 0;
1028 for (int dx = -1; dx <= 1; dx++) {
1029 for (int dy = -1; dy <= 1; dy++) {
1030 TileIndex t = TileAddWrap(tile, dx, dy);
1031 if (t != INVALID_TILE && GetTileMaxZ(t) > reference_height) num++;
1032 }
1033 }
1034
1035 if (num < 4) return false;
1036
1037 /* Are we near the top of a hill? */
1038 for (int dx = -16; dx <= 16; dx++) {
1039 for (int dy = -16; dy <= 16; dy++) {
1040 TileIndex t = TileAddWrap(tile, dx, dy);
1041 if (t != INVALID_TILE && GetTileMaxZ(t) > reference_height + 2) return false;
1042 }
1043 }
1044
1045 return true;
1046}
1047
1054 static bool IsValidRiverTerminusTile(TileIndex tile, uint height)
1055{
1056 if (!IsValidTile(tile) || TileHeight(tile) != height || !IsTileFlat(tile)) return false;
1057 if (_settings_game.game_creation.landscape == LandscapeType::Tropic && GetTropicZone(tile) == TROPICZONE_DESERT) return false;
1058
1059 return true;
1060}
1061
1067 static void MakeLake(TileIndex lake_centre, uint height_lake)
1068{
1069 MakeRiverAndModifyDesertZoneAround(lake_centre);
1070 uint diameter = RandomRange(8) + 3;
1071
1072 /* Run the loop twice, so artefacts from going circular in one direction get (mostly) hidden. */
1073 for (uint loops = 0; loops < 2; ++loops) {
1074 for (TileIndex tile : SpiralTileSequence(lake_centre, diameter)) {
1075 if (!IsValidRiverTerminusTile(tile, height_lake)) continue;
1076 for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
1077 TileIndex t = tile + TileOffsByDiagDir(d);
1078 if (IsWaterTile(t)) {
1079 MakeRiverAndModifyDesertZoneAround(tile);
1080 break;
1081 }
1082 }
1083 }
1084 }
1085}
1086
1093 static void MakeWetlands(TileIndex centre, uint height, uint river_length)
1094{
1095 MakeRiverAndModifyDesertZoneAround(centre);
1096
1097 uint diameter = std::max((river_length), 16u);
1098
1099 /* Some wetlands have trees planted among the water tiles. */
1100 bool has_trees = Chance16(1, 2);
1101
1102 /* Create the main wetland area. */
1103 for (TileIndex tile : SpiralTileSequence(centre, diameter)) {
1104 if (!IsValidRiverTerminusTile(tile, height)) continue;
1105
1106 /* Don't make a perfect square, but a circle with a noisy border. */
1107 uint radius = diameter / 2;
1108 if ((DistanceSquare(tile, centre) > radius * radius) && Chance16(3, 4)) continue;
1109
1110 if (Chance16(1, 3)) {
1111 /* This tile is water. */
1112 MakeRiverAndModifyDesertZoneAround(tile);
1113 } else if (IsTileType(tile, MP_CLEAR)) {
1114 /* This tile is ground, which we always make rough. */
1115 SetClearGroundDensity(tile, CLEAR_ROUGH, 3);
1116 /* Maybe place trees? */
1117 if (has_trees && _settings_game.game_creation.tree_placer != TP_NONE) {
1118 PlaceTree(tile, Random(), true);
1119 }
1120 }
1121 }
1122}
1123
1130 static bool TryMakeRiverTerminus(TileIndex tile, TileIndex begin)
1131{
1132 if (!IsValidTile(tile)) return false;
1133
1134 /* We don't want to end the river at the entry of the valley. */
1135 if (tile == begin) return false;
1136
1137 /* We don't want the river to end in the desert. */
1138 if (_settings_game.game_creation.landscape == LandscapeType::Tropic && GetTropicZone(tile) == TROPICZONE_DESERT) return false;
1139
1140 /* Only end on flat slopes. */
1141 int height_lake;
1142 if (!IsTileFlat(tile, &height_lake)) return false;
1143
1144 /* Only build at the height of the river. */
1145 int height_begin = TileHeight(begin);
1146 if (height_lake != height_begin) return false;
1147
1148 /* Checks successful, time to build.
1149 * Chance of water feature is split evenly between a lake, a wetland with trees, and a wetland with grass. */
1150 if (Chance16(1, 3)) {
1151 MakeLake(tile, height_lake);
1152 } else {
1153 MakeWetlands(tile, height_lake, DistanceManhattan(tile, begin));
1154 }
1155
1156 /* This is the new end of the river. */
1157 return true;
1158}
1159
1165 void RiverMakeWider(TileIndex tile, TileIndex origin_tile)
1166{
1167 /* Don't expand into void tiles. */
1168 if (!IsValidTile(tile)) return;
1169
1170 /* If the tile is already sea or river, don't expand. */
1171 if (IsWaterTile(tile)) return;
1172
1173 /* If the tile is at height 0 after terraforming but the ocean hasn't flooded yet, don't build river. */
1174 if (GetTileMaxZ(tile) == 0) return;
1175
1176 Slope cur_slope = GetTileSlope(tile);
1177 Slope desired_slope = GetTileSlope(origin_tile); // Initialize matching the origin tile as a shortcut if no terraforming is needed.
1178
1179 /* Never flow uphill. */
1180 if (GetTileMaxZ(tile) > GetTileMaxZ(origin_tile)) return;
1181
1182 /* If the new tile can't hold a river tile, try terraforming. */
1183 if (!IsTileFlat(tile) && !IsInclinedSlope(cur_slope)) {
1184 /* Don't try to terraform steep slopes. */
1185 if (IsSteepSlope(cur_slope)) return;
1186
1187 bool flat_river_found = false;
1188 bool sloped_river_found = false;
1189
1190 /* There are two common possibilities:
1191 * 1. River flat, adjacent tile has one corner lowered.
1192 * 2. River descending, adjacent tile has either one or three corners raised.
1193 */
1194
1195 /* First, determine the desired slope based on adjacent river tiles. This doesn't necessarily match the origin tile for the SpiralTileSequence. */
1196 for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
1197 TileIndex other_tile = TileAddByDiagDir(tile, d);
1198 Slope other_slope = GetTileSlope(other_tile);
1199
1200 /* Only consider river tiles. */
1201 if (IsWaterTile(other_tile) && IsRiver(other_tile)) {
1202 /* If the adjacent river tile flows downhill, we need to check where we are relative to the slope. */
1203 if (IsInclinedSlope(other_slope) && GetTileMaxZ(tile) == GetTileMaxZ(other_tile)) {
1204 /* Check for a parallel slope. If we don't find one, we're above or below the slope instead. */
1205 if (GetInclinedSlopeDirection(other_slope) == ChangeDiagDir(d, DIAGDIRDIFF_90RIGHT) ||
1206 GetInclinedSlopeDirection(other_slope) == ChangeDiagDir(d, DIAGDIRDIFF_90LEFT)) {
1207 desired_slope = other_slope;
1208 sloped_river_found = true;
1209 break;
1210 }
1211 }
1212 /* If we find an adjacent river tile, remember it. We'll terraform to match it later if we don't find a slope. */
1213 if (IsTileFlat(other_tile)) flat_river_found = true;
1214 }
1215 }
1216 /* We didn't find either an inclined or flat river, so we're climbing the wrong slope. Bail out. */
1217 if (!sloped_river_found && !flat_river_found) return;
1218
1219 /* We didn't find an inclined river, but there is a flat river. */
1220 if (!sloped_river_found && flat_river_found) desired_slope = SLOPE_FLAT;
1221
1222 /* Now that we know the desired slope, it's time to terraform! */
1223
1224 /* If the river is flat and the adjacent tile has one corner lowered, we want to raise it. */
1225 if (desired_slope == SLOPE_FLAT && IsSlopeWithThreeCornersRaised(cur_slope)) {
1226 /* Make sure we're not affecting an existing river slope tile. */
1227 for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
1228 TileIndex other_tile = TileAddByDiagDir(tile, d);
1229 if (IsInclinedSlope(GetTileSlope(other_tile)) && IsWaterTile(other_tile)) return;
1230 }
1231 Command<CMD_TERRAFORM_LAND>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto}, tile, ComplementSlope(cur_slope), true);
1232
1233 /* If the river is descending and the adjacent tile has either one or three corners raised, we want to make it match the slope. */
1234 } else if (IsInclinedSlope(desired_slope)) {
1235 /* Don't break existing flat river tiles by terraforming under them. */
1236 DiagDirection river_direction = ReverseDiagDir(GetInclinedSlopeDirection(desired_slope));
1237
1238 for (DiagDirDiff d = DIAGDIRDIFF_BEGIN; d < DIAGDIRDIFF_END; d++) {
1239 /* We don't care about downstream or upstream tiles, just the riverbanks. */
1240 if (d == DIAGDIRDIFF_SAME || d == DIAGDIRDIFF_REVERSE) continue;
1241
1242 TileIndex other_tile = (TileAddByDiagDir(tile, ChangeDiagDir(river_direction, d)));
1243 if (IsWaterTile(other_tile) && IsRiver(other_tile) && IsTileFlat(other_tile)) return;
1244 }
1245
1246 /* Get the corners which are different between the current and desired slope. */
1247 Slope to_change = cur_slope ^ desired_slope;
1248
1249 /* Lower unwanted corners first. If only one corner is raised, no corners need lowering. */
1250 if (!IsSlopeWithOneCornerRaised(cur_slope)) {
1251 to_change = to_change & ComplementSlope(desired_slope);
1252 Command<CMD_TERRAFORM_LAND>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto}, tile, to_change, false);
1253 }
1254
1255 /* Now check the match and raise any corners needed. */
1256 cur_slope = GetTileSlope(tile);
1257 if (cur_slope != desired_slope && IsSlopeWithOneCornerRaised(cur_slope)) {
1258 to_change = cur_slope ^ desired_slope;
1259 Command<CMD_TERRAFORM_LAND>::Do({DoCommandFlag::Execute, DoCommandFlag::Auto}, tile, to_change, true);
1260 }
1261 }
1262 /* Update cur_slope after possibly terraforming. */
1263 cur_slope = GetTileSlope(tile);
1264 }
1265
1266 /* Sloped rivers need water both upstream and downstream. */
1267 if (IsInclinedSlope(cur_slope)) {
1268 DiagDirection slope_direction = GetInclinedSlopeDirection(cur_slope);
1269
1270 TileIndex upstream_tile = TileAddByDiagDir(tile, slope_direction);
1271 TileIndex downstream_tile = TileAddByDiagDir(tile, ReverseDiagDir(slope_direction));
1272
1273 /* Don't look outside the map. */
1274 if (!IsValidTile(upstream_tile) || !IsValidTile(downstream_tile)) return;
1275
1276 /* Downstream might be new ocean created by our terraforming, and it hasn't flooded yet. */
1277 bool downstream_is_ocean = GetTileZ(downstream_tile) == 0 && (GetTileSlope(downstream_tile) == SLOPE_FLAT || IsSlopeWithOneCornerRaised(GetTileSlope(downstream_tile)));
1278
1279 /* If downstream is dry, flat, and not ocean, try making it a river tile. */
1280 if (!IsWaterTile(downstream_tile) && !downstream_is_ocean) {
1281 /* If the tile upstream isn't flat, don't bother. */
1282 if (GetTileSlope(downstream_tile) != SLOPE_FLAT) return;
1283
1284 MakeRiverAndModifyDesertZoneAround(downstream_tile);
1285 }
1286
1287 /* If upstream is dry and flat, try making it a river tile. */
1288 if (!IsWaterTile(upstream_tile)) {
1289 /* If the tile upstream isn't flat, don't bother. */
1290 if (GetTileSlope(upstream_tile) != SLOPE_FLAT) return;
1291
1292 MakeRiverAndModifyDesertZoneAround(upstream_tile);
1293 }
1294 }
1295
1296 /* If the tile slope matches the desired slope, add a river tile. */
1297 if (cur_slope == desired_slope) {
1298 MakeRiverAndModifyDesertZoneAround(tile);
1299 }
1300}
1301
1308 bool RiverFlowsDown(TileIndex begin, TileIndex end)
1309{
1310 assert(DistanceManhattan(begin, end) == 1);
1311
1312 auto [slope_end, height_end] = GetTileSlopeZ(end);
1313
1314 /* Slope either is inclined or flat; rivers don't support other slopes. */
1315 if (slope_end != SLOPE_FLAT && !IsInclinedSlope(slope_end)) return false;
1316
1317 auto [slope_begin, height_begin] = GetTileSlopeZ(begin);
1318
1319 /* It can't flow uphill. */
1320 if (height_end > height_begin) return false;
1321
1322 /* Slope continues, then it must be lower... */
1323 if (slope_end == slope_begin && height_end < height_begin) return true;
1324
1325 /* ... or either end must be flat. */
1326 return slope_end == SLOPE_FLAT || slope_begin == SLOPE_FLAT;
1327}
1328
1336 static bool CountConnectedSeaTiles(TileIndex tile, std::unordered_set<TileIndex> &sea, const uint limit)
1337{
1338 /* This tile might not be sea. */
1339 if (!IsWaterTile(tile) || GetWaterClass(tile) != WaterClass::Sea || !IsTileFlat(tile)) return false;
1340
1341 /* If we've found an edge tile, we are "connected to the sea outside the map." */
1342 if (DistanceFromEdge(tile) <= 1) return true;
1343
1344 /* We have now evaluated this tile and don't want to check it again. */
1345 sea.insert(tile);
1346
1347 /* We might want to cut our search short if the size of the sea is "big enough".
1348 * Count this tile but don't check its neighbors. */
1349 if (sea.size() > limit) return false;
1350
1351 /* Count adjacent tiles using recusion. */
1352 for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
1353 TileIndex t = tile + TileOffsByDiagDir(d);
1354 if (IsValidTile(t) && !sea.contains(t)) {
1355 if (CountConnectedSeaTiles(t, sea, limit)) return true;
1356 }
1357 }
1358
1359 return false;
1360}
1361
1369 static std::tuple<bool, bool> FlowRiver(TileIndex spring, TileIndex begin, uint min_river_length)
1370{
1371 if (IsWaterTile(begin)) {
1372 return { DistanceManhattan(spring, begin) > min_river_length, GetTileZ(begin) == 0 };
1373 }
1374
1375 int height_begin = TileHeight(begin);
1376
1377 std::unordered_set<TileIndex> marks;
1378 marks.insert(begin);
1379
1380 std::vector<TileIndex> queue;
1381 queue.push_back(begin);
1382
1383 /* Breadth first search for the closest tile we can flow down to.
1384 * We keep the queue to find the Nth tile for lake guessing. The tiles
1385 * in the queue are neatly ordered by insertion.
1386 */
1387 bool found = false;
1388 TileIndex end;
1389 for (size_t i = 0; i != queue.size(); i++) {
1390 end = queue[i];
1391
1392 int height_end;
1393 if (IsTileFlat(end, &height_end) && (height_end < height_begin || (height_end == height_begin && IsWaterTile(end)))) {
1394 if (IsWaterTile(end) && GetWaterClass(end) == WaterClass::Sea) {
1395 /* If we've found the sea, make sure it's large enough. Scale by the map size but set a cap to avoid performance issues on large maps. */
1396 const uint MAX_SEA_SIZE_THRESHOLD = 1024;
1397 const uint SEA_SIZE_THRESHOLD = std::min(static_cast<uint>(2 * std::sqrt(Map::SizeX() * Map::SizeY())), MAX_SEA_SIZE_THRESHOLD);
1398 std::unordered_set<TileIndex> sea;
1399 /* Count the connected tiles, if the sea is large we can end the river here. */
1400 bool found_edge = CountConnectedSeaTiles(end, sea, SEA_SIZE_THRESHOLD);
1401 if (found_edge || sea.size() > SEA_SIZE_THRESHOLD) {
1402 found = true;
1403 break;
1404 } else {
1405 /* Sea is too small, flatten it so the river keeps looking or forms a lake / wetland. */
1406 for (TileIndex sea_tile : sea) {
1407 Command<CMD_TERRAFORM_LAND>::Do(DoCommandFlag::Execute, sea_tile, SLOPE_ELEVATED, false);
1408 Slope slope = ComplementSlope(GetTileSlope(sea_tile));
1409 Command<CMD_TERRAFORM_LAND>::Do(DoCommandFlag::Execute, sea_tile, slope, true);
1410 }
1411 }
1412 } else {
1413 /* We've found a river. */
1414 found = true;
1415 break;
1416 }
1417 }
1418
1419 for (DiagDirection d = DIAGDIR_BEGIN; d < DIAGDIR_END; d++) {
1420 TileIndex t = end + TileOffsByDiagDir(d);
1421 if (IsValidTile(t) && !marks.contains(t) && RiverFlowsDown(end, t)) {
1422 marks.insert(t);
1423 queue.push_back(t);
1424 }
1425 }
1426 }
1427
1428 bool main_river = false;
1429 if (found) {
1430 /* Flow further down hill. */
1431 std::tie(found, main_river) = FlowRiver(spring, end, min_river_length);
1432 } else if (queue.size() > 32) {
1433 /* Maybe we can make a lake. Find the Nth of the considered tiles. */
1434 TileIndex lake_centre = queue[RandomRange(static_cast<uint32_t>(queue.size()))];
1435 if (DistanceManhattan(spring, lake_centre) > min_river_length) {
1436 if (TryMakeRiverTerminus(lake_centre, begin)) {
1437 /* If successful, this becomes the new end of the river. */
1438 end = lake_centre;
1439 found = true;
1440 }
1441 }
1442 }
1443
1444 if (found) YapfBuildRiver(begin, end, spring, main_river);
1445 return { found, main_river };
1446}
1447
1451 static void CreateRivers()
1452{
1453 int amount = _settings_game.game_creation.amount_of_rivers;
1454 if (amount == 0) return;
1455
1456 uint wells = Map::ScaleBySize(4 << _settings_game.game_creation.amount_of_rivers);
1457 const uint num_short_rivers = wells - std::max(1u, wells / 10);
1458 SetGeneratingWorldProgress(GWP_RIVER, wells + TILE_UPDATE_FREQUENCY / 64); // Include the tile loop calls below.
1459
1460 /* Try to create long rivers. */
1461 for (; wells > num_short_rivers; wells--) {
1462 IncreaseGeneratingWorldProgress(GWP_RIVER);
1463 bool done = false;
1464 for (int tries = 0; tries < 512; tries++) {
1465 for (auto t : SpiralTileSequence(RandomTile(), 8)) {
1466 if (FindSpring(t)) {
1467 done = std::get<0>(FlowRiver(t, t, _settings_game.game_creation.min_river_length * 4));
1468 break;
1469 }
1470 }
1471 if (done) break;
1472 }
1473 }
1474
1475 /* Try to create short rivers. */
1476 for (; wells != 0; wells--) {
1477 IncreaseGeneratingWorldProgress(GWP_RIVER);
1478 bool done = false;
1479 for (int tries = 0; tries < 128; tries++) {
1480 for (auto t : SpiralTileSequence(RandomTile(), 8)) {
1481 if (FindSpring(t)) {
1482 done = std::get<0>(FlowRiver(t, t, _settings_game.game_creation.min_river_length));
1483 break;
1484 }
1485 }
1486 if (done) break;
1487 }
1488 }
1489
1490 /* Widening rivers may have left some tiles requiring to be watered. */
1491 ConvertGroundTilesIntoWaterTiles();
1492
1493 /* Run tile loop to update the ground density. */
1494 for (uint i = 0; i != TILE_UPDATE_FREQUENCY; i++) {
1495 if (i % 64 == 0) IncreaseGeneratingWorldProgress(GWP_RIVER);
1496 RunTileLoop();
1497 }
1498}
1499
1517 static uint CalculateCoverageLine(uint coverage, uint edge_multiplier)
1518{
1519 /* Histogram of how many tiles per height level exist. */
1520 std::array<int, MAX_TILE_HEIGHT + 1> histogram = {};
1521 /* Histogram of how many neighbour tiles are lower than the tiles of the height level. */
1522 std::array<int, MAX_TILE_HEIGHT + 1> edge_histogram = {};
1523
1524 /* Build a histogram of the map height. */
1525 for (const auto tile : Map::Iterate()) {
1526 uint h = TileHeight(tile);
1527 histogram[h]++;
1528
1529 if (edge_multiplier != 0) {
1530 /* Check if any of our neighbours is below us. */
1531 for (DiagDirection dir = DIAGDIR_BEGIN; dir != DIAGDIR_END; dir++) {
1532 TileIndex neighbour_tile = AddTileIndexDiffCWrap(tile, TileIndexDiffCByDiagDir(dir));
1533 if (IsValidTile(neighbour_tile) && TileHeight(neighbour_tile) < h) {
1534 edge_histogram[h]++;
1535 }
1536 }
1537 }
1538 }
1539
1540 /* The amount of land we have is the map size minus the first (sea) layer. */
1541 uint land_tiles = Map::Size() - histogram[0];
1542 int best_score = land_tiles;
1543
1544 /* Our goal is the coverage amount of the land-mass. */
1545 int goal_tiles = land_tiles * coverage / 100;
1546
1547 /* We scan from top to bottom. */
1548 uint h = MAX_TILE_HEIGHT;
1549 uint best_h = h;
1550
1551 int current_tiles = 0;
1552 for (; h > 0; h--) {
1553 current_tiles += histogram[h];
1554 int current_score = goal_tiles - current_tiles;
1555
1556 /* Tropic grows from water and mountains into the desert. This is a
1557 * great visual, but it also means we* need to take into account how
1558 * much less desert tiles are being created if we are on this
1559 * height-level. We estimate this based on how many neighbouring
1560 * tiles are below us for a given length, assuming that is where
1561 * tropic is growing from.
1562 */
1563 if (edge_multiplier != 0 && h > 1) {
1564 /* From water tropic tiles grow for a few tiles land inward. */
1565 current_score -= edge_histogram[1] * edge_multiplier;
1566 /* Tropic tiles grow into the desert for a few tiles. */
1567 current_score -= edge_histogram[h] * edge_multiplier;
1568 }
1569
1570 if (std::abs(current_score) < std::abs(best_score)) {
1571 best_score = current_score;
1572 best_h = h;
1573 }
1574
1575 /* Always scan all height-levels, as h == 1 might give a better
1576 * score than any before. This is true for example with 0% desert
1577 * coverage. */
1578 }
1579
1580 return best_h;
1581}
1582
1586 static void CalculateSnowLine()
1587{
1588 /* We do not have snow sprites on coastal tiles, so never allow "1" as height. */
1589 _settings_game.game_creation.snow_line_height = std::max(CalculateCoverageLine(_settings_game.game_creation.snow_coverage, 0), 2u);
1590}
1591
1596 static uint8_t CalculateDesertLine()
1597{
1598 /* CalculateCoverageLine() runs from top to bottom, so we need to invert the coverage. */
1599 return CalculateCoverageLine(100 - _settings_game.game_creation.desert_coverage, 4);
1600}
1601
1602 bool GenerateLandscape(uint8_t mode)
1603{
1604 /* Number of steps of landscape generation */
1605 static constexpr uint GLS_HEIGHTMAP = 3;
1606 static constexpr uint GLS_TERRAGENESIS = 4;
1607 static constexpr uint GLS_ORIGINAL = 2;
1608 static constexpr uint GLS_TROPIC = 12;
1609 static constexpr uint GLS_OTHER = 0;
1610 uint steps = (_settings_game.game_creation.landscape == LandscapeType::Tropic) ? GLS_TROPIC : GLS_OTHER;
1611
1612 if (mode == GWM_HEIGHTMAP) {
1613 SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_HEIGHTMAP);
1614 if (!LoadHeightmap(_file_to_saveload.ftype.detailed, _file_to_saveload.name)) {
1615 return false;
1616 }
1617 IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
1618 } else if (_settings_game.game_creation.land_generator == LG_TERRAGENESIS) {
1619 SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_TERRAGENESIS);
1620 GenerateTerrainPerlin();
1621 } else {
1622 SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_ORIGINAL);
1623 if (_settings_game.construction.freeform_edges) {
1624 for (uint x = 0; x < Map::SizeX(); x++) MakeVoid(TileXY(x, 0));
1625 for (uint y = 0; y < Map::SizeY(); y++) MakeVoid(TileXY(0, y));
1626 }
1627 switch (_settings_game.game_creation.landscape) {
1628 case LandscapeType::Arctic: {
1629 uint32_t r = Random();
1630
1631 for (uint i = Map::ScaleBySize(GB(r, 0, 7) + 950); i != 0; --i) {
1632 GenerateTerrain(2, 0);
1633 }
1634
1635 uint flag = GB(r, 7, 2) | 4;
1636 for (uint i = Map::ScaleBySize(GB(r, 9, 7) + 450); i != 0; --i) {
1637 GenerateTerrain(4, flag);
1638 }
1639 break;
1640 }
1641
1642 case LandscapeType::Tropic: {
1643 uint32_t r = Random();
1644
1645 for (uint i = Map::ScaleBySize(GB(r, 0, 7) + 170); i != 0; --i) {
1646 GenerateTerrain(0, 0);
1647 }
1648
1649 uint flag = GB(r, 7, 2) | 4;
1650 for (uint i = Map::ScaleBySize(GB(r, 9, 8) + 1700); i != 0; --i) {
1651 GenerateTerrain(0, flag);
1652 }
1653
1654 flag ^= 2;
1655
1656 for (uint i = Map::ScaleBySize(GB(r, 17, 7) + 410); i != 0; --i) {
1657 GenerateTerrain(3, flag);
1658 }
1659 break;
1660 }
1661
1662 default: {
1663 uint32_t r = Random();
1664
1665 assert(_settings_game.difficulty.quantity_sea_lakes != CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY);
1666 uint i = Map::ScaleBySize(GB(r, 0, 7) + (3 - _settings_game.difficulty.quantity_sea_lakes) * 256 + 100);
1667 for (; i != 0; --i) {
1668 /* Make sure we do not overflow. */
1669 GenerateTerrain(Clamp(_settings_game.difficulty.terrain_type, 0, 3), 0);
1670 }
1671 break;
1672 }
1673 }
1674 }
1675
1676 /* Do not call IncreaseGeneratingWorldProgress() before FixSlopes(),
1677 * it allows screen redraw. Drawing of broken slopes crashes the game */
1678 FixSlopes();
1679 MarkWholeScreenDirty();
1680 IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
1681
1682 ConvertGroundTilesIntoWaterTiles();
1683 MarkWholeScreenDirty();
1684 IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
1685
1686 switch (_settings_game.game_creation.landscape) {
1687 case LandscapeType::Arctic:
1688 CalculateSnowLine();
1689 break;
1690
1691 case LandscapeType::Tropic: {
1692 uint desert_tropic_line = CalculateDesertLine();
1693 CreateDesertOrRainForest(desert_tropic_line);
1694 break;
1695 }
1696
1697 default:
1698 break;
1699 }
1700
1701 CreateRivers();
1702 return true;
1703}
1704
1705void OnTick_Town();
1706void OnTick_Trees();
1707void OnTick_Station();
1708void OnTick_Industry();
1709
1710void OnTick_Companies();
1711void OnTick_LinkGraph();
1712
1713void CallLandscapeTick()
1714{
1715 {
1716 PerformanceAccumulator framerate(PFE_GL_LANDSCAPE);
1717
1718 OnTick_Town();
1719 OnTick_Trees();
1720 OnTick_Station();
1721 OnTick_Industry();
1722 }
1723
1724 OnTick_Companies();
1725 OnTick_LinkGraph();
1726}
DeleteAnimatedTile
void DeleteAnimatedTile(TileIndex tile, bool immediate)
Stops animation on the given tile.
Definition animated_tile.cpp:27
animated_tile_func.h
Tile animation!
GB
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
Definition bitmath_func.hpp:32
ClearBridgeMiddle
void ClearBridgeMiddle(Tile t)
Removes bridges from the given, that is bridges along the X and Y axis.
Definition bridge_map.h:103
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
BaseBitSet::None
constexpr bool None() const
Test if none of the values are set.
Definition base_bitset_type.hpp:188
BaseBitSet::Reset
constexpr Timpl & Reset()
Reset all bits.
Definition base_bitset_type.hpp:83
BaseBitSet::Set
constexpr Timpl & Set()
Set all bits.
Definition base_bitset_type.hpp:40
BaseBitSet::Any
constexpr bool Any(const Timpl &other) const
Test if any of the given values are set.
Definition base_bitset_type.hpp:170
CommandCost
Common return value for all commands.
Definition command_type.h:24
CommandCost::AddCost
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
Definition command_type.h:98
CommandCost::GetCost
Money GetCost() const
The costs as made up to this moment.
Definition command_type.h:118
CommandCost::Failed
bool Failed() const
Did this command fail?
Definition command_type.h:177
EnumBitSet
Enum-as-bit-set wrapper.
Definition enum_type.hpp:177
OverflowSafeInt< int64_t >
PerformanceAccumulator
RAII class for measuring multi-step elements of performance.
Definition framerate_type.h:113
SpiralTileSequence
Generate TileIndices around a center tile or tile area, with increasing distance.
Definition tilearea_type.h:316
TileIterator::Create
static std::unique_ptr< TileIterator > Create(TileIndex corner1, TileIndex corner2, bool diagonal)
Create either an OrthogonalTileIterator or DiagonalTileIterator given the diagonal parameter.
Definition tilearea.cpp:291
TimerGameCalendar::ConvertDateToYMD
static YearMonthDay ConvertDateToYMD(Date date)
Converts a Date to a Year, Month & Day.
Definition timer_game_calendar.cpp:42
TimerGameCalendar::date
static Date date
Current date in days (day counter).
Definition timer_game_calendar.h:33
TimerGameTick::counter
static TickCounter counter
Monotonic counter, in ticks, since start of game.
Definition timer_game_tick.h:60
clear_map.h
Map accessors for 'clear' tiles.
IsClearGround
bool IsClearGround(Tile t, ClearGround ct)
Set the type of clear tile.
Definition clear_map.h:59
CLEAR_GRASS
@ CLEAR_GRASS
0-3
Definition clear_map.h:20
CLEAR_DESERT
@ CLEAR_DESERT
1,3
Definition clear_map.h:25
CLEAR_ROUGH
@ CLEAR_ROUGH
3
Definition clear_map.h:21
MakeClear
void MakeClear(Tile t, ClearGround g, uint density)
Make a clear tile.
Definition clear_map.h:247
SetClearGroundDensity
void SetClearGroundDensity(Tile t, ClearGround type, uint density)
Sets ground type and density in one go, also sets the counter to 0.
Definition clear_map.h:146
command_func.h
Functions related to commands.
CMD_ERROR
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition command_func.h:28
DoCommandFlag::Auto
@ Auto
don't allow building on structures
DoCommandFlag::NoWater
@ NoWater
don't allow building on water
DoCommandFlag::Execute
@ Execute
execute the given command
DoCommandFlag::Bankrupt
@ Bankrupt
company bankrupts, skip money check, skip vehicle on tile check in some cases
DoCommandFlag::ForceClearTile
@ ForceClearTile
do not only remove the object on the tile, but also clear any water left on it
GetAvailableMoneyForCommand
Money GetAvailableMoneyForCommand()
This functions returns the money which can be used to execute a command.
Definition company_cmd.cpp:252
_current_company
CompanyID _current_company
Company currently doing an action.
Definition company_cmd.cpp:56
company_func.h
Functions related to companies.
DirtyCompanyInfrastructureWindows
void DirtyCompanyInfrastructureWindows(CompanyID company)
Redraw all windows with company infrastructure counts.
Definition company_gui.cpp:2318
company_gui.h
GUI Functions related to companies.
ReverseDiagDir
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
Definition direction_func.h:118
ChangeDiagDir
DiagDirection ChangeDiagDir(DiagDirection d, DiagDirDiff delta)
Applies a difference on a DiagDirection.
Definition direction_func.h:149
DiagDirToAxis
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
Definition direction_func.h:214
DiagDirDiff
DiagDirDiff
Enumeration for the difference between to DiagDirection.
Definition direction_type.h:102
DIAGDIRDIFF_END
@ DIAGDIRDIFF_END
Used for iterations.
Definition direction_type.h:108
DIAGDIRDIFF_90RIGHT
@ DIAGDIRDIFF_90RIGHT
90 degrees right
Definition direction_type.h:105
DIAGDIRDIFF_90LEFT
@ DIAGDIRDIFF_90LEFT
90 degrees left
Definition direction_type.h:107
DIAGDIRDIFF_REVERSE
@ DIAGDIRDIFF_REVERSE
Reverse directions.
Definition direction_type.h:106
DIAGDIRDIFF_SAME
@ DIAGDIRDIFF_SAME
Same directions.
Definition direction_type.h:104
DIAGDIRDIFF_BEGIN
@ DIAGDIRDIFF_BEGIN
Used for iterations.
Definition direction_type.h:103
AXIS_Y
@ AXIS_Y
The y axis.
Definition direction_type.h:125
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition direction_type.h:78
DIAGDIR_NE
@ DIAGDIR_NE
Northeast, upper right on your monitor.
Definition direction_type.h:80
DIAGDIR_NW
@ DIAGDIR_NW
Northwest.
Definition direction_type.h:83
DIAGDIR_SE
@ DIAGDIR_SE
Southeast.
Definition direction_type.h:81
DIAGDIR_END
@ DIAGDIR_END
Used for iterations.
Definition direction_type.h:84
DIAGDIR_BEGIN
@ DIAGDIR_BEGIN
Used for iterations.
Definition direction_type.h:79
DIAGDIR_SW
@ DIAGDIR_SW
Southwest.
Definition direction_type.h:82
EXPENSES_CONSTRUCTION
@ EXPENSES_CONSTRUCTION
Construction costs.
Definition economy_type.h:179
CreateEffectVehicleAbove
EffectVehicle * CreateEffectVehicleAbove(int x, int y, int z, EffectVehicleType type)
Create an effect vehicle above a particular location.
Definition effectvehicle.cpp:594
effectvehicle_func.h
Functions related to effect vehicles.
EV_EXPLOSION_SMALL
@ EV_EXPLOSION_SMALL
Various explosions.
Definition effectvehicle_func.h:24
EV_EXPLOSION_LARGE
@ EV_EXPLOSION_LARGE
Various explosions.
Definition effectvehicle_func.h:22
error_func.h
Error reporting related functions.
fios.h
Declarations for savegames operations.
framerate_type.h
Types for recording game performance data.
PFE_GL_LANDSCAPE
@ PFE_GL_LANDSCAPE
Time spent processing other world features.
Definition framerate_type.h:54
genland.h
Table used to generate deserts and/or rainforests.
_generating_world
bool _generating_world
Whether we are generating the map or not.
Definition genworld.cpp:74
genworld.h
Functions related to world/map generation.
IncreaseGeneratingWorldProgress
void IncreaseGeneratingWorldProgress(GenWorldProgress cls)
Increases the current stage of the world generation with one.
Definition genworld_gui.cpp:1534
LG_TERRAGENESIS
@ LG_TERRAGENESIS
TerraGenesis Perlin landscape generator.
Definition genworld.h:22
CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY
static const uint CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY
Value for custom sea level in difficulty settings.
Definition genworld.h:48
GWP_LANDSCAPE
@ GWP_LANDSCAPE
Create the landscape.
Definition genworld.h:63
GWP_RIVER
@ GWP_RIVER
Create the rivers.
Definition genworld.h:64
SetGeneratingWorldProgress
void SetGeneratingWorldProgress(GenWorldProgress cls, uint total)
Set the total of a stage of the world generation.
Definition genworld_gui.cpp:1520
GWM_HEIGHTMAP
@ GWM_HEIGHTMAP
Generate a newgame from a heightmap.
Definition genworld.h:32
_pause_mode
PauseModes _pause_mode
The current pause mode.
Definition gfx.cpp:50
SpriteID
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
SpriteType::MapGen
@ MapGen
Special sprite for the map generator.
LowestSnowLine
uint8_t LowestSnowLine()
Get the lowest possible snow line height, either variable or static.
Definition landscape.cpp:628
GetSnowLine
uint8_t GetSnowLine()
Get the current snow line, either variable or static.
Definition landscape.cpp:605
IsSnowLineSet
bool IsSnowLineSet()
Has a snow line table already been loaded.
Definition landscape.cpp:585
ClearSnowLine
void ClearSnowLine()
Clear the variable snow line table and free the memory.
Definition landscape.cpp:637
_snow_line
static std::unique_ptr< SnowLine > _snow_line
Description of the snow line throughout the year.
Definition landscape.cpp:99
SetSnowLine
void SetSnowLine(std::unique_ptr< SnowLine > &&snow_line)
Set a variable snow line, as loaded from a newgrf file.
Definition landscape.cpp:595
HighestSnowLine
uint8_t HighestSnowLine()
Get the highest possible snow line height, either variable or static.
Definition landscape.cpp:618
MarkWholeScreenDirty
void MarkWholeScreenDirty()
This function mark the whole screen as dirty.
Definition gfx.cpp:1546
MarkTileDirtyByTile
void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset, int tile_height_override)
Mark a tile given by its index dirty for repaint.
Definition viewport.cpp:2128
LoadHeightmap
bool LoadHeightmap(DetailedFileType dft, std::string_view filename)
Load a heightmap from file and change the map in its current dimensions to a landscape representing t...
Definition heightmap.cpp:517
FixSlopes
void FixSlopes()
This function takes care of the fact that land in OpenTTD can never differ more than 1 in height.
Definition heightmap.cpp:403
heightmap.h
Functions related to creating heightmaps from files.
GetPartialPixelZ
uint GetPartialPixelZ(int x, int y, Slope corners)
Determines height at given coordinate of a slope.
Definition landscape.cpp:231
FlowRiver
static std::tuple< bool, bool > FlowRiver(TileIndex spring, TileIndex begin, uint min_river_length)
Try to flow the river down from a given begin.
Definition landscape.cpp:1369
GetSlopePixelZOutsideMap
int GetSlopePixelZOutsideMap(int x, int y)
Return world z coordinate of a given point of a tile, also for tiles outside the map (virtual "black"...
Definition landscape.cpp:321
GetTileTrackStatus
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
Definition landscape.cpp:559
OnTick_Companies
void OnTick_Companies()
Called every tick for updating some company info.
Definition company_cmd.cpp:770
TryMakeRiverTerminus
static bool TryMakeRiverTerminus(TileIndex tile, TileIndex begin)
Try to end a river at a tile which is not the sea.
Definition landscape.cpp:1130
CalculateCoverageLine
static uint CalculateCoverageLine(uint coverage, uint edge_multiplier)
Calculate what height would be needed to cover N% of the landmass.
Definition landscape.cpp:1517
IsValidRiverTerminusTile
static bool IsValidRiverTerminusTile(TileIndex tile, uint height)
Is this a valid tile for the water feature at the end of a river?
Definition landscape.cpp:1054
CalculateSnowLine
static void CalculateSnowLine()
Calculate the line from which snow begins.
Definition landscape.cpp:1586
TILE_UPDATE_FREQUENCY_LOG
static const uint TILE_UPDATE_FREQUENCY_LOG
The logarithm of how many ticks it takes between tile updates (log base 2).
Definition landscape.cpp:88
ChangeTileOwner
void ChangeTileOwner(TileIndex tile, Owner old_owner, Owner new_owner)
Change the owner of a tile.
Definition landscape.cpp:570
RunTileLoop
void RunTileLoop()
Gradually iterate over all tiles on the map, calling their TileLoopProcs once every TILE_UPDATE_FREQU...
Definition landscape.cpp:794
FindSpring
static bool FindSpring(TileIndex tile)
Find the spring of a river.
Definition landscape.cpp:1018
RiverFlowsDown
bool RiverFlowsDown(TileIndex begin, TileIndex end)
Check whether a river at begin could (logically) flow down to end.
Definition landscape.cpp:1308
CreateRivers
static void CreateRivers()
Actually (try to) create some rivers.
Definition landscape.cpp:1451
DrawFoundation
void DrawFoundation(TileInfo *ti, Foundation f)
Draw foundation f at tile ti.
Definition landscape.cpp:428
GetSlopeZInCorner
int GetSlopeZInCorner(Slope tileh, Corner corner)
Determine the Z height of a corner relative to TileZ.
Definition landscape.cpp:339
GetFoundationSlope
std::tuple< Slope, int > GetFoundationSlope(TileIndex tile)
Get slope of a tile on top of a (possible) foundation If a tile does not have a foundation,...
Definition landscape.cpp:385
GetSlopePixelZOnEdge
void GetSlopePixelZOnEdge(Slope tileh, DiagDirection edge, int &z1, int &z2)
Determine the Z height of the corners of a specific tile edge.
Definition landscape.cpp:357
MakeWetlands
static void MakeWetlands(TileIndex centre, uint height, uint river_length)
Make wetlands around the given tile.
Definition landscape.cpp:1093
OnTick_LinkGraph
void OnTick_LinkGraph()
Spawn or join a link graph job or compress a link graph if any link graph is due to do so.
Definition linkgraphschedule.cpp:202
_tile_type_procs
const TileTypeProcs *const _tile_type_procs[16]
Tile callback functions for each type of tile.
Definition landscape.cpp:68
InverseRemapCoords2
Point InverseRemapCoords2(int x, int y, bool clamp_to_map, bool *clamped)
Map 2D viewport or smallmap coordinate to 3D world or tile coordinate.
Definition landscape.cpp:114
_tile_type_town_procs
const TileTypeProcs _tile_type_town_procs
Tile callback functions for a town.
Definition landscape.cpp:54
MakeLake
static void MakeLake(TileIndex lake_centre, uint height_lake)
Make a lake centred on the given tile, of a random diameter.
Definition landscape.cpp:1067
OnTick_Town
void OnTick_Town()
Iterate through all towns and call their tick handler.
Definition town_cmd.cpp:940
CalculateDesertLine
static uint8_t CalculateDesertLine()
Calculate the line (in height) between desert and tropic.
Definition landscape.cpp:1596
_slope_to_sprite_offset
const uint8_t _slope_to_sprite_offset[32]
landscape slope => sprite
CmdClearArea
std::tuple< CommandCost, Money > CmdClearArea(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, bool diagonal)
Clear a big piece of landscape.
Definition landscape.cpp:736
_tile_type_road_procs
const TileTypeProcs _tile_type_road_procs
Tile callback functions for road tiles.
Definition landscape.cpp:53
ApplyFoundationToSlope
uint ApplyFoundationToSlope(Foundation f, Slope &s)
Applies a foundation to a slope.
Definition landscape.cpp:173
IsMapSurroundedByWater
bool IsMapSurroundedByWater()
Check if all tiles on the map edge should be considered water borders.
Definition landscape.cpp:646
CountConnectedSeaTiles
static bool CountConnectedSeaTiles(TileIndex tile, std::unordered_set< TileIndex > &sea, const uint limit)
Find the size of a patch of connected sea tiles.
Definition landscape.cpp:1336
GenerateLandscape
bool GenerateLandscape(uint8_t mode)
Definition landscape.cpp:1602
CmdLandscapeClear
CommandCost CmdLandscapeClear(DoCommandFlags flags, TileIndex tile)
Clear a piece of landscape.
Definition landscape.cpp:678
RiverMakeWider
void RiverMakeWider(TileIndex tile, TileIndex origin_tile)
Widen a river by expanding into adjacent tiles via circular tile search.
Definition landscape.cpp:1165
TILE_UPDATE_FREQUENCY
static const uint TILE_UPDATE_FREQUENCY
How many ticks it takes between tile updates (has to be a power of 2).
Definition landscape.cpp:89
GetSlopePixelZ
int GetSlopePixelZ(int x, int y, bool ground_vehicle)
Return world Z coordinate of a given point of a tile.
Definition landscape.cpp:306
landscape.h
Functions related to OTTD's landscape.
GetFoundationPixelSlope
std::tuple< Slope, int > GetFoundationPixelSlope(TileIndex tile)
Get slope of a tile on top of a (possible) foundation If a tile does not have a foundation,...
Definition landscape.h:67
ApplyPixelFoundationToSlope
uint ApplyPixelFoundationToSlope(Foundation f, Slope &s)
Applies a foundation to a slope.
Definition landscape.h:128
InverseRemapCoords
Point InverseRemapCoords(int x, int y)
Map 2D viewport or smallmap coordinate to 3D world or tile coordinate.
Definition landscape.h:111
landscape_cmd.h
Command definitions related to landscape (slopes etc.).
landscape_type.h
Types related to the landscape.
BorderFlag::Random
@ Random
Randomise borders.
DistanceSquare
uint DistanceSquare(TileIndex t0, TileIndex t1)
Gets the 'Square' distance between the two given tiles.
Definition map.cpp:175
DistanceFromEdge
uint DistanceFromEdge(TileIndex tile)
Param the minimum distance to an edge.
Definition map.cpp:218
TileAddWrap
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:109
DistanceManhattan
uint DistanceManhattan(TileIndex t0, TileIndex t1)
Gets the Manhattan distance between the two given tiles.
Definition map.cpp:158
TileAddXY
TileIndex TileAddXY(TileIndex tile, int x, int y)
Adds a given offset to a tile.
Definition map_func.h:482
TileVirtXY
static TileIndex TileVirtXY(uint x, uint y)
Get a tile from the virtual XY-coordinate.
Definition map_func.h:416
AddTileIndexDiffCWrap
TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff)
Add a TileIndexDiffC to a TileIndex and returns the new one.
Definition map_func.h:527
TileAddByDiagDir
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:623
TileDiffXY
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition map_func.h:401
TileXY
static TileIndex TileXY(uint x, uint y)
Returns the TileIndex of a coordinate.
Definition map_func.h:385
TileY
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:437
TileIndexDiffCByDiagDir
TileIndexDiffC TileIndexDiffCByDiagDir(DiagDirection dir)
Returns the TileIndexDiffC offset from a DiagDirection.
Definition map_func.h:495
TileX
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:427
RandomTile
#define RandomTile()
Get a valid random tile.
Definition map_func.h:664
TileOffsByDiagDir
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:582
MIN_MAP_SIZE_BITS
static const uint MIN_MAP_SIZE_BITS
Minimal and maximal map width and height.
Definition map_type.h:37
MAX_MAP_SIZE_BITS
static const uint MAX_MAP_SIZE_BITS
Maximal size of map is equal to 2 ^ MAX_MAP_SIZE_BITS.
Definition map_type.h:38
IsInsideBS
constexpr bool IsInsideBS(const T x, const size_t base, const size_t size)
Checks if a value is between a window started at some base point.
Definition math_func.hpp:252
CeilDiv
constexpr uint CeilDiv(uint a, uint b)
Computes ceil(a / b) for non-negative a and b.
Definition math_func.hpp:310
Clamp
constexpr T Clamp(const T a, const T min, const T max)
Clamp a value between an interval.
Definition math_func.hpp:79
object_base.h
Base for all objects.
FindClearedObject
ClearedObjectArea * FindClearedObject(TileIndex tile)
Find the entry in _cleared_object_areas which occupies a certain tile.
Definition object_cmd.cpp:530
random_func.hpp
Pseudo random number generator.
RandomRange
uint32_t RandomRange(uint32_t limit, const std::source_location location=std::source_location::current())
Pick a random number between 0 and limit - 1, inclusive.
Definition random_func.hpp:88
Chance16
bool Chance16(const uint32_t a, const uint32_t b, const std::source_location location=std::source_location::current())
Flips a coin with given probability.
Definition random_func.hpp:134
safeguards.h
A number of safeguards to prevent using unsafe methods.
_file_to_saveload
FileToSaveLoad _file_to_saveload
File to save or load in the openttd loop.
Definition saveload.cpp:78
saveload.h
Functions/types related to saving and loading games.
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
TP_NONE
@ TP_NONE
No tree placer algorithm.
Definition settings_type.h:108
IsSpecialRailFoundation
bool IsSpecialRailFoundation(Foundation f)
Tests if a foundation is a special rail foundation for single horizontal/vertical track.
Definition slope_func.h:345
SlopeWithThreeCornersRaised
Slope SlopeWithThreeCornersRaised(Corner corner)
Returns the slope with all except one corner raised.
Definition slope_func.h:206
OppositeCorner
Corner OppositeCorner(Corner corner)
Returns the opposite corner.
Definition slope_func.h:184
GetHalftileSlopeCorner
static constexpr Corner GetHalftileSlopeCorner(Slope s)
Returns the leveled halftile of a halftile slope.
Definition slope_func.h:148
RemoveHalftileSlope
static constexpr Slope RemoveHalftileSlope(Slope s)
Removes a halftile slope from a slope.
Definition slope_func.h:60
IsSlopeWithOneCornerRaised
bool IsSlopeWithOneCornerRaised(Slope s)
Tests if a specific slope has exactly one corner raised.
Definition slope_func.h:88
IsNonContinuousFoundation
bool IsNonContinuousFoundation(Foundation f)
Tests if a foundation is a non-continuous foundation, i.e.
Definition slope_func.h:320
GetHighestSlopeCorner
Corner GetHighestSlopeCorner(Slope s)
Returns the highest corner of a slope (one corner raised or a steep slope).
Definition slope_func.h:126
GetHalftileFoundationCorner
Corner GetHalftileFoundationCorner(Foundation f)
Returns the halftile corner of a halftile-foundation.
Definition slope_func.h:333
IsLeveledFoundation
bool IsLeveledFoundation(Foundation f)
Tests if the foundation is a leveled foundation.
Definition slope_func.h:298
IsFoundation
bool IsFoundation(Foundation f)
Tests for FOUNDATION_NONE.
Definition slope_func.h:287
IsSteepSlope
static constexpr bool IsSteepSlope(Slope s)
Checks if a slope is steep.
Definition slope_func.h:36
IsSlopeWithThreeCornersRaised
bool IsSlopeWithThreeCornersRaised(Slope s)
Tests if a specific slope has exactly three corners raised.
Definition slope_func.h:195
IsInclinedSlope
bool IsInclinedSlope(Slope s)
Tests if a specific slope is an inclined slope.
Definition slope_func.h:228
SteepSlope
Slope SteepSlope(Corner corner)
Returns a specific steep slope.
Definition slope_func.h:217
GetRailFoundationCorner
Corner GetRailFoundationCorner(Foundation f)
Returns the track corner of a special rail foundation.
Definition slope_func.h:356
IsHalftileSlope
static constexpr bool IsHalftileSlope(Slope s)
Checks for non-continuous slope on halftile foundations.
Definition slope_func.h:47
GetSlopeMaxPixelZ
static constexpr int GetSlopeMaxPixelZ(Slope s)
Returns the height of the highest corner of a slope relative to TileZ (= minimal height)
Definition slope_func.h:173
GetInclinedSlopeDirection
DiagDirection GetInclinedSlopeDirection(Slope s)
Returns the direction of an inclined slope.
Definition slope_func.h:239
HalftileSlope
static constexpr Slope HalftileSlope(Slope s, Corner corner)
Adds a halftile slope to a slope.
Definition slope_func.h:274
ComplementSlope
Slope ComplementSlope(Slope s)
Return the complement of a slope.
Definition slope_func.h:76
SlopeWithOneCornerRaised
Slope SlopeWithOneCornerRaised(Corner corner)
Returns the slope with a specific corner raised.
Definition slope_func.h:99
IsInclinedFoundation
bool IsInclinedFoundation(Foundation f)
Tests if the foundation is an inclined foundation.
Definition slope_func.h:309
Corner
Corner
Enumeration of tile corners.
Definition slope_type.h:22
Slope
Slope
Enumeration for the slope-type.
Definition slope_type.h:48
SLOPE_W
@ SLOPE_W
the west corner of the tile is raised
Definition slope_type.h:50
SLOPE_ELEVATED
@ SLOPE_ELEVATED
bit mask containing all 'simple' slopes
Definition slope_type.h:61
SLOPE_NS
@ SLOPE_NS
north and south corner are raised
Definition slope_type.h:60
SLOPE_E
@ SLOPE_E
the east corner of the tile is raised
Definition slope_type.h:52
SLOPE_WSE
@ SLOPE_WSE
west, south and east corner are raised
Definition slope_type.h:63
SLOPE_S
@ SLOPE_S
the south corner of the tile is raised
Definition slope_type.h:51
SLOPE_N
@ SLOPE_N
the north corner of the tile is raised
Definition slope_type.h:53
SLOPE_SEN
@ SLOPE_SEN
south, east and north corner are raised
Definition slope_type.h:64
SLOPE_ENW
@ SLOPE_ENW
east, north and west corner are raised
Definition slope_type.h:65
SLOPE_SW
@ SLOPE_SW
south and west corner are raised
Definition slope_type.h:56
SLOPE_FLAT
@ SLOPE_FLAT
a flat tile
Definition slope_type.h:49
SLOPE_STEEP_W
@ SLOPE_STEEP_W
a steep slope falling to east (from west)
Definition slope_type.h:66
SLOPE_NE
@ SLOPE_NE
north and east corner are raised
Definition slope_type.h:58
SLOPE_STEEP_E
@ SLOPE_STEEP_E
a steep slope falling to west (from east)
Definition slope_type.h:68
SLOPE_SE
@ SLOPE_SE
south and east corner are raised
Definition slope_type.h:57
SLOPE_NWS
@ SLOPE_NWS
north, west and south corner are raised
Definition slope_type.h:62
SLOPE_NW
@ SLOPE_NW
north and west corner are raised
Definition slope_type.h:55
SLOPE_STEEP_N
@ SLOPE_STEEP_N
a steep slope falling to south (from north)
Definition slope_type.h:69
SLOPE_STEEP_S
@ SLOPE_STEEP_S
a steep slope falling to north (from south)
Definition slope_type.h:67
SLOPE_EW
@ SLOPE_EW
east and west corner are raised
Definition slope_type.h:59
SLOPE_STEEP
@ SLOPE_STEEP
indicates the slope is steep
Definition slope_type.h:54
Foundation
Foundation
Enumeration for Foundations.
Definition slope_type.h:93
FOUNDATION_INCLINED_X
@ FOUNDATION_INCLINED_X
The tile has an along X-axis inclined foundation.
Definition slope_type.h:96
FOUNDATION_STEEP_BOTH
@ FOUNDATION_STEEP_BOTH
The tile has a steep slope. The lowest corner is raised by a foundation and the upper halftile is lev...
Definition slope_type.h:101
FOUNDATION_INCLINED_Y
@ FOUNDATION_INCLINED_Y
The tile has an along Y-axis inclined foundation.
Definition slope_type.h:97
FOUNDATION_STEEP_LOWER
@ FOUNDATION_STEEP_LOWER
The tile has a steep slope. The lowest corner is raised by a foundation to allow building railroad on...
Definition slope_type.h:98
spritecache.h
Functions to cache sprites in memory.
sprites.h
This file contains all sprite-related enums and defines.
SPR_HALFTILE_FOUNDATION_BASE
static const SpriteID SPR_HALFTILE_FOUNDATION_BASE
Halftile foundations.
Definition sprites.h:212
station_func.h
Functions related to stations.
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
lengthof
#define lengthof(array)
Return the length of an fixed size array.
Definition stdafx.h:271
ClearedObjectArea
Keeps track of removed objects during execution/testruns of commands.
Definition object_base.h:86
ClearedObjectArea::first_tile
TileIndex first_tile
The first tile being cleared, which then causes the whole object to be cleared.
Definition object_base.h:87
CommandHelper
Definition command_func.h:83
CompanyProperties::clear_limit
uint32_t clear_limit
Amount of tiles we can (still) clear (times 65536).
Definition company_base.h:106
Company
Definition company_base.h:127
ConstructionSettings::freeform_edges
bool freeform_edges
allow terraforming the tiles at the map edges
Definition settings_type.h:423
ConstructionSettings::map_height_limit
uint8_t map_height_limit
the maximum allowed heightlevel
Definition settings_type.h:410
Coord2D< int >
Coord2D::y
T y
Y coordinate.
Definition geometry_type.hpp:35
Coord2D::x
T x
X coordinate.
Definition geometry_type.hpp:34
Coord3D::x
T x
X coordinate.
Definition geometry_type.hpp:44
Coord3D::z
T z
Z coordinate.
Definition geometry_type.hpp:46
DifficultySettings::terrain_type
uint8_t terrain_type
the mountainousness of the landscape
Definition settings_type.h:137
DifficultySettings::quantity_sea_lakes
uint8_t quantity_sea_lakes
the amount of seas/lakes
Definition settings_type.h:138
FileToSaveLoad::ftype
FiosType ftype
File type.
Definition saveload.h:429
FileToSaveLoad::name
std::string name
Name of the file.
Definition saveload.h:430
FiosType::detailed
DetailedFileType detailed
Detailed file type.
Definition fileio_type.h:65
GameCreationSettings::tree_placer
uint8_t tree_placer
the tree placer algorithm
Definition settings_type.h:391
GameCreationSettings::amount_of_rivers
uint8_t amount_of_rivers
the amount of rivers
Definition settings_type.h:405
GameCreationSettings::min_river_length
uint8_t min_river_length
the minimum river length
Definition settings_type.h:403
GameCreationSettings::snow_coverage
uint8_t snow_coverage
the amount of snow coverage on the map
Definition settings_type.h:387
GameCreationSettings::desert_coverage
uint8_t desert_coverage
the amount of desert coverage on the map
Definition settings_type.h:388
GameCreationSettings::landscape
LandscapeType landscape
the landscape we're currently in
Definition settings_type.h:395
GameCreationSettings::snow_line_height
uint8_t snow_line_height
the configured snow line height (deduced from "snow_coverage")
Definition settings_type.h:386
GameCreationSettings::land_generator
uint8_t land_generator
the landscape generator
Definition settings_type.h:384
GameSettings::construction
ConstructionSettings construction
construction of things in-game
Definition settings_type.h:635
GameSettings::difficulty
DifficultySettings difficulty
settings related to the difficulty
Definition settings_type.h:633
GameSettings::game_creation
GameCreationSettings game_creation
settings used during the creation of a game (map)
Definition settings_type.h:634
Map
Size related data of the map.
Definition map_func.h:206
Map::SizeX
static uint SizeX()
Get the size of the map along the X.
Definition map_func.h:272
Map::ScaleBySize
static uint ScaleBySize(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:340
Map::SizeY
static uint SizeY()
Get the size of the map along the Y.
Definition map_func.h:281
Map::Iterate
static IterateWrapper Iterate()
Returns an iterable ensemble of all Tiles.
Definition map_func.h:375
Map::LogX
static uint LogX()
Logarithm of the map size along the X side.
Definition map_func.h:253
Map::LogY
static uint LogY()
Logarithm of the map size along the y side.
Definition map_func.h:263
Map::MaxY
static uint MaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
Definition map_func.h:308
Map::MaxX
static uint MaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition map_func.h:299
Map::Size
static uint Size()
Get the size of the map.
Definition map_func.h:290
PoolID< uint8_t, struct CompanyIDTag, 0xF, 0xFF >
Pool::PoolItem<&_company_pool >::Get
static Titem * Get(auto index)
Returns Titem with given index.
Definition pool_type.hpp:387
Pool::PoolItem<&_company_pool >::IsValidID
static bool IsValidID(auto index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition pool_type.hpp:376
Pool::PoolItem<&_company_pool >::GetIfValid
static Titem * GetIfValid(auto index)
Returns Titem with given index.
Definition pool_type.hpp:398
SpriteBounds
Definition sprite.h:18
SpriteBounds::extent
Coord3D< uint8_t > extent
Size of bounding box.
Definition sprite.h:20
Sprite
Data structure describing a sprite.
Definition spritecache_type.h:16
Sprite::width
uint16_t width
Width of the sprite.
Definition spritecache_type.h:18
Sprite::height
uint16_t height
Height of the sprite.
Definition spritecache_type.h:17
Sprite::data
std::byte data[]
Sprite data.
Definition spritecache_type.h:21
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
TileDesc
Tile description for the 'land area information' tool.
Definition tile_cmd.h:36
TileInfo
Tile information, used while rendering the tile.
Definition tile_cmd.h:30
TileInfo::tileh
Slope tileh
Slope of the tile.
Definition tile_cmd.h:31
TileInfo::tile
TileIndex tile
Tile index.
Definition tile_cmd.h:32
TileTypeProcs
Set of callback functions for performing tile operations of a given tile type.
Definition tile_cmd.h:152
TileTypeProcs::get_tile_desc_proc
GetTileDescProc * get_tile_desc_proc
Get a description of a tile (for the 'land area information' tool)
Definition tile_cmd.h:157
TileTypeProcs::get_tile_track_status_proc
GetTileTrackStatusProc * get_tile_track_status_proc
Get available tracks and status of a tile.
Definition tile_cmd.h:158
terraform_cmd.h
Command definitions related to terraforming.
GenerateTerrainPerlin
void GenerateTerrainPerlin()
The main new land generator using Perlin noise.
Definition tgp.cpp:979
tgp.h
Functions for the Perlin noise enhanced map generator.
MayAnimateTile
bool MayAnimateTile(TileIndex tile)
Test if a tile may be animated.
Definition tile_cmd.h:197
IsTileFlat
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition tile_map.cpp:95
GetTilePixelSlopeOutsideMap
std::tuple< Slope, int > GetTilePixelSlopeOutsideMap(int x, int y)
Return the slope of a given tile, also for tiles outside the map (virtual "black" tiles).
Definition tile_map.cpp:78
GetTileSlopeZ
std::tuple< Slope, int > GetTileSlopeZ(TileIndex tile)
Return the slope of a given tile inside the map.
Definition tile_map.cpp:55
GetTileMaxZ
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition tile_map.cpp:136
GetTileZ
int GetTileZ(TileIndex tile)
Get bottom height of the tile.
Definition tile_map.cpp:116
IsTileType
static bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition tile_map.h:150
TileHeight
static uint TileHeight(Tile tile)
Returns the height of a tile.
Definition tile_map.h:29
GetTileOwner
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition tile_map.h:178
IsValidTile
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition tile_map.h:161
GetTropicZone
TropicZone GetTropicZone(Tile tile)
Get the tropic zone.
Definition tile_map.h:238
SetTileHeight
void SetTileHeight(Tile tile, uint height)
Sets the height of a tile.
Definition tile_map.h:57
GetTileSlope
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
Definition tile_map.h:279
SetTropicZone
void SetTropicZone(Tile tile, TropicZone type)
Set the tropic zone.
Definition tile_map.h:225
GetTileType
static TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition tile_map.h:96
MAX_TILE_HEIGHT
static constexpr uint MAX_TILE_HEIGHT
Maximum allowed tile height.
Definition tile_type.h:24
TROPICZONE_RAINFOREST
@ TROPICZONE_RAINFOREST
Rainforest tile.
Definition tile_type.h:79
TROPICZONE_DESERT
@ TROPICZONE_DESERT
Tile is desert.
Definition tile_type.h:78
TROPICZONE_NORMAL
@ TROPICZONE_NORMAL
Normal tropiczone.
Definition tile_type.h:77
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition tile_type.h:95
TILE_SIZE
static constexpr uint TILE_SIZE
Tile size in world coordinates.
Definition tile_type.h:15
TILE_PIXELS
static constexpr uint TILE_PIXELS
Pixel distance between tile columns/rows in ZOOM_BASE.
Definition tile_type.h:17
TILE_HEIGHT
static constexpr uint TILE_HEIGHT
Height of a height level in world coordinate AND in pixels in ZOOM_BASE.
Definition tile_type.h:18
MP_CLEAR
@ MP_CLEAR
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition tile_type.h:48
MP_WATER
@ MP_WATER
Water tile.
Definition tile_type.h:54
MP_VOID
@ MP_VOID
Invisible tiles at the SW and SE border.
Definition tile_type.h:55
timer_game_calendar.h
Definition of the game-calendar-timer.
timer_game_tick.h
Definition of the tick-based game-timer.
TransportType
TransportType
Available types of transport.
Definition transport_type.h:17
PlaceTree
void PlaceTree(TileIndex tile, uint32_t r, bool keep_density)
Make a random tree tile of the given tile.
Definition tree_cmd.cpp:161
tree_cmd.h
Command definitions related to tree tiles.
OffsetGroundSprite
void OffsetGroundSprite(int x, int y)
Called when a foundation has been drawn for the current tile.
Definition viewport.cpp:591
AddSortableSpriteToDraw
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int z, const SpriteBounds &bounds, bool transparent, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
Definition viewport.cpp:663
viewport_func.h
Functions related to (drawing on) viewports.
void_map.h
Map accessors for void tiles.
MakeVoid
void MakeVoid(Tile t)
Make a nice void tile ;)
Definition void_map.h:19
water.h
Functions related to water (management)
ClearNeighbourNonFloodingStates
void ClearNeighbourNonFloodingStates(TileIndex tile)
Clear non-flooding state of the tiles around a tile.
Definition water_cmd.cpp:97
MakeRiverAndModifyDesertZoneAround
void MakeRiverAndModifyDesertZoneAround(TileIndex tile)
Make a river tile and remove desert directly around it.
Definition water_cmd.cpp:472
IsTileOnWater
bool IsTileOnWater(Tile t)
Tests if the tile was built on water.
Definition water_map.h:138
IsRiver
bool IsRiver(Tile t)
Is it a river water tile?
Definition water_map.h:182
WaterClass::Canal
@ Canal
Canal.
WaterClass::Sea
@ Sea
Sea.
HasTileWaterClass
bool HasTileWaterClass(Tile t)
Checks whether the tile has an waterclass associated.
Definition water_map.h:103
IsCanal
bool IsCanal(Tile t)
Is it a canal tile?
Definition water_map.h:171
GetWaterClass
WaterClass GetWaterClass(Tile t)
Get the water class at a tile.
Definition water_map.h:114
IsCoastTile
bool IsCoastTile(Tile t)
Is it a coast tile.
Definition water_map.h:213
IsDockingTile
bool IsDockingTile(Tile t)
Checks whether the tile is marked as a dockling tile.
Definition water_map.h:373
IsWaterTile
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition water_map.h:192
InvalidateWaterRegion
void InvalidateWaterRegion(TileIndex tile)
Marks the water region that tile is part of as invalid.
Definition water_regions.cpp:313
water_regions.h
Handles dividing the water in the map into regions to assist pathfinding.
YapfBuildRiver
void YapfBuildRiver(TileIndex start_tile, TileIndex end_tile, TileIndex spring_tile, bool main_river)
Builds a river from the start tile to the end tile.
Definition yapf_river_builder.cpp:144
yapf_river_builder.h
Pathfinder for river building.