OpenTTD Source: src/water_cmd.cpp Source File

OpenTTD Source 15.0-RC2

water_cmd.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
10#include "stdafx.h"
11#include "landscape.h"
12#include "viewport_func.h"
13#include "command_func.h"
14#include "town.h"
15#include "news_func.h"
16#include "depot_base.h"
17#include "depot_func.h"
18#include "water.h"
19#include "industry_map.h"
20#include "newgrf_canal.h"
21#include "strings_func.h"
22#include "vehicle_func.h"
23#include "sound_func.h"
24#include "company_func.h"
25#include "clear_map.h"
26#include "tree_map.h"
27#include "aircraft.h"
28#include "effectvehicle_func.h"
29#include "tunnelbridge_map.h"
30#include "station_base.h"
31#include "ai/ai.hpp"
32#include "game/game.hpp"
33#include "core/random_func.hpp"
34#include "core/backup_type.hpp"
35#include "timer/timer_game_calendar.h"
36#include "company_base.h"
37#include "company_gui.h"
38#include "newgrf_generic.h"
39#include "industry.h"
40#include "water_cmd.h"
41#include "landscape_cmd.h"
42#include "pathfinder/water_regions.h"
43
44#include "table/strings.h"
45
46#include "safeguards.h"
47
51 static const Directions _flood_from_dirs[] = {
52 {DIR_NW, DIR_SW, DIR_SE, DIR_NE}, // SLOPE_FLAT
53 {DIR_NE, DIR_SE}, // SLOPE_W
54 {DIR_NW, DIR_NE}, // SLOPE_S
55 {DIR_NE}, // SLOPE_SW
56 {DIR_NW, DIR_SW}, // SLOPE_E
57 {}, // SLOPE_EW
58 {DIR_NW}, // SLOPE_SE
59 {DIR_N, DIR_NW, DIR_NE}, // SLOPE_WSE, SLOPE_STEEP_S
60 {DIR_SW, DIR_SE}, // SLOPE_N
61 {DIR_SE}, // SLOPE_NW
62 {}, // SLOPE_NS
63 {DIR_E, DIR_NE, DIR_SE}, // SLOPE_NWS, SLOPE_STEEP_W
64 {DIR_SW}, // SLOPE_NE
65 {DIR_S, DIR_SW, DIR_SE}, // SLOPE_ENW, SLOPE_STEEP_N
66 {DIR_W, DIR_SW, DIR_NW}, // SLOPE_SEN, SLOPE_STEEP_E
67};
68
75 static inline void MarkTileDirtyIfCanalOrRiver(TileIndex tile)
76{
77 if (IsValidTile(tile) && IsTileType(tile, MP_WATER) && (IsCanal(tile) || IsRiver(tile))) MarkTileDirtyByTile(tile);
78}
79
86 static void MarkCanalsAndRiversAroundDirty(TileIndex tile)
87{
88 for (Direction dir = DIR_BEGIN; dir < DIR_END; dir++) {
89 MarkTileDirtyIfCanalOrRiver(tile + TileOffsByDir(dir));
90 }
91}
92
97 void ClearNeighbourNonFloodingStates(TileIndex tile)
98{
99 for (Direction dir = DIR_BEGIN; dir != DIR_END; dir++) {
100 TileIndex dest = tile + TileOffsByDir(dir);
101 if (IsValidTile(dest) && IsTileType(dest, MP_WATER)) SetNonFloodingWaterTile(dest, false);
102 }
103}
104
112 CommandCost CmdBuildShipDepot(DoCommandFlags flags, TileIndex tile, Axis axis)
113{
114 if (!IsValidAxis(axis)) return CMD_ERROR;
115 TileIndex tile2 = tile + TileOffsByAxis(axis);
116
117 if (!HasTileWaterGround(tile) || !HasTileWaterGround(tile2)) {
118 return CommandCost(STR_ERROR_MUST_BE_BUILT_ON_WATER);
119 }
120
121 if (IsBridgeAbove(tile) || IsBridgeAbove(tile2)) return CommandCost(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
122
123 if (!IsTileFlat(tile) || !IsTileFlat(tile2)) {
124 /* Prevent depots on rapids */
125 return CommandCost(STR_ERROR_SITE_UNSUITABLE);
126 }
127
128 if (!Depot::CanAllocateItem()) return CMD_ERROR;
129
130 WaterClass wc1 = GetWaterClass(tile);
131 WaterClass wc2 = GetWaterClass(tile2);
132 CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_DEPOT_SHIP]);
133
134 bool add_cost = !IsWaterTile(tile);
135 CommandCost ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags | DoCommandFlag::Auto, tile);
136 if (ret.Failed()) return ret;
137 if (add_cost) {
138 cost.AddCost(ret.GetCost());
139 }
140 add_cost = !IsWaterTile(tile2);
141 ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags | DoCommandFlag::Auto, tile2);
142 if (ret.Failed()) return ret;
143 if (add_cost) {
144 cost.AddCost(ret.GetCost());
145 }
146
147 if (flags.Test(DoCommandFlag::Execute)) {
148 Depot *depot = new Depot(tile);
149
150 uint new_water_infra = 2 * LOCK_DEPOT_TILE_FACTOR;
151 /* Update infrastructure counts after the tile clears earlier.
152 * Clearing object tiles may result in water tiles which are already accounted for in the water infrastructure total.
153 * See: MakeWaterKeepingClass() */
154 if (wc1 == WaterClass::Canal && !(HasTileWaterClass(tile) && GetWaterClass(tile) == WaterClass::Canal && IsTileOwner(tile, _current_company))) new_water_infra++;
155 if (wc2 == WaterClass::Canal && !(HasTileWaterClass(tile2) && GetWaterClass(tile2) == WaterClass::Canal && IsTileOwner(tile2, _current_company))) new_water_infra++;
156
157 Company::Get(_current_company)->infrastructure.water += new_water_infra;
158 DirtyCompanyInfrastructureWindows(_current_company);
159
160 MakeShipDepot(tile, _current_company, depot->index, DepotPart::North, axis, wc1);
161 MakeShipDepot(tile2, _current_company, depot->index, DepotPart::South, axis, wc2);
162 CheckForDockingTile(tile);
163 CheckForDockingTile(tile2);
164 MarkTileDirtyByTile(tile);
165 MarkTileDirtyByTile(tile2);
166 MakeDefaultName(depot);
167 }
168
169 return cost;
170}
171
172bool IsPossibleDockingTile(Tile t)
173{
174 assert(IsValidTile(t));
175 switch (GetTileType(t)) {
176 case MP_WATER:
177 if (IsLock(t) && GetLockPart(t) == LockPart::Middle) return false;
178 [[fallthrough]];
179 case MP_RAILWAY:
180 case MP_STATION:
181 case MP_TUNNELBRIDGE:
182 return TrackStatusToTrackBits(GetTileTrackStatus(t, TRANSPORT_WATER, 0)) != TRACK_BIT_NONE;
183
184 default:
185 return false;
186 }
187}
188
194 void CheckForDockingTile(TileIndex t)
195{
196 for (DiagDirection d = DIAGDIR_BEGIN; d != DIAGDIR_END; d++) {
197 TileIndex tile = t + TileOffsByDiagDir(d);
198 if (!IsValidTile(tile)) continue;
199
200 if (IsDockTile(tile) && IsDockWaterPart(tile)) {
201 Station::GetByTile(tile)->docking_station.Add(t);
202 SetDockingTile(t, true);
203 }
204 if (IsTileType(tile, MP_INDUSTRY)) {
205 Station *st = Industry::GetByTile(tile)->neutral_station;
206 if (st != nullptr) {
207 st->docking_station.Add(t);
208 SetDockingTile(t, true);
209 }
210 }
211 if (IsTileType(tile, MP_STATION) && IsOilRig(tile)) {
212 Station::GetByTile(tile)->docking_station.Add(t);
213 SetDockingTile(t, true);
214 }
215 }
216}
217
218void MakeWaterKeepingClass(TileIndex tile, Owner o)
219{
220 WaterClass wc = GetWaterClass(tile);
221
222 /* Autoslope might turn an originally canal or river tile into land */
223 auto [slope, z] = GetTileSlopeZ(tile);
224
225 if (slope != SLOPE_FLAT) {
226 if (wc == WaterClass::Canal) {
227 /* If we clear the canal, we have to remove it from the infrastructure count as well. */
228 Company *c = Company::GetIfValid(o);
229 if (c != nullptr) {
230 c->infrastructure.water--;
231 DirtyCompanyInfrastructureWindows(c->index);
232 }
233 /* Sloped canals are locks and no natural water remains whatever the slope direction */
234 wc = WaterClass::Invalid;
235 }
236
237 /* Only river water should be restored on appropriate slopes. Other water would be invalid on slopes */
238 if (wc != WaterClass::River || GetInclinedSlopeDirection(slope) == INVALID_DIAGDIR) {
239 wc = WaterClass::Invalid;
240 }
241 }
242
243 if (wc == WaterClass::Sea && z > 0) {
244 /* Update company infrastructure count. */
245 Company *c = Company::GetIfValid(o);
246 if (c != nullptr) {
247 c->infrastructure.water++;
248 DirtyCompanyInfrastructureWindows(c->index);
249 }
250
251 wc = WaterClass::Canal;
252 }
253
254 /* Zero map array and terminate animation */
255 DoClearSquare(tile);
256
257 /* Maybe change to water */
258 switch (wc) {
259 case WaterClass::Sea: MakeSea(tile); break;
260 case WaterClass::Canal: MakeCanal(tile, o, Random()); break;
261 case WaterClass::River: MakeRiver(tile, Random()); break;
262 default: break;
263 }
264
265 if (wc != WaterClass::Invalid) CheckForDockingTile(tile);
266 MarkTileDirtyByTile(tile);
267}
268
269static CommandCost RemoveShipDepot(TileIndex tile, DoCommandFlags flags)
270{
271 if (!IsShipDepot(tile)) return CMD_ERROR;
272
273 CommandCost ret = CheckTileOwnership(tile);
274 if (ret.Failed()) return ret;
275
276 TileIndex tile2 = GetOtherShipDepotTile(tile);
277
278 /* do not check for ship on tile when company goes bankrupt */
279 if (!flags.Test(DoCommandFlag::Bankrupt)) {
280 ret = EnsureNoVehicleOnGround(tile);
281 if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile2);
282 if (ret.Failed()) return ret;
283 }
284
285 bool do_clear = flags.Test(DoCommandFlag::ForceClearTile);
286
287 if (flags.Test(DoCommandFlag::Execute)) {
288 delete Depot::GetByTile(tile);
289
290 Company *c = Company::GetIfValid(GetTileOwner(tile));
291 if (c != nullptr) {
292 c->infrastructure.water -= 2 * LOCK_DEPOT_TILE_FACTOR;
293 if (do_clear && GetWaterClass(tile) == WaterClass::Canal) c->infrastructure.water--;
294 DirtyCompanyInfrastructureWindows(c->index);
295 }
296
297 if (!do_clear) MakeWaterKeepingClass(tile, GetTileOwner(tile));
298 MakeWaterKeepingClass(tile2, GetTileOwner(tile2));
299 }
300
301 return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_DEPOT_SHIP]);
302}
303
309 static uint8_t GetLockPartMinimalBridgeHeight(LockPart lock_part)
310{
311 static constexpr uint8_t MINIMAL_BRIDGE_HEIGHT[to_underlying(LockPart::End)] = {
312 2, // LockPart::Middle
313 3, // LockPart::Lower
314 2, // LockPart::Upper
315 };
316 return MINIMAL_BRIDGE_HEIGHT[to_underlying(lock_part)];
317}
318
326 static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlags flags)
327{
328 CommandCost cost(EXPENSES_CONSTRUCTION);
329
330 TileIndexDiff delta = TileOffsByDiagDir(dir);
331 CommandCost ret = EnsureNoVehicleOnGround(tile);
332 if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile + delta);
333 if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile - delta);
334 if (ret.Failed()) return ret;
335
336 /* middle tile */
337 WaterClass wc_middle = HasTileWaterGround(tile) ? GetWaterClass(tile) : WaterClass::Canal;
338 ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
339 if (ret.Failed()) return ret;
340 cost.AddCost(ret.GetCost());
341
342 /* lower tile */
343 if (!IsWaterTile(tile - delta)) {
344 ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile - delta);
345 if (ret.Failed()) return ret;
346 cost.AddCost(ret.GetCost());
347 cost.AddCost(_price[PR_BUILD_CANAL]);
348 }
349 if (!IsTileFlat(tile - delta)) {
350 return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
351 }
352 WaterClass wc_lower = IsWaterTile(tile - delta) ? GetWaterClass(tile - delta) : WaterClass::Canal;
353
354 /* upper tile */
355 if (!IsWaterTile(tile + delta)) {
356 ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile + delta);
357 if (ret.Failed()) return ret;
358 cost.AddCost(ret.GetCost());
359 cost.AddCost(_price[PR_BUILD_CANAL]);
360 }
361 if (!IsTileFlat(tile + delta)) {
362 return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
363 }
364 WaterClass wc_upper = IsWaterTile(tile + delta) ? GetWaterClass(tile + delta) : WaterClass::Canal;
365
366 for (LockPart lock_part = LockPart::Middle; TileIndex t : {tile, tile - delta, tile + delta}) {
367 if (IsBridgeAbove(t) && GetBridgeHeight(GetSouthernBridgeEnd(t)) < GetTileMaxZ(t) + GetLockPartMinimalBridgeHeight(lock_part)) {
368 int height_diff = (GetTileMaxZ(tile) + GetLockPartMinimalBridgeHeight(lock_part) - GetBridgeHeight(GetSouthernBridgeEnd(t))) * TILE_HEIGHT_STEP;
369 return CommandCostWithParam(STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK, height_diff);
370 }
371 ++lock_part;
372 }
373
374 if (flags.Test(DoCommandFlag::Execute)) {
375 /* Update company infrastructure counts. */
376 Company *c = Company::GetIfValid(_current_company);
377 if (c != nullptr) {
378 /* Counts for the water. */
379 if (!IsWaterTile(tile - delta)) c->infrastructure.water++;
380 if (!IsWaterTile(tile + delta)) c->infrastructure.water++;
381 /* Count for the lock itself. */
382 c->infrastructure.water += 3 * LOCK_DEPOT_TILE_FACTOR; // Lock is three tiles.
383 DirtyCompanyInfrastructureWindows(_current_company);
384 }
385
386 MakeLock(tile, _current_company, dir, wc_lower, wc_upper, wc_middle);
387 CheckForDockingTile(tile - delta);
388 CheckForDockingTile(tile + delta);
389 MarkTileDirtyByTile(tile);
390 MarkTileDirtyByTile(tile - delta);
391 MarkTileDirtyByTile(tile + delta);
392 MarkCanalsAndRiversAroundDirty(tile - delta);
393 MarkCanalsAndRiversAroundDirty(tile + delta);
394 InvalidateWaterRegion(tile - delta);
395 InvalidateWaterRegion(tile + delta);
396 }
397 cost.AddCost(_price[PR_BUILD_LOCK]);
398
399 return cost;
400}
401
408 static CommandCost RemoveLock(TileIndex tile, DoCommandFlags flags)
409{
410 if (GetTileOwner(tile) != OWNER_NONE) {
411 CommandCost ret = CheckTileOwnership(tile);
412 if (ret.Failed()) return ret;
413 }
414
415 TileIndexDiff delta = TileOffsByDiagDir(GetLockDirection(tile));
416
417 /* make sure no vehicle is on the tile. */
418 CommandCost ret = EnsureNoVehicleOnGround(tile);
419 if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile + delta);
420 if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile - delta);
421 if (ret.Failed()) return ret;
422
423 if (flags.Test(DoCommandFlag::Execute)) {
424 /* Remove middle part from company infrastructure count. */
425 Company *c = Company::GetIfValid(GetTileOwner(tile));
426 if (c != nullptr) {
427 c->infrastructure.water -= 3 * LOCK_DEPOT_TILE_FACTOR; // three parts of the lock.
428 DirtyCompanyInfrastructureWindows(c->index);
429 }
430
431 if (GetWaterClass(tile) == WaterClass::River) {
432 MakeRiver(tile, Random());
433 } else {
434 DoClearSquare(tile);
435 ClearNeighbourNonFloodingStates(tile);
436 }
437 MakeWaterKeepingClass(tile + delta, GetTileOwner(tile + delta));
438 MakeWaterKeepingClass(tile - delta, GetTileOwner(tile - delta));
439 MarkCanalsAndRiversAroundDirty(tile);
440 MarkCanalsAndRiversAroundDirty(tile - delta);
441 MarkCanalsAndRiversAroundDirty(tile + delta);
442 }
443
444 return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_LOCK]);
445}
446
453 CommandCost CmdBuildLock(DoCommandFlags flags, TileIndex tile)
454{
455 DiagDirection dir = GetInclinedSlopeDirection(GetTileSlope(tile));
456 if (dir == INVALID_DIAGDIR) return CommandCost(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
457
458 TileIndex lower_tile = TileAddByDiagDir(tile, ReverseDiagDir(dir));
459
460 /* If freeform edges are disabled, don't allow building on edge tiles. */
461 if (!_settings_game.construction.freeform_edges && (!IsInsideMM(TileX(lower_tile), 1, Map::MaxX() - 1) || !IsInsideMM(TileY(lower_tile), 1, Map::MaxY() - 1))) {
462 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP);
463 }
464
465 return DoBuildLock(tile, dir, flags);
466}
467
472 void MakeRiverAndModifyDesertZoneAround(TileIndex tile)
473{
474 MakeRiver(tile, Random());
475 MarkTileDirtyByTile(tile);
476
477 /* Remove desert directly around the river tile. */
478 for (auto t : SpiralTileSequence(tile, RIVER_OFFSET_DESERT_DISTANCE)) {
479 if (GetTropicZone(t) == TROPICZONE_DESERT) SetTropicZone(t, TROPICZONE_NORMAL);
480 }
481}
482
492 CommandCost CmdBuildCanal(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal)
493{
494 if (start_tile >= Map::Size() || !IsValidWaterClass(wc)) return CMD_ERROR;
495
496 /* Outside of the editor you can only build canals, not oceans */
497 if (wc != WaterClass::Canal && _game_mode != GM_EDITOR) return CMD_ERROR;
498
499 CommandCost cost(EXPENSES_CONSTRUCTION);
500
501 std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
502 for (; *iter != INVALID_TILE; ++(*iter)) {
503 TileIndex current_tile = *iter;
504 CommandCost ret;
505
506 Slope slope = GetTileSlope(current_tile);
507 if (slope != SLOPE_FLAT && (wc != WaterClass::River || !IsInclinedSlope(slope))) {
508 return CommandCost(STR_ERROR_FLAT_LAND_REQUIRED);
509 }
510
511 bool water = IsWaterTile(current_tile);
512
513 /* Outside the editor, prevent building canals over your own or OWNER_NONE owned canals */
514 if (water && IsCanal(current_tile) && _game_mode != GM_EDITOR && (IsTileOwner(current_tile, _current_company) || IsTileOwner(current_tile, OWNER_NONE))) continue;
515
516 ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
517 if (ret.Failed()) return ret;
518
519 if (!water) cost.AddCost(ret.GetCost());
520
521 if (flags.Test(DoCommandFlag::Execute)) {
522 if (IsTileType(current_tile, MP_WATER) && IsCanal(current_tile)) {
523 Owner owner = GetTileOwner(current_tile);
524 if (Company::IsValidID(owner)) {
525 Company::Get(owner)->infrastructure.water--;
526 DirtyCompanyInfrastructureWindows(owner);
527 }
528 }
529
530 switch (wc) {
531 case WaterClass::River:
532 MakeRiver(current_tile, Random());
533 if (_game_mode == GM_EDITOR) {
534 /* Remove desert directly around the river tile. */
535 for (auto t : SpiralTileSequence(current_tile, RIVER_OFFSET_DESERT_DISTANCE)) {
536 if (GetTropicZone(t) == TROPICZONE_DESERT) SetTropicZone(t, TROPICZONE_NORMAL);
537 }
538 }
539 break;
540
541 case WaterClass::Sea:
542 if (TileHeight(current_tile) == 0) {
543 MakeSea(current_tile);
544 break;
545 }
546 [[fallthrough]];
547
548 default:
549 MakeCanal(current_tile, _current_company, Random());
550 if (Company::IsValidID(_current_company)) {
551 Company::Get(_current_company)->infrastructure.water++;
552 DirtyCompanyInfrastructureWindows(_current_company);
553 }
554 break;
555 }
556 MarkTileDirtyByTile(current_tile);
557 MarkCanalsAndRiversAroundDirty(current_tile);
558 CheckForDockingTile(current_tile);
559 }
560
561 cost.AddCost(_price[PR_BUILD_CANAL]);
562 }
563
564 if (cost.GetCost() == 0) {
565 return CommandCost(STR_ERROR_ALREADY_BUILT);
566 } else {
567 return cost;
568 }
569}
570
571
572static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlags flags)
573{
574 switch (GetWaterTileType(tile)) {
575 case WaterTileType::Clear: {
576 if (flags.Test(DoCommandFlag::NoWater)) return CommandCost(STR_ERROR_CAN_T_BUILD_ON_WATER);
577
578 Money base_cost = IsCanal(tile) ? _price[PR_CLEAR_CANAL] : _price[PR_CLEAR_WATER];
579 /* Make sure freeform edges are allowed or it's not an edge tile. */
580 if (!_settings_game.construction.freeform_edges && (!IsInsideMM(TileX(tile), 1, Map::MaxX() - 1) ||
581 !IsInsideMM(TileY(tile), 1, Map::MaxY() - 1))) {
582 return CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP);
583 }
584
585 /* Make sure no vehicle is on the tile */
586 CommandCost ret = EnsureNoVehicleOnGround(tile);
587 if (ret.Failed()) return ret;
588
589 Owner owner = GetTileOwner(tile);
590 if (owner != OWNER_WATER && owner != OWNER_NONE) {
591 ret = CheckTileOwnership(tile);
592 if (ret.Failed()) return ret;
593 }
594
595 if (flags.Test(DoCommandFlag::Execute)) {
596 if (IsCanal(tile) && Company::IsValidID(owner)) {
597 Company::Get(owner)->infrastructure.water--;
598 DirtyCompanyInfrastructureWindows(owner);
599 }
600 DoClearSquare(tile);
601 MarkCanalsAndRiversAroundDirty(tile);
602 ClearNeighbourNonFloodingStates(tile);
603 }
604
605 return CommandCost(EXPENSES_CONSTRUCTION, base_cost);
606 }
607
608 case WaterTileType::Coast: {
609 Slope slope = GetTileSlope(tile);
610
611 /* Make sure no vehicle is on the tile */
612 CommandCost ret = EnsureNoVehicleOnGround(tile);
613 if (ret.Failed()) return ret;
614
615 if (flags.Test(DoCommandFlag::Execute)) {
616 DoClearSquare(tile);
617 MarkCanalsAndRiversAroundDirty(tile);
618 ClearNeighbourNonFloodingStates(tile);
619 }
620 if (IsSlopeWithOneCornerRaised(slope)) {
621 return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_WATER]);
622 } else {
623 return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_ROUGH]);
624 }
625 }
626
627 case WaterTileType::Lock: {
628 static const TileIndexDiffC _lock_tomiddle_offs[to_underlying(LockPart::End)][DIAGDIR_END] = {
629 /* NE SE SW NW */
630 { { 0, 0}, {0, 0}, { 0, 0}, {0, 0} }, // LockPart::Middle
631 { {-1, 0}, {0, 1}, { 1, 0}, {0, -1} }, // LockPart::Lower
632 { { 1, 0}, {0, -1}, {-1, 0}, {0, 1} }, // LockPart::Upper
633 };
634
635 if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
636 if (_current_company == OWNER_WATER) return CMD_ERROR;
637 /* move to the middle tile.. */
638 return RemoveLock(tile + ToTileIndexDiff(_lock_tomiddle_offs[to_underlying(GetLockPart(tile))][GetLockDirection(tile)]), flags);
639 }
640
641 case WaterTileType::Depot:
642 if (flags.Test(DoCommandFlag::Auto)) return CommandCost(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
643 return RemoveShipDepot(tile, flags);
644
645 default:
646 NOT_REACHED();
647 }
648}
649
658 bool IsWateredTile(TileIndex tile, Direction from)
659{
660 switch (GetTileType(tile)) {
661 case MP_WATER:
662 switch (GetWaterTileType(tile)) {
663 default: NOT_REACHED();
664 case WaterTileType::Depot: case WaterTileType::Clear: return true;
665 case WaterTileType::Lock: return DiagDirToAxis(GetLockDirection(tile)) == DiagDirToAxis(DirToDiagDir(from));
666
667 case WaterTileType::Coast:
668 switch (GetTileSlope(tile)) {
669 case SLOPE_W: return (from == DIR_SE) || (from == DIR_E) || (from == DIR_NE);
670 case SLOPE_S: return (from == DIR_NE) || (from == DIR_N) || (from == DIR_NW);
671 case SLOPE_E: return (from == DIR_NW) || (from == DIR_W) || (from == DIR_SW);
672 case SLOPE_N: return (from == DIR_SW) || (from == DIR_S) || (from == DIR_SE);
673 default: return false;
674 }
675 }
676
677 case MP_RAILWAY:
678 if (GetRailGroundType(tile) == RailGroundType::HalfTileWater) {
679 assert(IsPlainRail(tile));
680 switch (GetTileSlope(tile)) {
681 case SLOPE_W: return (from == DIR_SE) || (from == DIR_E) || (from == DIR_NE);
682 case SLOPE_S: return (from == DIR_NE) || (from == DIR_N) || (from == DIR_NW);
683 case SLOPE_E: return (from == DIR_NW) || (from == DIR_W) || (from == DIR_SW);
684 case SLOPE_N: return (from == DIR_SW) || (from == DIR_S) || (from == DIR_SE);
685 default: return false;
686 }
687 }
688 return false;
689
690 case MP_STATION:
691 if (IsOilRig(tile)) {
692 /* Do not draw waterborders inside of industries.
693 * Note: There is no easy way to detect the industry of an oilrig tile. */
694 TileIndex src_tile = tile + TileOffsByDir(from);
695 if ((IsTileType(src_tile, MP_STATION) && IsOilRig(src_tile)) ||
696 (IsTileType(src_tile, MP_INDUSTRY))) return true;
697
698 return IsTileOnWater(tile);
699 }
700 return (IsDock(tile) && IsTileFlat(tile)) || IsBuoy(tile);
701
702 case MP_INDUSTRY: {
703 /* Do not draw waterborders inside of industries.
704 * Note: There is no easy way to detect the industry of an oilrig tile. */
705 TileIndex src_tile = tile + TileOffsByDir(from);
706 if ((IsTileType(src_tile, MP_STATION) && IsOilRig(src_tile)) ||
707 (IsTileType(src_tile, MP_INDUSTRY) && GetIndustryIndex(src_tile) == GetIndustryIndex(tile))) return true;
708
709 return IsTileOnWater(tile);
710 }
711
712 case MP_OBJECT: return IsTileOnWater(tile);
713
714 case MP_TUNNELBRIDGE: return GetTunnelBridgeTransportType(tile) == TRANSPORT_WATER && ReverseDiagDir(GetTunnelBridgeDirection(tile)) == DirToDiagDir(from);
715
716 case MP_VOID: return true; // consider map border as water, esp. for rivers
717
718 default: return false;
719 }
720}
721
729 static void DrawWaterSprite(SpriteID base, uint offset, CanalFeature feature, TileIndex tile)
730{
731 if (base != SPR_FLAT_WATER_TILE) {
732 /* Only call offset callback if the sprite is NewGRF-provided. */
733 offset = GetCanalSpriteOffset(feature, tile, offset);
734 }
735 DrawGroundSprite(base + offset, PAL_NONE);
736}
737
744 static void DrawWaterEdges(bool canal, uint offset, TileIndex tile)
745{
746 CanalFeature feature;
747 SpriteID base = 0;
748 if (canal) {
749 feature = CF_DIKES;
750 base = GetCanalSprite(CF_DIKES, tile);
751 if (base == 0) base = SPR_CANAL_DIKES_BASE;
752 } else {
753 feature = CF_RIVER_EDGE;
754 base = GetCanalSprite(CF_RIVER_EDGE, tile);
755 if (base == 0) return; // Don't draw if no sprites provided.
756 }
757
758 uint wa;
759
760 /* determine the edges around with water. */
761 wa = IsWateredTile(TileAddXY(tile, -1, 0), DIR_SW) << 0;
762 wa += IsWateredTile(TileAddXY(tile, 0, 1), DIR_NW) << 1;
763 wa += IsWateredTile(TileAddXY(tile, 1, 0), DIR_NE) << 2;
764 wa += IsWateredTile(TileAddXY(tile, 0, -1), DIR_SE) << 3;
765
766 if (!(wa & 1)) DrawWaterSprite(base, offset, feature, tile);
767 if (!(wa & 2)) DrawWaterSprite(base, offset + 1, feature, tile);
768 if (!(wa & 4)) DrawWaterSprite(base, offset + 2, feature, tile);
769 if (!(wa & 8)) DrawWaterSprite(base, offset + 3, feature, tile);
770
771 /* right corner */
772 switch (wa & 0x03) {
773 case 0: DrawWaterSprite(base, offset + 4, feature, tile); break;
774 case 3: if (!IsWateredTile(TileAddXY(tile, -1, 1), DIR_W)) DrawWaterSprite(base, offset + 8, feature, tile); break;
775 }
776
777 /* bottom corner */
778 switch (wa & 0x06) {
779 case 0: DrawWaterSprite(base, offset + 5, feature, tile); break;
780 case 6: if (!IsWateredTile(TileAddXY(tile, 1, 1), DIR_N)) DrawWaterSprite(base, offset + 9, feature, tile); break;
781 }
782
783 /* left corner */
784 switch (wa & 0x0C) {
785 case 0: DrawWaterSprite(base, offset + 6, feature, tile); break;
786 case 12: if (!IsWateredTile(TileAddXY(tile, 1, -1), DIR_E)) DrawWaterSprite(base, offset + 10, feature, tile); break;
787 }
788
789 /* upper corner */
790 switch (wa & 0x09) {
791 case 0: DrawWaterSprite(base, offset + 7, feature, tile); break;
792 case 9: if (!IsWateredTile(TileAddXY(tile, -1, -1), DIR_S)) DrawWaterSprite(base, offset + 11, feature, tile); break;
793 }
794}
795
797 static void DrawSeaWater(TileIndex)
798{
799 DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
800}
801
803 static void DrawCanalWater(TileIndex tile)
804{
805 SpriteID image = SPR_FLAT_WATER_TILE;
806 if (HasBit(_water_feature[CF_WATERSLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
807 /* First water slope sprite is flat water. */
808 image = GetCanalSprite(CF_WATERSLOPE, tile);
809 if (image == 0) image = SPR_FLAT_WATER_TILE;
810 }
811 DrawWaterSprite(image, 0, CF_WATERSLOPE, tile);
812
813 DrawWaterEdges(true, 0, tile);
814}
815
816#include "table/water_land.h"
817
827 static void DrawWaterTileStruct(const TileInfo *ti, std::span<const DrawTileSeqStruct> seq, SpriteID base, uint offset, PaletteID palette, CanalFeature feature)
828{
829 /* Don't draw if buildings are invisible. */
830 if (IsInvisibilitySet(TO_BUILDINGS)) return;
831
832 for (const DrawTileSeqStruct &dtss : seq) {
833 uint tile_offs = offset + dtss.image.sprite;
834 if (feature < CF_END) tile_offs = GetCanalSpriteOffset(feature, ti->tile, tile_offs);
835 AddSortableSpriteToDraw(base + tile_offs, palette, *ti, dtss, IsTransparencySet(TO_BUILDINGS));
836 }
837}
838
840 static void DrawWaterLock(const TileInfo *ti)
841{
842 LockPart part = GetLockPart(ti->tile);
843 const DrawTileSprites &dts = _lock_display_data[to_underlying(part)][GetLockDirection(ti->tile)];
844
845 /* Draw ground sprite. */
846 SpriteID image = dts.ground.sprite;
847
848 SpriteID water_base = GetCanalSprite(CF_WATERSLOPE, ti->tile);
849 if (water_base == 0) {
850 /* Use default sprites. */
851 water_base = SPR_CANALS_BASE;
852 } else if (HasBit(_water_feature[CF_WATERSLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
853 /* NewGRF supplies a flat sprite as first sprite. */
854 if (image == SPR_FLAT_WATER_TILE) {
855 image = water_base;
856 } else {
857 image++;
858 }
859 }
860
861 if (image < 5) image += water_base;
862 DrawGroundSprite(image, PAL_NONE);
863
864 /* Draw structures. */
865 uint zoffs = 0;
866 SpriteID base = GetCanalSprite(CF_LOCKS, ti->tile);
867
868 if (base == 0) {
869 /* If no custom graphics, use defaults. */
870 base = SPR_LOCK_BASE;
871 uint8_t z_threshold = part == LockPart::Upper ? 8 : 0;
872 zoffs = ti->z > z_threshold ? 24 : 0;
873 }
874
875 DrawWaterTileStruct(ti, dts.GetSequence(), base, zoffs, PAL_NONE, CF_LOCKS);
876}
877
879 static void DrawWaterDepot(const TileInfo *ti)
880{
881 DrawWaterClassGround(ti);
882 DrawWaterTileStruct(ti, _shipdepot_display_data[GetShipDepotAxis(ti->tile)][to_underlying(GetShipDepotPart(ti->tile))].seq, 0, 0, GetCompanyPalette(GetTileOwner(ti->tile)), CF_END);
883}
884
885static void DrawRiverWater(const TileInfo *ti)
886{
887 SpriteID image = SPR_FLAT_WATER_TILE;
888 uint offset = 0;
889 uint edges_offset = 0;
890
891 if (ti->tileh != SLOPE_FLAT || HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
892 image = GetCanalSprite(CF_RIVER_SLOPE, ti->tile);
893 if (image == 0) {
894 switch (ti->tileh) {
895 case SLOPE_NW: image = SPR_WATER_SLOPE_Y_DOWN; break;
896 case SLOPE_SW: image = SPR_WATER_SLOPE_X_UP; break;
897 case SLOPE_SE: image = SPR_WATER_SLOPE_Y_UP; break;
898 case SLOPE_NE: image = SPR_WATER_SLOPE_X_DOWN; break;
899 default: image = SPR_FLAT_WATER_TILE; break;
900 }
901 } else {
902 /* Flag bit 0 indicates that the first sprite is flat water. */
903 offset = HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE) ? 1 : 0;
904
905 switch (ti->tileh) {
906 case SLOPE_SE: edges_offset += 12; break;
907 case SLOPE_NE: offset += 1; edges_offset += 24; break;
908 case SLOPE_SW: offset += 2; edges_offset += 36; break;
909 case SLOPE_NW: offset += 3; edges_offset += 48; break;
910 default: offset = 0; break;
911 }
912
913 offset = GetCanalSpriteOffset(CF_RIVER_SLOPE, ti->tile, offset);
914 }
915 }
916
917 DrawGroundSprite(image + offset, PAL_NONE);
918
919 /* Draw river edges if available. */
920 DrawWaterEdges(false, edges_offset, ti->tile);
921}
922
923void DrawShoreTile(Slope tileh)
924{
925 /* Converts the enum Slope into an offset based on SPR_SHORE_BASE.
926 * This allows to calculate the proper sprite to display for this Slope */
927 static const uint8_t tileh_to_shoresprite[32] = {
928 0, 1, 2, 3, 4, 16, 6, 7, 8, 9, 17, 11, 12, 13, 14, 0,
929 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 10, 15, 0,
930 };
931
932 assert(!IsHalftileSlope(tileh)); // Halftile slopes need to get handled earlier.
933 assert(tileh != SLOPE_FLAT); // Shore is never flat
934
935 assert((tileh != SLOPE_EW) && (tileh != SLOPE_NS)); // No suitable sprites for current flooding behaviour
936
937 DrawGroundSprite(SPR_SHORE_BASE + tileh_to_shoresprite[tileh], PAL_NONE);
938}
939
940void DrawWaterClassGround(const TileInfo *ti)
941{
942 switch (GetWaterClass(ti->tile)) {
943 case WaterClass::Sea: DrawSeaWater(ti->tile); break;
944 case WaterClass::Canal: DrawCanalWater(ti->tile); break;
945 case WaterClass::River: DrawRiverWater(ti); break;
946 default: NOT_REACHED();
947 }
948}
949
950static void DrawTile_Water(TileInfo *ti)
951{
952 switch (GetWaterTileType(ti->tile)) {
953 case WaterTileType::Clear:
954 DrawWaterClassGround(ti);
955 /* A plain water tile can be traversed in any direction, so setting blocked pillars here would mean all bridges
956 * with edges would have no pillars above water. Instead prefer current behaviour of ships passing through. */
957 DrawBridgeMiddle(ti, {});
958 break;
959
960 case WaterTileType::Coast: {
961 DrawShoreTile(ti->tileh);
962 DrawBridgeMiddle(ti, {});
963 break;
964 }
965
966 case WaterTileType::Lock:
967 DrawWaterLock(ti);
968 DrawBridgeMiddle(ti, DiagDirToAxis(GetLockDirection(ti->tile)) == AXIS_X
969 ? BridgePillarFlags{BridgePillarFlag::EdgeNE, BridgePillarFlag::EdgeSW}
970 : BridgePillarFlags{BridgePillarFlag::EdgeNW, BridgePillarFlag::EdgeSE});
971 break;
972
973 case WaterTileType::Depot:
974 DrawWaterDepot(ti);
975 break;
976 }
977}
978
979void DrawShipDepotSprite(int x, int y, Axis axis, DepotPart part)
980{
981 const DrawTileSprites &dts = _shipdepot_display_data[axis][to_underlying(part)];
982
983 DrawSprite(dts.ground.sprite, dts.ground.pal, x, y);
984 DrawOrigTileSeqInGUI(x, y, &dts, GetCompanyPalette(_local_company));
985}
986
987
988static int GetSlopePixelZ_Water(TileIndex tile, uint x, uint y, bool)
989{
990 auto [tileh, z] = GetTilePixelSlope(tile);
991
992 return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
993}
994
995static Foundation GetFoundation_Water(TileIndex, Slope)
996{
997 return FOUNDATION_NONE;
998}
999
1000static void GetTileDesc_Water(TileIndex tile, TileDesc &td)
1001{
1002 switch (GetWaterTileType(tile)) {
1003 case WaterTileType::Clear:
1004 switch (GetWaterClass(tile)) {
1005 case WaterClass::Sea: td.str = STR_LAI_WATER_DESCRIPTION_WATER; break;
1006 case WaterClass::Canal: td.str = STR_LAI_WATER_DESCRIPTION_CANAL; break;
1007 case WaterClass::River: td.str = STR_LAI_WATER_DESCRIPTION_RIVER; break;
1008 default: NOT_REACHED();
1009 }
1010 break;
1011 case WaterTileType::Coast: td.str = STR_LAI_WATER_DESCRIPTION_COAST_OR_RIVERBANK; break;
1012 case WaterTileType::Lock : td.str = STR_LAI_WATER_DESCRIPTION_LOCK; break;
1013 case WaterTileType::Depot:
1014 td.str = STR_LAI_WATER_DESCRIPTION_SHIP_DEPOT;
1015 td.build_date = Depot::GetByTile(tile)->build_date;
1016 break;
1017 default: NOT_REACHED();
1018 }
1019
1020 td.owner[0] = GetTileOwner(tile);
1021}
1022
1028 static void FloodVehicle(Vehicle *v)
1029{
1030 uint victims = v->Crash(true);
1031
1032 AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED, victims, v->owner));
1033 Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED, victims, v->owner));
1034 AddTileNewsItem(GetEncodedString(STR_NEWS_DISASTER_FLOOD_VEHICLE, victims), NewsType::Accident, v->tile);
1035 CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
1036 if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
1037}
1038
1044 static void FloodVehicleProc(Vehicle *v, int z)
1045{
1046 if (v->vehstatus.Test(VehState::Crashed)) return;
1047
1048 switch (v->type) {
1049 default: break;
1050
1051 case VEH_AIRCRAFT: {
1052 if (!IsAirportTile(v->tile) || GetTileMaxZ(v->tile) != 0) break;
1053 if (v->subtype == AIR_SHADOW) break;
1054
1055 /* We compare v->z_pos against delta_z + 1 because the shadow
1056 * is at delta_z and the actual aircraft at delta_z + 1. */
1057 const Station *st = Station::GetByTile(v->tile);
1058 const AirportFTAClass *airport = st->airport.GetFTA();
1059 if (v->z_pos != airport->delta_z + 1) break;
1060
1061 FloodVehicle(v);
1062 break;
1063 }
1064
1065 case VEH_TRAIN:
1066 case VEH_ROAD: {
1067 if (v->z_pos > z) break;
1068 FloodVehicle(v->First());
1069 break;
1070 }
1071 }
1072}
1073
1074static void FloodVehiclesOnTile(TileIndex tile, int z)
1075{
1076 for (Vehicle *v : VehiclesOnTile(tile)) {
1077 FloodVehicleProc(v, z);
1078 }
1079}
1080
1086 static void FloodVehicles(TileIndex tile)
1087{
1088 if (IsAirportTile(tile)) {
1089 const Station *st = Station::GetByTile(tile);
1090 for (TileIndex airport_tile : st->airport) {
1091 if (st->TileBelongsToAirport(airport_tile)) FloodVehiclesOnTile(airport_tile, 0);
1092 }
1093
1094 /* No vehicle could be flooded on this airport anymore */
1095 return;
1096 }
1097
1098 if (!IsBridgeTile(tile)) {
1099 FloodVehiclesOnTile(tile, 0);
1100 return;
1101 }
1102
1103 TileIndex end = GetOtherBridgeEnd(tile);
1104 int z = GetBridgePixelHeight(tile);
1105
1106 FloodVehiclesOnTile(tile, z);
1107 FloodVehiclesOnTile(end, z);
1108}
1109
1115 FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
1116{
1117 /* FLOOD_ACTIVE: 'single-corner-raised'-coast, sea, sea-shipdepots, sea-buoys, sea-docks (water part), rail with flooded halftile, sea-water-industries, sea-oilrigs
1118 * FLOOD_DRYUP: coast with more than one corner raised, coast with rail-track, coast with trees
1119 * FLOOD_PASSIVE: (not used)
1120 * FLOOD_NONE: canals, rivers, everything else
1121 */
1122 switch (GetTileType(tile)) {
1123 case MP_WATER:
1124 if (IsCoast(tile)) {
1125 Slope tileh = GetTileSlope(tile);
1126 return (IsSlopeWithOneCornerRaised(tileh) ? FLOOD_ACTIVE : FLOOD_DRYUP);
1127 }
1128 [[fallthrough]];
1129 case MP_STATION:
1130 case MP_INDUSTRY:
1131 case MP_OBJECT:
1132 return (GetWaterClass(tile) == WaterClass::Sea) ? FLOOD_ACTIVE : FLOOD_NONE;
1133
1134 case MP_RAILWAY:
1135 if (GetRailGroundType(tile) == RailGroundType::HalfTileWater) {
1136 return (IsSlopeWithOneCornerRaised(GetTileSlope(tile)) ? FLOOD_ACTIVE : FLOOD_DRYUP);
1137 }
1138 return FLOOD_NONE;
1139
1140 case MP_TREES:
1141 return (GetTreeGround(tile) == TREE_GROUND_SHORE ? FLOOD_DRYUP : FLOOD_NONE);
1142
1143 case MP_VOID:
1144 return FLOOD_ACTIVE;
1145
1146 default:
1147 return FLOOD_NONE;
1148 }
1149}
1150
1154 static void DoFloodTile(TileIndex target)
1155{
1156 assert(!IsTileType(target, MP_WATER));
1157
1158 bool flooded = false; // Will be set to true if something is changed.
1159
1160 Backup<CompanyID> cur_company(_current_company, OWNER_WATER);
1161
1162 Slope tileh = GetTileSlope(target);
1163 if (tileh != SLOPE_FLAT) {
1164 /* make coast.. */
1165 switch (GetTileType(target)) {
1166 case MP_RAILWAY: {
1167 if (!IsPlainRail(target)) break;
1168 FloodVehicles(target);
1169 flooded = FloodHalftile(target);
1170 break;
1171 }
1172
1173 case MP_TREES:
1174 if (!IsSlopeWithOneCornerRaised(tileh)) {
1175 SetTreeGroundDensity(target, TREE_GROUND_SHORE, 3);
1176 MarkTileDirtyByTile(target);
1177 flooded = true;
1178 break;
1179 }
1180 [[fallthrough]];
1181
1182 case MP_CLEAR:
1183 if (Command<CMD_LANDSCAPE_CLEAR>::Do(DoCommandFlag::Execute, target).Succeeded()) {
1184 MakeShore(target);
1185 MarkTileDirtyByTile(target);
1186 flooded = true;
1187 }
1188 break;
1189
1190 default:
1191 break;
1192 }
1193 } else {
1194 /* Flood vehicles */
1195 FloodVehicles(target);
1196
1197 /* flood flat tile */
1198 if (Command<CMD_LANDSCAPE_CLEAR>::Do(DoCommandFlag::Execute, target).Succeeded()) {
1199 MakeSea(target);
1200 MarkTileDirtyByTile(target);
1201 flooded = true;
1202 }
1203 }
1204
1205 if (flooded) {
1206 /* Mark surrounding canal tiles dirty too to avoid glitches */
1207 MarkCanalsAndRiversAroundDirty(target);
1208
1209 /* update signals if needed */
1210 UpdateSignalsInBuffer();
1211
1212 if (IsPossibleDockingTile(target)) CheckForDockingTile(target);
1213 InvalidateWaterRegion(target);
1214 }
1215
1216 cur_company.Restore();
1217}
1218
1222 static void DoDryUp(TileIndex tile)
1223{
1224 Backup<CompanyID> cur_company(_current_company, OWNER_WATER);
1225
1226 switch (GetTileType(tile)) {
1227 case MP_RAILWAY:
1228 assert(IsPlainRail(tile));
1229 assert(GetRailGroundType(tile) == RailGroundType::HalfTileWater);
1230
1231 RailGroundType new_ground;
1232 switch (GetTrackBits(tile)) {
1233 case TRACK_BIT_UPPER: new_ground = RailGroundType::FenceHoriz1; break;
1234 case TRACK_BIT_LOWER: new_ground = RailGroundType::FenceHoriz2; break;
1235 case TRACK_BIT_LEFT: new_ground = RailGroundType::FenceVert1; break;
1236 case TRACK_BIT_RIGHT: new_ground = RailGroundType::FenceVert2; break;
1237 default: NOT_REACHED();
1238 }
1239 SetRailGroundType(tile, new_ground);
1240 MarkTileDirtyByTile(tile);
1241 break;
1242
1243 case MP_TREES:
1244 SetTreeGroundDensity(tile, TREE_GROUND_GRASS, 3);
1245 MarkTileDirtyByTile(tile);
1246 break;
1247
1248 case MP_WATER:
1249 assert(IsCoast(tile));
1250
1251 if (Command<CMD_LANDSCAPE_CLEAR>::Do(DoCommandFlag::Execute, tile).Succeeded()) {
1252 MakeClear(tile, CLEAR_GRASS, 3);
1253 MarkTileDirtyByTile(tile);
1254 }
1255 break;
1256
1257 default: NOT_REACHED();
1258 }
1259
1260 cur_company.Restore();
1261}
1262
1269 void TileLoop_Water(TileIndex tile)
1270{
1271 if (IsTileType(tile, MP_WATER)) {
1272 AmbientSoundEffect(tile);
1273 if (IsNonFloodingWaterTile(tile)) return;
1274 }
1275
1276 switch (GetFloodingBehaviour(tile)) {
1277 case FLOOD_ACTIVE: {
1278 bool continue_flooding = false;
1279 for (Direction dir = DIR_BEGIN; dir < DIR_END; dir++) {
1280 TileIndex dest = AddTileIndexDiffCWrap(tile, TileIndexDiffCByDir(dir));
1281 /* Contrary to drying up, flooding does not consider MP_VOID tiles. */
1282 if (!IsValidTile(dest)) continue;
1283 /* do not try to flood water tiles - increases performance a lot */
1284 if (IsTileType(dest, MP_WATER)) continue;
1285
1286 /* Buoys and docks cannot be flooded, and when removed turn into flooding water. */
1287 if (IsTileType(dest, MP_STATION) && (IsBuoy(dest) || IsDock(dest))) continue;
1288
1289 /* This neighbour tile might be floodable later if the tile is cleared, so allow flooding to continue. */
1290 continue_flooding = true;
1291
1292 /* TREE_GROUND_SHORE is the sign of a previous flood. */
1293 if (IsTileType(dest, MP_TREES) && GetTreeGround(dest) == TREE_GROUND_SHORE) continue;
1294
1295 auto [slope_dest, z_dest] = GetFoundationSlope(dest);
1296 if (z_dest > 0) continue;
1297
1298 if (!_flood_from_dirs[slope_dest & ~SLOPE_HALFTILE_MASK & ~SLOPE_STEEP].Test(ReverseDir(dir))) continue;
1299
1300 DoFloodTile(dest);
1301 }
1302 if (!continue_flooding && IsTileType(tile, MP_WATER)) SetNonFloodingWaterTile(tile, true);
1303 break;
1304 }
1305
1306 case FLOOD_DRYUP: {
1307 Slope slope_here = std::get<0>(GetFoundationSlope(tile)) & ~SLOPE_HALFTILE_MASK & ~SLOPE_STEEP;
1308 for (Direction dir : _flood_from_dirs[slope_here]) {
1309 TileIndex dest = AddTileIndexDiffCWrap(tile, TileIndexDiffCByDir(dir));
1310 /* Contrary to flooding, drying up does consider MP_VOID tiles. */
1311 if (dest == INVALID_TILE) continue;
1312
1313 FloodingBehaviour dest_behaviour = GetFloodingBehaviour(dest);
1314 if ((dest_behaviour == FLOOD_ACTIVE) || (dest_behaviour == FLOOD_PASSIVE)) return;
1315 }
1316 DoDryUp(tile);
1317 break;
1318 }
1319
1320 default: return;
1321 }
1322}
1323
1324void ConvertGroundTilesIntoWaterTiles()
1325{
1326 for (const auto tile : Map::Iterate()) {
1327 auto [slope, z] = GetTileSlopeZ(tile);
1328 if (IsTileType(tile, MP_CLEAR) && z == 0) {
1329 /* Make both water for tiles at level 0
1330 * and make shore, as that looks much better
1331 * during the generation. */
1332 switch (slope) {
1333 case SLOPE_FLAT:
1334 MakeSea(tile);
1335 break;
1336
1337 case SLOPE_N:
1338 case SLOPE_E:
1339 case SLOPE_S:
1340 case SLOPE_W:
1341 MakeShore(tile);
1342 break;
1343
1344 default:
1345 for (Direction dir : _flood_from_dirs[slope & ~SLOPE_STEEP]) {
1346 TileIndex dest = TileAddByDir(tile, dir);
1347 Slope slope_dest = GetTileSlope(dest) & ~SLOPE_STEEP;
1348 if (slope_dest == SLOPE_FLAT || IsSlopeWithOneCornerRaised(slope_dest) || IsTileType(dest, MP_VOID)) {
1349 MakeShore(tile);
1350 break;
1351 }
1352 }
1353 break;
1354 }
1355 }
1356 }
1357}
1358
1359static TrackStatus GetTileTrackStatus_Water(TileIndex tile, TransportType mode, uint, DiagDirection)
1360{
1361 static const TrackBits coast_tracks[] = {TRACK_BIT_NONE, TRACK_BIT_RIGHT, TRACK_BIT_UPPER, TRACK_BIT_NONE, TRACK_BIT_LEFT, TRACK_BIT_NONE, TRACK_BIT_NONE,
1362 TRACK_BIT_NONE, TRACK_BIT_LOWER, TRACK_BIT_NONE, TRACK_BIT_NONE, TRACK_BIT_NONE, TRACK_BIT_NONE, TRACK_BIT_NONE, TRACK_BIT_NONE, TRACK_BIT_NONE};
1363
1364 TrackBits ts;
1365
1366 if (mode != TRANSPORT_WATER) return 0;
1367
1368 switch (GetWaterTileType(tile)) {
1369 case WaterTileType::Clear: ts = IsTileFlat(tile) ? TRACK_BIT_ALL : TRACK_BIT_NONE; break;
1370 case WaterTileType::Coast: ts = coast_tracks[GetTileSlope(tile) & 0xF]; break;
1371 case WaterTileType::Lock: ts = DiagDirToDiagTrackBits(GetLockDirection(tile)); break;
1372 case WaterTileType::Depot: ts = AxisToTrackBits(GetShipDepotAxis(tile)); break;
1373 default: return 0;
1374 }
1375 if (TileX(tile) == 0) {
1376 /* NE border: remove tracks that connects NE tile edge */
1377 ts &= ~(TRACK_BIT_X | TRACK_BIT_UPPER | TRACK_BIT_RIGHT);
1378 }
1379 if (TileY(tile) == 0) {
1380 /* NW border: remove tracks that connects NW tile edge */
1381 ts &= ~(TRACK_BIT_Y | TRACK_BIT_LEFT | TRACK_BIT_UPPER);
1382 }
1383 return CombineTrackStatus(TrackBitsToTrackdirBits(ts), TRACKDIR_BIT_NONE);
1384}
1385
1386static bool ClickTile_Water(TileIndex tile)
1387{
1388 if (GetWaterTileType(tile) == WaterTileType::Depot) {
1389 ShowDepotWindow(GetShipDepotNorthTile(tile), VEH_SHIP);
1390 return true;
1391 }
1392 return false;
1393}
1394
1395static void ChangeTileOwner_Water(TileIndex tile, Owner old_owner, Owner new_owner)
1396{
1397 if (!IsTileOwner(tile, old_owner)) return;
1398
1399 bool is_lock_middle = IsLock(tile) && GetLockPart(tile) == LockPart::Middle;
1400
1401 /* No need to dirty company windows here, we'll redraw the whole screen anyway. */
1402 if (is_lock_middle) Company::Get(old_owner)->infrastructure.water -= 3 * LOCK_DEPOT_TILE_FACTOR; // Lock has three parts.
1403 if (new_owner != INVALID_OWNER) {
1404 if (is_lock_middle) Company::Get(new_owner)->infrastructure.water += 3 * LOCK_DEPOT_TILE_FACTOR; // Lock has three parts.
1405 /* Only subtract from the old owner here if the new owner is valid,
1406 * otherwise we clear ship depots and canal water below. */
1407 if (GetWaterClass(tile) == WaterClass::Canal && !is_lock_middle) {
1408 Company::Get(old_owner)->infrastructure.water--;
1409 Company::Get(new_owner)->infrastructure.water++;
1410 }
1411 if (IsShipDepot(tile)) {
1412 Company::Get(old_owner)->infrastructure.water -= LOCK_DEPOT_TILE_FACTOR;
1413 Company::Get(new_owner)->infrastructure.water += LOCK_DEPOT_TILE_FACTOR;
1414 }
1415
1416 SetTileOwner(tile, new_owner);
1417 return;
1418 }
1419
1420 /* Remove depot */
1421 if (IsShipDepot(tile)) Command<CMD_LANDSCAPE_CLEAR>::Do({DoCommandFlag::Execute, DoCommandFlag::Bankrupt}, tile);
1422
1423 /* Set owner of canals and locks ... and also canal under dock there was before.
1424 * Check if the new owner after removing depot isn't OWNER_WATER. */
1425 if (IsTileOwner(tile, old_owner)) {
1426 if (GetWaterClass(tile) == WaterClass::Canal && !is_lock_middle) Company::Get(old_owner)->infrastructure.water--;
1427 SetTileOwner(tile, OWNER_NONE);
1428 }
1429}
1430
1431static VehicleEnterTileStates VehicleEnter_Water(Vehicle *, TileIndex, int, int)
1432{
1433 return {};
1434}
1435
1436static CommandCost TerraformTile_Water(TileIndex tile, DoCommandFlags flags, int, Slope)
1437{
1438 /* Canals can't be terraformed */
1439 if (IsWaterTile(tile) && IsCanal(tile)) return CommandCost(STR_ERROR_MUST_DEMOLISH_CANAL_FIRST);
1440
1441 return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
1442}
1443
1444static CommandCost CheckBuildAbove_Water(TileIndex tile, DoCommandFlags flags, Axis, int height)
1445{
1446 if (IsWater(tile) || IsCoast(tile)) return CommandCost();
1447 if (IsLock(tile)) {
1448 if (GetTileMaxZ(tile) + GetLockPartMinimalBridgeHeight(GetLockPart(tile)) <= height) return CommandCost();
1449 int height_diff = (GetTileMaxZ(tile) + GetLockPartMinimalBridgeHeight(GetLockPart(tile)) - height) * TILE_HEIGHT_STEP;
1450 return CommandCostWithParam(STR_ERROR_BRIDGE_TOO_LOW_FOR_LOCK, height_diff);
1451 }
1452 return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
1453}
1454
1455extern const TileTypeProcs _tile_type_water_procs = {
1456 DrawTile_Water, // draw_tile_proc
1457 GetSlopePixelZ_Water, // get_slope_z_proc
1458 ClearTile_Water, // clear_tile_proc
1459 nullptr, // add_accepted_cargo_proc
1460 GetTileDesc_Water, // get_tile_desc_proc
1461 GetTileTrackStatus_Water, // get_tile_track_status_proc
1462 ClickTile_Water, // click_tile_proc
1463 nullptr, // animate_tile_proc
1464 TileLoop_Water, // tile_loop_proc
1465 ChangeTileOwner_Water, // change_tile_owner_proc
1466 nullptr, // add_produced_cargo_proc
1467 VehicleEnter_Water, // vehicle_enter_tile_proc
1468 GetFoundation_Water, // get_foundation_proc
1469 TerraformTile_Water, // terraform_tile_proc
1470 CheckBuildAbove_Water, // check_build_above_proc
1471};
ai.hpp
Base functions for all AIs.
aircraft.h
Base for aircraft.
AIR_SHADOW
@ AIR_SHADOW
shadow of the aircraft
Definition aircraft.h:31
backup_type.hpp
Class for backupping variables and making sure they are restored later.
HasBit
constexpr bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
Definition bitmath_func.hpp:103
DrawBridgeMiddle
void DrawBridgeMiddle(const TileInfo *ti, BridgePillarFlags blocked_pillars)
Draw the middle bits of a bridge.
Definition tunnelbridge_cmd.cpp:1607
GetSouthernBridgeEnd
TileIndex GetSouthernBridgeEnd(TileIndex t)
Finds the southern end of a bridge starting at a middle tile.
Definition bridge_map.cpp:49
GetOtherBridgeEnd
TileIndex GetOtherBridgeEnd(TileIndex tile)
Starting at one bridge end finds the other bridge end.
Definition bridge_map.cpp:59
GetBridgeHeight
int GetBridgeHeight(TileIndex t)
Get the height ('z') of a bridge.
Definition bridge_map.cpp:70
IsBridgeTile
bool IsBridgeTile(Tile t)
checks if there is a bridge on this tile
Definition bridge_map.h:35
GetBridgePixelHeight
int GetBridgePixelHeight(TileIndex tile)
Get the height ('z') of a bridge in pixels.
Definition bridge_map.h:84
IsBridgeAbove
bool IsBridgeAbove(Tile t)
checks if a bridge is set above the ground of this tile
Definition bridge_map.h:45
BridgePillarFlag
BridgePillarFlag
Obstructed bridge pillars information.
Definition bridge_type.h:39
AI::NewEvent
static void NewEvent(CompanyID company, ScriptEvent *event)
Queue a new event for an AI.
Definition ai_core.cpp:235
BaseBitSet::Test
constexpr bool Test(Tvalue_type value) const
Test if the value-th bit is set.
Definition base_bitset_type.hpp:141
CommandCost
Common return value for all commands.
Definition command_type.h:24
CommandCost::Succeeded
bool Succeeded() const
Did this command succeed?
Definition command_type.h:168
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
Game::NewEvent
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition game_core.cpp:136
OverflowSafeInt< int64_t >
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
Tile
Wrapper class to abstract away the way the tiles are stored.
Definition map_func.h:25
VehiclesOnTile
Iterate over all vehicles on a tile.
Definition vehicle_func.h:53
clear_map.h
Map accessors for 'clear' tiles.
CLEAR_GRASS
@ CLEAR_GRASS
0-3
Definition clear_map.h:20
MakeClear
void MakeClear(Tile t, ClearGround g, uint density)
Make a clear tile.
Definition clear_map.h:247
CommandCostWithParam
CommandCost CommandCostWithParam(StringID str, uint64_t value)
Return an error status, with string and parameter.
Definition command.cpp:417
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
company_base.h
Definition of stuff that is very close to a company, like the company struct itself.
CheckTileOwnership
CommandCost CheckTileOwnership(TileIndex tile)
Check whether the current owner owns the stuff on the given tile.
Definition company_cmd.cpp:404
GetCompanyPalette
PaletteID GetCompanyPalette(CompanyID company)
Get the palette for recolouring with a company colour.
Definition company_cmd.cpp:164
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition company_cmd.cpp:55
_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.
OWNER_NONE
static constexpr Owner OWNER_NONE
The tile has no ownership.
Definition company_type.h:26
INVALID_OWNER
static constexpr Owner INVALID_OWNER
An invalid owner.
Definition company_type.h:30
OWNER_WATER
static constexpr Owner OWNER_WATER
The tile/execution is done by "water".
Definition company_type.h:27
depot_base.h
Base for all depots (except hangars)
depot_func.h
Functions related to depots.
ShowDepotWindow
void ShowDepotWindow(TileIndex tile, VehicleType type)
Opens a depot window.
Definition depot_gui.cpp:1183
IsValidAxis
bool IsValidAxis(Axis d)
Checks if an integer value is a valid Axis.
Definition direction_func.h:43
ReverseDiagDir
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
Definition direction_func.h:118
ReverseDir
Direction ReverseDir(Direction d)
Return the reverse of a direction.
Definition direction_func.h:54
DiagDirToAxis
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
Definition direction_func.h:214
DirToDiagDir
DiagDirection DirToDiagDir(Direction dir)
Convert a Direction to a DiagDirection.
Definition direction_func.h:166
Direction
Direction
Defines the 8 directions on the map.
Definition direction_type.h:24
DIR_BEGIN
@ DIR_BEGIN
Used to iterate.
Definition direction_type.h:25
DIR_SW
@ DIR_SW
Southwest.
Definition direction_type.h:31
DIR_NW
@ DIR_NW
Northwest.
Definition direction_type.h:33
DIR_N
@ DIR_N
North.
Definition direction_type.h:26
DIR_SE
@ DIR_SE
Southeast.
Definition direction_type.h:29
DIR_S
@ DIR_S
South.
Definition direction_type.h:30
DIR_NE
@ DIR_NE
Northeast.
Definition direction_type.h:27
DIR_END
@ DIR_END
Used to iterate.
Definition direction_type.h:34
DIR_W
@ DIR_W
West.
Definition direction_type.h:32
DIR_E
@ DIR_E
East.
Definition direction_type.h:28
Axis
Axis
Allow incrementing of DiagDirDiff variables.
Definition direction_type.h:123
AXIS_X
@ AXIS_X
The X axis.
Definition direction_type.h:124
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition direction_type.h:78
DIAGDIR_END
@ DIAGDIR_END
Used for iterations.
Definition direction_type.h:84
DIAGDIR_BEGIN
@ DIAGDIR_BEGIN
Used for iterations.
Definition direction_type.h:79
INVALID_DIAGDIR
@ INVALID_DIAGDIR
Flag for an invalid DiagDirection.
Definition direction_type.h:85
LOCK_DEPOT_TILE_FACTOR
static const uint LOCK_DEPOT_TILE_FACTOR
Multiplier for how many regular tiles a lock counts.
Definition economy_type.h:245
EXPENSES_CONSTRUCTION
@ EXPENSES_CONSTRUCTION
Construction costs.
Definition economy_type.h:179
CreateEffectVehicleRel
EffectVehicle * CreateEffectVehicleRel(const Vehicle *v, int x, int y, int z, EffectVehicleType type)
Create an effect vehicle above a particular vehicle.
Definition effectvehicle.cpp:610
effectvehicle_func.h
Functions related to effect vehicles.
EV_EXPLOSION_LARGE
@ EV_EXPLOSION_LARGE
Various explosions.
Definition effectvehicle_func.h:22
to_underlying
constexpr std::underlying_type_t< enum_type > to_underlying(enum_type e)
Implementation of std::to_underlying (from C++23)
Definition enum_type.hpp:17
game.hpp
Base functions for all Games.
DrawSprite
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
Draw a sprite, not in a viewport.
Definition gfx.cpp:1031
SpriteID
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition gfx_type.h:17
PaletteID
uint32_t PaletteID
The number of the palette.
Definition gfx_type.h:18
MarkCanalsAndRiversAroundDirty
static void MarkCanalsAndRiversAroundDirty(TileIndex tile)
Marks the tiles around a tile as dirty, if they are canals or rivers.
Definition water_cmd.cpp:86
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
industry.h
Base of all industries.
industry_map.h
Accessors for industries.
GetIndustryIndex
IndustryID GetIndustryIndex(Tile t)
Get the industry ID of the given tile.
Definition industry_map.h:63
GetPartialPixelZ
uint GetPartialPixelZ(int x, int y, Slope corners)
Determines height at given coordinate of a slope.
Definition landscape.cpp:231
GetTileTrackStatus
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
Definition landscape.cpp:559
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
landscape.h
Functions related to OTTD's landscape.
landscape_cmd.h
Command definitions related to landscape (slopes etc.).
BorderFlag::Random
@ Random
Randomise borders.
TileAddXY
TileIndex TileAddXY(TileIndex tile, int x, int y)
Adds a given offset to a tile.
Definition map_func.h:482
AddTileIndexDiffCWrap
TileIndex AddTileIndexDiffCWrap(TileIndex tile, TileIndexDiffC diff)
Add a TileIndexDiffC to a TileIndex and returns the new one.
Definition map_func.h:527
TileAddByDir
TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
Definition map_func.h:611
ToTileIndexDiff
TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between two tiles from a TileIndexDiffC struct.
Definition map_func.h:452
TileAddByDiagDir
TileIndex TileAddByDiagDir(TileIndex tile, DiagDirection dir)
Adds a DiagDir to a tile.
Definition map_func.h:623
TileOffsByAxis
TileIndexDiff TileOffsByAxis(Axis axis)
Convert an Axis to a TileIndexDiff.
Definition map_func.h:567
TileY
static uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition map_func.h:437
TileX
static uint TileX(TileIndex tile)
Get the X component of a tile.
Definition map_func.h:427
TileIndexDiffCByDir
TileIndexDiffC TileIndexDiffCByDir(Direction dir)
Returns the TileIndexDiffC offset from a Direction.
Definition map_func.h:509
TileOffsByDir
TileIndexDiff TileOffsByDir(Direction dir)
Convert a Direction to a TileIndexDiff.
Definition map_func.h:596
TileOffsByDiagDir
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition map_func.h:582
TileIndexDiff
int32_t TileIndexDiff
An offset value between two tiles.
Definition map_type.h:23
IsInsideMM
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition math_func.hpp:267
CanalFeature
CanalFeature
List of different canal 'features'.
Definition newgrf.h:25
GetCanalSpriteOffset
uint GetCanalSpriteOffset(CanalFeature feature, TileIndex tile, uint cur_offset)
Get the new sprite offset for a water tile.
Definition newgrf_canal.cpp:171
_water_feature
std::array< WaterFeature, CF_END > _water_feature
Table of canal 'feature' sprite groups.
Definition newgrf_canal.cpp:20
GetCanalSprite
SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile)
Lookup the base sprite to use for a canal.
Definition newgrf_canal.cpp:139
newgrf_canal.h
Handling of NewGRF canals.
CFF_HAS_FLAT_SPRITE
@ CFF_HAS_FLAT_SPRITE
Additional flat ground sprite in the beginning.
Definition newgrf_canal.h:19
newgrf_generic.h
Functions related to generic callbacks.
AmbientSoundEffect
void AmbientSoundEffect(TileIndex tile)
Play an ambient sound effect for an empty tile.
Definition newgrf_generic.h:54
news_func.h
Functions related to news.
NewsType::Accident
@ Accident
An accident or disaster has occurred.
FloodHalftile
bool FloodHalftile(TileIndex t)
Called from water_cmd if a non-flat rail-tile gets flooded and should be converted to shore.
Definition rail_cmd.cpp:759
IsPlainRail
static bool IsPlainRail(Tile t)
Returns whether this is plain rails, with or without signals.
Definition rail_map.h:49
GetTrackBits
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition rail_map.h:136
RailGroundType
RailGroundType
The ground 'under' the rail.
Definition rail_map.h:484
RailGroundType::FenceVert2
@ FenceVert2
Grass with a fence at the western side.
RailGroundType::FenceHoriz2
@ FenceHoriz2
Grass with a fence at the northern side.
RailGroundType::HalfTileWater
@ HalfTileWater
Grass with a fence and shore or water on the free halftile.
RailGroundType::FenceVert1
@ FenceVert1
Grass with a fence at the eastern side.
RailGroundType::FenceHoriz1
@ FenceHoriz1
Grass with a fence at the southern side.
random_func.hpp
Pseudo random number generator.
safeguards.h
A number of safeguards to prevent using unsafe methods.
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition settings.cpp:61
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition settings.cpp:60
UpdateSignalsInBuffer
void UpdateSignalsInBuffer()
Update signals in buffer Called from 'outside'.
Definition signal.cpp:573
IsSlopeWithOneCornerRaised
bool IsSlopeWithOneCornerRaised(Slope s)
Tests if a specific slope has exactly one corner raised.
Definition slope_func.h:88
IsInclinedSlope
bool IsInclinedSlope(Slope s)
Tests if a specific slope is an inclined slope.
Definition slope_func.h:228
IsHalftileSlope
static constexpr bool IsHalftileSlope(Slope s)
Checks for non-continuous slope on halftile foundations.
Definition slope_func.h:47
GetInclinedSlopeDirection
DiagDirection GetInclinedSlopeDirection(Slope s)
Returns the direction of an inclined slope.
Definition slope_func.h:239
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_HALFTILE_MASK
@ SLOPE_HALFTILE_MASK
three bits used for halftile slopes
Definition slope_type.h:72
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_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_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_NE
@ SLOPE_NE
north and east corner are raised
Definition slope_type.h:58
SLOPE_SE
@ SLOPE_SE
south and east corner are raised
Definition slope_type.h:57
SLOPE_NW
@ SLOPE_NW
north and west corner are raised
Definition slope_type.h:55
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_NONE
@ FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Definition slope_type.h:94
sound_func.h
Functions related to sound.
SND_12_EXPLOSION
@ SND_12_EXPLOSION
16 == 0x10 Destruction, crashes, disasters, ...
Definition sound_type.h:63
DrawOrigTileSeqInGUI
void DrawOrigTileSeqInGUI(int x, int y, const DrawTileSprites *dts, PaletteID default_palette)
Draw TTD sprite sequence in GUI.
Definition sprite.h:121
SPR_SHORE_BASE
static const SpriteID SPR_SHORE_BASE
shore tiles - action 05-0D
Definition sprites.h:226
station_base.h
Base classes/functions for stations.
IsAirportTile
bool IsAirportTile(Tile t)
Is this tile a station tile and an airport tile?
Definition station_map.h:167
IsBuoy
bool IsBuoy(Tile t)
Is tile t a buoy tile?
Definition station_map.h:400
IsDockTile
bool IsDockTile(Tile t)
Is tile t a dock tile?
Definition station_map.h:389
IsOilRig
bool IsOilRig(Tile t)
Is tile t part of an oilrig?
Definition station_map.h:368
IsDockWaterPart
bool IsDockWaterPart(Tile t)
Check whether a dock tile is the tile on water.
Definition station_map.h:605
IsDock
bool IsDock(Tile t)
Is tile t a dock tile?
Definition station_map.h:379
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
GetEncodedString
EncodedString GetEncodedString(StringID str)
Encode a string with no parameters into an encoded string.
Definition strings.cpp:90
strings_func.h
Functions related to OTTD's strings.
AirportFTAClass
Finite sTate mAchine (FTA) of an airport.
Definition airport.h:159
AirportFTAClass::delta_z
uint8_t delta_z
Z adjustment for helicopter pads.
Definition airport.h:197
Airport::GetFTA
const AirportFTAClass * GetFTA() const
Get the finite-state machine for this airport or the finite-state machine for the dummy airport in ca...
Definition station_base.h:378
Backup
Class to backup a specific variable and restore it later.
Definition backup_type.hpp:21
Backup::Restore
void Restore()
Restore the variable.
Definition backup_type.hpp:110
BaseStation::GetByTile
static BaseStation * GetByTile(TileIndex tile)
Get the base station belonging to a specific tile.
Definition base_station_base.h:160
BaseVehicle::type
VehicleType type
Type of vehicle.
Definition vehicle_type.h:51
ClientSettings::sound
SoundSettings sound
sound effect settings
Definition settings_type.h:653
CommandHelper
Definition command_func.h:83
CompanyInfrastructure::water
uint32_t water
Count of company owned track bits for canals.
Definition company_base.h:36
Company
Definition company_base.h:127
Company::infrastructure
CompanyInfrastructure infrastructure
NOSAVE: Counts of company owned infrastructure.
Definition company_base.h:141
ConstructionSettings::freeform_edges
bool freeform_edges
allow terraforming the tiles at the map edges
Definition settings_type.h:423
Coord3D::z
T z
Z coordinate.
Definition geometry_type.hpp:46
Depot
Definition depot_base.h:20
Depot::build_date
TimerGameCalendar::Date build_date
Date of construction.
Definition depot_base.h:26
DrawTileSeqStruct
A tile child sprite and palette to draw for stations etc, with 3D bounding box.
Definition sprite.h:33
DrawTileSprites
Ground palette sprite of a tile, together with its sprite layout.
Definition sprite.h:52
DrawTileSprites::ground
PalSpriteID ground
Palette and sprite for the ground.
Definition sprite.h:53
GameSettings::construction
ConstructionSettings construction
construction of things in-game
Definition settings_type.h:635
Industry::GetByTile
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition industry.h:251
Industry::neutral_station
Station * neutral_station
Associated neutral station.
Definition industry.h:108
Map
Size related data of the map.
Definition map_func.h:206
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
OrthogonalTileArea::Add
void Add(TileIndex to_add)
Add a single tile to a tile area; enlarge if needed.
Definition tilearea.cpp:43
PalSpriteID::sprite
SpriteID sprite
The 'real' sprite.
Definition gfx_type.h:23
PalSpriteID::pal
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition gfx_type.h:24
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::index
Tindex index
Index of this pool item.
Definition pool_type.hpp:286
Pool::PoolItem<&_depot_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition pool_type.hpp:357
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
SoundSettings::disaster
bool disaster
Play disaster and accident sounds.
Definition settings_type.h:277
Station
Station data structure.
Definition station_base.h:500
Station::docking_station
TileArea docking_station
Tile area the docking tiles cover.
Definition station_base.h:516
Station::airport
Airport airport
Tile area the airport covers.
Definition station_base.h:514
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
TileDesc::str
StringID str
Description of the tile.
Definition tile_cmd.h:37
TileDesc::build_date
TimerGameCalendar::Date build_date
Date of construction of tile contents.
Definition tile_cmd.h:41
TileDesc::owner
std::array< Owner, 4 > owner
Name of the owner(s)
Definition tile_cmd.h:39
TileIndexDiffC
A pair-construct of a TileIndexDiff.
Definition map_type.h:31
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
Vehicle
Vehicle data structure.
Definition vehicle_base.h:205
Vehicle::z_pos
int32_t z_pos
z coordinate.
Definition vehicle_base.h:267
Vehicle::Crash
virtual uint Crash(bool flooded=false)
Crash the (whole) vehicle chain.
Definition vehicle.cpp:291
Vehicle::subtype
uint8_t subtype
subtype (Filled with values from AircraftSubType/DisasterSubType/EffectVehicleType/GroundVehicleSubty...
Definition vehicle_base.h:310
Vehicle::vehstatus
VehStates vehstatus
Status.
Definition vehicle_base.h:309
Vehicle::First
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Definition vehicle_base.h:600
Vehicle::tile
TileIndex tile
Current tile index.
Definition vehicle_base.h:225
Vehicle::owner
Owner owner
Which company owns the vehicle?
Definition vehicle_base.h:270
IsTileFlat
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition tile_map.cpp:95
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
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
IsTileOwner
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition tile_map.h:214
GetTileOwner
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition tile_map.h:178
SetTileOwner
void SetTileOwner(Tile tile, Owner owner)
Sets the owner of a tile.
Definition tile_map.h:198
GetTilePixelSlope
std::tuple< Slope, int > GetTilePixelSlope(TileIndex tile)
Return the slope of a given tile.
Definition tile_map.h:289
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
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
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
MP_TREES
@ MP_TREES
Tile got trees.
Definition tile_type.h:52
MP_STATION
@ MP_STATION
A tile of a station.
Definition tile_type.h:53
MP_TUNNELBRIDGE
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition tile_type.h:57
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_RAILWAY
@ MP_RAILWAY
A railway.
Definition tile_type.h:49
MP_INDUSTRY
@ MP_INDUSTRY
Part of an industry.
Definition tile_type.h:56
MP_VOID
@ MP_VOID
Invisible tiles at the SW and SE border.
Definition tile_type.h:55
MP_OBJECT
@ MP_OBJECT
Contains objects such as transmitters and owned land.
Definition tile_type.h:58
timer_game_calendar.h
Definition of the game-calendar-timer.
town.h
Base of the town class.
MakeDefaultName
void MakeDefaultName(T *obj)
Set the default name for a depot/waypoint.
Definition town.h:284
TrackBitsToTrackdirBits
TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
Converts TrackBits to TrackdirBits while allowing both directions.
Definition track_func.h:319
CombineTrackStatus
TrackStatus CombineTrackStatus(TrackdirBits trackdirbits, TrackdirBits red_signals)
Builds a TrackStatus.
Definition track_func.h:388
AxisToTrackBits
TrackBits AxisToTrackBits(Axis a)
Maps an Axis to the corresponding TrackBits value.
Definition track_func.h:88
DiagDirToDiagTrackBits
TrackBits DiagDirToDiagTrackBits(DiagDirection diagdir)
Maps a (4-way) direction to the diagonal track bits incidating with that diagdir.
Definition track_func.h:524
TrackStatusToTrackBits
TrackBits TrackStatusToTrackBits(TrackStatus ts)
Returns the present-track-information of a TrackStatus.
Definition track_func.h:363
TrackBits
TrackBits
Allow incrementing of Track variables.
Definition track_type.h:35
TRACK_BIT_UPPER
@ TRACK_BIT_UPPER
Upper track.
Definition track_type.h:39
TRACK_BIT_LEFT
@ TRACK_BIT_LEFT
Left track.
Definition track_type.h:41
TRACK_BIT_Y
@ TRACK_BIT_Y
Y-axis track.
Definition track_type.h:38
TRACK_BIT_NONE
@ TRACK_BIT_NONE
No track.
Definition track_type.h:36
TRACK_BIT_X
@ TRACK_BIT_X
X-axis track.
Definition track_type.h:37
TRACK_BIT_LOWER
@ TRACK_BIT_LOWER
Lower track.
Definition track_type.h:40
TRACK_BIT_ALL
@ TRACK_BIT_ALL
All possible tracks.
Definition track_type.h:50
TRACK_BIT_RIGHT
@ TRACK_BIT_RIGHT
Right track.
Definition track_type.h:42
TRACKDIR_BIT_NONE
@ TRACKDIR_BIT_NONE
No track build.
Definition track_type.h:98
IsTransparencySet
bool IsTransparencySet(TransparencyOption to)
Check if the transparency option bit is set and if we aren't in the game menu (there's never transpar...
Definition transparency.h:50
IsInvisibilitySet
bool IsInvisibilitySet(TransparencyOption to)
Check if the invisibility option bit is set and if we aren't in the game menu (there's never transpar...
Definition transparency.h:61
TO_BUILDINGS
@ TO_BUILDINGS
company buildings - depots, stations, HQ, ...
Definition transparency.h:28
TransportType
TransportType
Available types of transport.
Definition transport_type.h:17
TRANSPORT_WATER
@ TRANSPORT_WATER
Transport over water.
Definition transport_type.h:27
tree_map.h
Map accessors for tree tiles.
GetTreeGround
TreeGround GetTreeGround(Tile t)
Returns the groundtype for tree tiles.
Definition tree_map.h:102
TREE_GROUND_GRASS
@ TREE_GROUND_GRASS
normal grass
Definition tree_map.h:53
TREE_GROUND_SHORE
@ TREE_GROUND_SHORE
shore
Definition tree_map.h:56
SetTreeGroundDensity
void SetTreeGroundDensity(Tile t, TreeGround g, uint d)
Set the density and ground type of a tile with trees.
Definition tree_map.h:144
tunnelbridge_map.h
Functions that have tunnels and bridges in common.
GetTunnelBridgeDirection
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
Definition tunnelbridge_map.h:26
GetTunnelBridgeTransportType
TransportType GetTunnelBridgeTransportType(Tile t)
Tunnel: Get the transport type of the tunnel (road or rail) Bridge: Get the transport type of the bri...
Definition tunnelbridge_map.h:39
EnsureNoVehicleOnGround
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition vehicle.cpp:527
VehState::Crashed
@ Crashed
Vehicle is crashed.
vehicle_func.h
Functions related to vehicles.
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition vehicle_type.h:26
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition vehicle_type.h:28
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition vehicle_type.h:27
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition vehicle_type.h:25
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
DrawGroundSprite
void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub, int extra_offs_x, int extra_offs_y)
Draws a ground sprite for the current tile.
Definition viewport.cpp:579
viewport_func.h
Functions related to (drawing on) viewports.
TILE_HEIGHT_STEP
static const int TILE_HEIGHT_STEP
One Z unit tile height difference is displayed as 50m.
Definition viewport_func.h:21
water.h
Functions related to water (management)
FloodingBehaviour
FloodingBehaviour
Describes the behaviour of a tile during flooding.
Definition water.h:19
FLOOD_NONE
@ FLOOD_NONE
The tile does not flood neighboured tiles.
Definition water.h:20
FLOOD_ACTIVE
@ FLOOD_ACTIVE
The tile floods neighboured tiles.
Definition water.h:21
FLOOD_DRYUP
@ FLOOD_DRYUP
The tile drys up if it is not constantly flooded from neighboured tiles.
Definition water.h:23
FLOOD_PASSIVE
@ FLOOD_PASSIVE
The tile does not actively flood neighboured tiles, but it prevents them from drying up.
Definition water.h:22
RIVER_OFFSET_DESERT_DISTANCE
static const uint RIVER_OFFSET_DESERT_DISTANCE
Circular tile search diameter to create non-desert around a river tile.
Definition water.h:44
GetLockPartMinimalBridgeHeight
static uint8_t GetLockPartMinimalBridgeHeight(LockPart lock_part)
Get the minimal height required for a bridge above a lock part.
Definition water_cmd.cpp:309
TileLoop_Water
void TileLoop_Water(TileIndex tile)
Let a water tile floods its diagonal adjoining tiles called from tunnelbridge_cmd,...
Definition water_cmd.cpp:1269
DrawWaterDepot
static void DrawWaterDepot(const TileInfo *ti)
Draw a ship depot tile.
Definition water_cmd.cpp:879
DrawWaterSprite
static void DrawWaterSprite(SpriteID base, uint offset, CanalFeature feature, TileIndex tile)
Draw a water sprite, potentially with a NewGRF-modified sprite offset.
Definition water_cmd.cpp:729
DoBuildLock
static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlags flags)
Builds a lock.
Definition water_cmd.cpp:326
CmdBuildLock
CommandCost CmdBuildLock(DoCommandFlags flags, TileIndex tile)
Builds a lock.
Definition water_cmd.cpp:453
RemoveLock
static CommandCost RemoveLock(TileIndex tile, DoCommandFlags flags)
Remove a lock.
Definition water_cmd.cpp:408
DrawWaterLock
static void DrawWaterLock(const TileInfo *ti)
Draw a lock tile.
Definition water_cmd.cpp:840
FloodVehicle
static void FloodVehicle(Vehicle *v)
Handle the flooding of a vehicle.
Definition water_cmd.cpp:1028
FloodVehicles
static void FloodVehicles(TileIndex tile)
Finds a vehicle to flood.
Definition water_cmd.cpp:1086
DrawWaterEdges
static void DrawWaterEdges(bool canal, uint offset, TileIndex tile)
Draw canal or river edges.
Definition water_cmd.cpp:744
FloodVehicleProc
static void FloodVehicleProc(Vehicle *v, int z)
Flood a vehicle if we are allowed to flood it, i.e.
Definition water_cmd.cpp:1044
_flood_from_dirs
static const Directions _flood_from_dirs[]
Describes from which directions a specific slope can be flooded (if the tile is floodable at all).
Definition water_cmd.cpp:51
ClearNeighbourNonFloodingStates
void ClearNeighbourNonFloodingStates(TileIndex tile)
Clear non-flooding state of the tiles around a tile.
Definition water_cmd.cpp:97
DrawWaterTileStruct
static void DrawWaterTileStruct(const TileInfo *ti, std::span< const DrawTileSeqStruct > seq, SpriteID base, uint offset, PaletteID palette, CanalFeature feature)
Draw a build sprite sequence for water tiles.
Definition water_cmd.cpp:827
DoDryUp
static void DoDryUp(TileIndex tile)
Drys a tile up.
Definition water_cmd.cpp:1222
MarkTileDirtyIfCanalOrRiver
static void MarkTileDirtyIfCanalOrRiver(TileIndex tile)
Marks tile dirty if it is a canal or river tile.
Definition water_cmd.cpp:75
GetFloodingBehaviour
FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
Returns the behaviour of a tile during flooding.
Definition water_cmd.cpp:1115
CheckForDockingTile
void CheckForDockingTile(TileIndex t)
Mark the supplied tile as a docking tile if it is suitable for docking.
Definition water_cmd.cpp:194
DrawSeaWater
static void DrawSeaWater(TileIndex)
Draw a plain sea water tile with no edges.
Definition water_cmd.cpp:797
CmdBuildShipDepot
CommandCost CmdBuildShipDepot(DoCommandFlags flags, TileIndex tile, Axis axis)
Build a ship depot.
Definition water_cmd.cpp:112
DrawCanalWater
static void DrawCanalWater(TileIndex tile)
draw a canal styled water tile with dikes around
Definition water_cmd.cpp:803
MakeRiverAndModifyDesertZoneAround
void MakeRiverAndModifyDesertZoneAround(TileIndex tile)
Make a river tile and remove desert directly around it.
Definition water_cmd.cpp:472
DoFloodTile
static void DoFloodTile(TileIndex target)
Floods a tile.
Definition water_cmd.cpp:1154
IsWateredTile
bool IsWateredTile(TileIndex tile, Direction from)
return true if a tile is a water tile wrt.
Definition water_cmd.cpp:658
CmdBuildCanal
CommandCost CmdBuildCanal(DoCommandFlags flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal)
Build a piece of canal.
Definition water_cmd.cpp:492
water_cmd.h
Command definitions related to water tiles.
water_land.h
Sprites to use and how to display them for water tiles (depots/locks).
MakeShore
void MakeShore(Tile t)
Helper function to make a coast tile.
Definition water_map.h:383
HasTileWaterGround
bool HasTileWaterGround(Tile t)
Checks whether the tile has water at the ground.
Definition water_map.h:352
GetShipDepotNorthTile
TileIndex GetShipDepotNorthTile(Tile t)
Get the most northern tile of a ship depot.
Definition water_map.h:291
MakeLock
void MakeLock(Tile t, Owner o, DiagDirection d, WaterClass wc_lower, WaterClass wc_upper, WaterClass wc_middle)
Make a water lock.
Definition water_map.h:512
GetShipDepotPart
DepotPart GetShipDepotPart(Tile t)
Get the part of a ship depot.
Definition water_map.h:257
IsTileOnWater
bool IsTileOnWater(Tile t)
Tests if the tile was built on water.
Definition water_map.h:138
IsShipDepot
bool IsShipDepot(Tile t)
Is it a water tile with a ship depot on it?
Definition water_map.h:224
IsValidWaterClass
bool IsValidWaterClass(WaterClass wc)
Checks if a water class is valid.
Definition water_map.h:52
IsRiver
bool IsRiver(Tile t)
Is it a river water tile?
Definition water_map.h:182
GetLockDirection
DiagDirection GetLockDirection(Tile t)
Get the direction of the water lock.
Definition water_map.h:316
WaterClass
WaterClass
classes of water (for WaterTileType::Clear water tile type).
Definition water_map.h:39
WaterClass::River
@ River
River.
WaterClass::Invalid
@ Invalid
Used for industry tiles on land (also for oilrig if newgrf says so).
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
IsCoast
bool IsCoast(Tile t)
Is it a coast tile?
Definition water_map.h:203
MakeRiver
void MakeRiver(Tile t, uint8_t random_bits)
Make a river tile.
Definition water_map.h:436
GetWaterTileType
WaterTileType GetWaterTileType(Tile t)
Get the water tile type of a tile.
Definition water_map.h:80
SetNonFloodingWaterTile
void SetNonFloodingWaterTile(Tile t, bool b)
Set the non-flooding water tile state of a tile.
Definition water_map.h:530
GetWaterClass
WaterClass GetWaterClass(Tile t)
Get the water class at a tile.
Definition water_map.h:114
MakeCanal
void MakeCanal(Tile t, Owner o, uint8_t random_bits)
Make a canal tile.
Definition water_map.h:447
GetOtherShipDepotTile
TileIndex GetOtherShipDepotTile(Tile t)
Get the other tile of the ship depot.
Definition water_map.h:280
DepotPart
DepotPart
Sections of the water depot.
Definition water_map.h:58
DepotPart::South
@ South
Southern part of a depot.
DepotPart::North
@ North
Northern part of a depot.
WaterTileType::Coast
@ Coast
Coast.
WaterTileType::Depot
@ Depot
Water Depot.
WaterTileType::Lock
@ Lock
Water lock.
WaterTileType::Clear
@ Clear
Plain water.
IsNonFloodingWaterTile
bool IsNonFloodingWaterTile(Tile t)
Checks whether the tile is marked as a non-flooding water tile.
Definition water_map.h:539
SetDockingTile
void SetDockingTile(Tile t, bool b)
Set the docking tile state of a tile.
Definition water_map.h:363
LockPart
LockPart
Sections of the water lock.
Definition water_map.h:65
LockPart::Upper
@ Upper
Upper part of a lock.
LockPart::Middle
@ Middle
Middle part of a lock.
IsWater
bool IsWater(Tile t)
Is it a plain water tile?
Definition water_map.h:149
IsWaterTile
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition water_map.h:192
IsLock
bool IsLock(Tile t)
Is there a lock on a given water tile?
Definition water_map.h:305
MakeShipDepot
void MakeShipDepot(Tile t, Owner o, DepotID did, DepotPart part, Axis a, WaterClass original_water_class)
Make a ship depot section.
Definition water_map.h:462
MakeSea
void MakeSea(Tile t)
Make a sea tile.
Definition water_map.h:426
GetLockPart
LockPart GetLockPart(Tile t)
Get the part of a lock.
Definition water_map.h:328
GetShipDepotAxis
Axis GetShipDepotAxis(Tile t)
Get the axis of the ship depot.
Definition water_map.h:245
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.