OpenTTD Source  20240917-master-g9ab0a47812
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 <http://www.gnu.org/licenses/>.
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"
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"
43 
44 #include "table/strings.h"
45 
46 #include "safeguards.h"
47 
51 static const uint8_t _flood_from_dirs[] = {
52  (1 << DIR_NW) | (1 << DIR_SW) | (1 << DIR_SE) | (1 << DIR_NE), // SLOPE_FLAT
53  (1 << DIR_NE) | (1 << DIR_SE), // SLOPE_W
54  (1 << DIR_NW) | (1 << DIR_NE), // SLOPE_S
55  (1 << DIR_NE), // SLOPE_SW
56  (1 << DIR_NW) | (1 << DIR_SW), // SLOPE_E
57  0, // SLOPE_EW
58  (1 << DIR_NW), // SLOPE_SE
59  (1 << DIR_N ) | (1 << DIR_NW) | (1 << DIR_NE), // SLOPE_WSE, SLOPE_STEEP_S
60  (1 << DIR_SW) | (1 << DIR_SE), // SLOPE_N
61  (1 << DIR_SE), // SLOPE_NW
62  0, // SLOPE_NS
63  (1 << DIR_E ) | (1 << DIR_NE) | (1 << DIR_SE), // SLOPE_NWS, SLOPE_STEEP_W
64  (1 << DIR_SW), // SLOPE_NE
65  (1 << DIR_S ) | (1 << DIR_SW) | (1 << DIR_SE), // SLOPE_ENW, SLOPE_STEEP_N
66  (1 << DIR_W ) | (1 << DIR_SW) | (1 << 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 
87 {
88  for (Direction dir = DIR_BEGIN; dir < DIR_END; dir++) {
90  }
91 }
92 
93 
102 {
103  if (!IsValidAxis(axis)) return CMD_ERROR;
104  TileIndex tile2 = tile + (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
105 
106  if (!HasTileWaterGround(tile) || !HasTileWaterGround(tile2)) {
107  return_cmd_error(STR_ERROR_MUST_BE_BUILT_ON_WATER);
108  }
109 
110  if (IsBridgeAbove(tile) || IsBridgeAbove(tile2)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
111 
112  if (!IsTileFlat(tile) || !IsTileFlat(tile2)) {
113  /* Prevent depots on rapids */
114  return_cmd_error(STR_ERROR_SITE_UNSUITABLE);
115  }
116 
117  if (!Depot::CanAllocateItem()) return CMD_ERROR;
118 
119  WaterClass wc1 = GetWaterClass(tile);
120  WaterClass wc2 = GetWaterClass(tile2);
121  CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_DEPOT_SHIP]);
122 
123  bool add_cost = !IsWaterTile(tile);
125  if (ret.Failed()) return ret;
126  if (add_cost) {
127  cost.AddCost(ret);
128  }
129  add_cost = !IsWaterTile(tile2);
130  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags | DC_AUTO, tile2);
131  if (ret.Failed()) return ret;
132  if (add_cost) {
133  cost.AddCost(ret);
134  }
135 
136  if (flags & DC_EXEC) {
137  Depot *depot = new Depot(tile);
139 
140  uint new_water_infra = 2 * LOCK_DEPOT_TILE_FACTOR;
141  /* Update infrastructure counts after the tile clears earlier.
142  * Clearing object tiles may result in water tiles which are already accounted for in the water infrastructure total.
143  * See: MakeWaterKeepingClass() */
144  if (wc1 == WATER_CLASS_CANAL && !(HasTileWaterClass(tile) && GetWaterClass(tile) == WATER_CLASS_CANAL && IsTileOwner(tile, _current_company))) new_water_infra++;
145  if (wc2 == WATER_CLASS_CANAL && !(HasTileWaterClass(tile2) && GetWaterClass(tile2) == WATER_CLASS_CANAL && IsTileOwner(tile2, _current_company))) new_water_infra++;
146 
147  Company::Get(_current_company)->infrastructure.water += new_water_infra;
149 
150  MakeShipDepot(tile, _current_company, depot->index, DEPOT_PART_NORTH, axis, wc1);
151  MakeShipDepot(tile2, _current_company, depot->index, DEPOT_PART_SOUTH, axis, wc2);
152  CheckForDockingTile(tile);
153  CheckForDockingTile(tile2);
154  MarkTileDirtyByTile(tile);
155  MarkTileDirtyByTile(tile2);
156  MakeDefaultName(depot);
157  }
158 
159  return cost;
160 }
161 
162 bool IsPossibleDockingTile(Tile t)
163 {
164  assert(IsValidTile(t));
165  switch (GetTileType(t)) {
166  case MP_WATER:
167  if (IsLock(t) && GetLockPart(t) == LOCK_PART_MIDDLE) return false;
168  [[fallthrough]];
169  case MP_RAILWAY:
170  case MP_STATION:
171  case MP_TUNNELBRIDGE:
173 
174  default:
175  return false;
176  }
177 }
178 
185 {
186  for (DiagDirection d = DIAGDIR_BEGIN; d != DIAGDIR_END; d++) {
187  TileIndex tile = t + TileOffsByDiagDir(d);
188  if (!IsValidTile(tile)) continue;
189 
190  if (IsDockTile(tile) && IsDockWaterPart(tile)) {
192  SetDockingTile(t, true);
193  }
194  if (IsTileType(tile, MP_INDUSTRY)) {
196  if (st != nullptr) {
197  st->docking_station.Add(t);
198  SetDockingTile(t, true);
199  }
200  }
201  if (IsTileType(tile, MP_STATION) && IsOilRig(tile)) {
203  SetDockingTile(t, true);
204  }
205  }
206 }
207 
208 void MakeWaterKeepingClass(TileIndex tile, Owner o)
209 {
210  WaterClass wc = GetWaterClass(tile);
211 
212  /* Autoslope might turn an originally canal or river tile into land */
213  auto [slope, z] = GetTileSlopeZ(tile);
214 
215  if (slope != SLOPE_FLAT) {
216  if (wc == WATER_CLASS_CANAL) {
217  /* If we clear the canal, we have to remove it from the infrastructure count as well. */
219  if (c != nullptr) {
220  c->infrastructure.water--;
222  }
223  /* Sloped canals are locks and no natural water remains whatever the slope direction */
224  wc = WATER_CLASS_INVALID;
225  }
226 
227  /* Only river water should be restored on appropriate slopes. Other water would be invalid on slopes */
229  wc = WATER_CLASS_INVALID;
230  }
231  }
232 
233  if (wc == WATER_CLASS_SEA && z > 0) {
234  /* Update company infrastructure count. */
236  if (c != nullptr) {
237  c->infrastructure.water++;
239  }
240 
241  wc = WATER_CLASS_CANAL;
242  }
243 
244  /* Zero map array and terminate animation */
245  DoClearSquare(tile);
246 
247  /* Maybe change to water */
248  switch (wc) {
249  case WATER_CLASS_SEA: MakeSea(tile); break;
250  case WATER_CLASS_CANAL: MakeCanal(tile, o, Random()); break;
251  case WATER_CLASS_RIVER: MakeRiver(tile, Random()); break;
252  default: break;
253  }
254 
255  if (wc != WATER_CLASS_INVALID) CheckForDockingTile(tile);
256  MarkTileDirtyByTile(tile);
257 }
258 
259 static CommandCost RemoveShipDepot(TileIndex tile, DoCommandFlag flags)
260 {
261  if (!IsShipDepot(tile)) return CMD_ERROR;
262 
263  CommandCost ret = CheckTileOwnership(tile);
264  if (ret.Failed()) return ret;
265 
266  TileIndex tile2 = GetOtherShipDepotTile(tile);
267 
268  /* do not check for ship on tile when company goes bankrupt */
269  if (!(flags & DC_BANKRUPT)) {
270  ret = EnsureNoVehicleOnGround(tile);
271  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile2);
272  if (ret.Failed()) return ret;
273  }
274 
275  bool do_clear = (flags & DC_FORCE_CLEAR_TILE) != 0;
276 
277  if (flags & DC_EXEC) {
278  delete Depot::GetByTile(tile);
279 
281  if (c != nullptr) {
283  if (do_clear && GetWaterClass(tile) == WATER_CLASS_CANAL) c->infrastructure.water--;
285  }
286 
287  if (!do_clear) MakeWaterKeepingClass(tile, GetTileOwner(tile));
288  MakeWaterKeepingClass(tile2, GetTileOwner(tile2));
289  }
290 
291  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_DEPOT_SHIP]);
292 }
293 
302 {
304 
305  int delta = TileOffsByDiagDir(dir);
307  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile + delta);
308  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile - delta);
309  if (ret.Failed()) return ret;
310 
311  /* middle tile */
312  WaterClass wc_middle = HasTileWaterGround(tile) ? GetWaterClass(tile) : WATER_CLASS_CANAL;
313  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
314  if (ret.Failed()) return ret;
315  cost.AddCost(ret);
316 
317  /* lower tile */
318  if (!IsWaterTile(tile - delta)) {
319  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile - delta);
320  if (ret.Failed()) return ret;
321  cost.AddCost(ret);
322  cost.AddCost(_price[PR_BUILD_CANAL]);
323  }
324  if (!IsTileFlat(tile - delta)) {
325  return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
326  }
327  WaterClass wc_lower = IsWaterTile(tile - delta) ? GetWaterClass(tile - delta) : WATER_CLASS_CANAL;
328 
329  /* upper tile */
330  if (!IsWaterTile(tile + delta)) {
331  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile + delta);
332  if (ret.Failed()) return ret;
333  cost.AddCost(ret);
334  cost.AddCost(_price[PR_BUILD_CANAL]);
335  }
336  if (!IsTileFlat(tile + delta)) {
337  return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
338  }
339  WaterClass wc_upper = IsWaterTile(tile + delta) ? GetWaterClass(tile + delta) : WATER_CLASS_CANAL;
340 
341  if (IsBridgeAbove(tile) || IsBridgeAbove(tile - delta) || IsBridgeAbove(tile + delta)) {
342  return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
343  }
344 
345  if (flags & DC_EXEC) {
346  /* Update company infrastructure counts. */
348  if (c != nullptr) {
349  /* Counts for the water. */
350  if (!IsWaterTile(tile - delta)) c->infrastructure.water++;
351  if (!IsWaterTile(tile + delta)) c->infrastructure.water++;
352  /* Count for the lock itself. */
353  c->infrastructure.water += 3 * LOCK_DEPOT_TILE_FACTOR; // Lock is three tiles.
355  }
356 
357  MakeLock(tile, _current_company, dir, wc_lower, wc_upper, wc_middle);
358  CheckForDockingTile(tile - delta);
359  CheckForDockingTile(tile + delta);
360  MarkTileDirtyByTile(tile);
361  MarkTileDirtyByTile(tile - delta);
362  MarkTileDirtyByTile(tile + delta);
363  MarkCanalsAndRiversAroundDirty(tile - delta);
364  MarkCanalsAndRiversAroundDirty(tile + delta);
365  InvalidateWaterRegion(tile - delta);
366  InvalidateWaterRegion(tile + delta);
367  }
368  cost.AddCost(_price[PR_BUILD_LOCK]);
369 
370  return cost;
371 }
372 
380 {
381  if (GetTileOwner(tile) != OWNER_NONE) {
382  CommandCost ret = CheckTileOwnership(tile);
383  if (ret.Failed()) return ret;
384  }
385 
387 
388  /* make sure no vehicle is on the tile. */
390  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile + delta);
391  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile - delta);
392  if (ret.Failed()) return ret;
393 
394  if (flags & DC_EXEC) {
395  /* Remove middle part from company infrastructure count. */
397  if (c != nullptr) {
398  c->infrastructure.water -= 3 * LOCK_DEPOT_TILE_FACTOR; // three parts of the lock.
400  }
401 
402  if (GetWaterClass(tile) == WATER_CLASS_RIVER) {
403  MakeRiver(tile, Random());
404  } else {
405  DoClearSquare(tile);
406  }
407  MakeWaterKeepingClass(tile + delta, GetTileOwner(tile + delta));
408  MakeWaterKeepingClass(tile - delta, GetTileOwner(tile - delta));
410  MarkCanalsAndRiversAroundDirty(tile - delta);
411  MarkCanalsAndRiversAroundDirty(tile + delta);
412  }
413 
414  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_LOCK]);
415 }
416 
424 {
426  if (dir == INVALID_DIAGDIR) return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
427 
428  return DoBuildLock(tile, dir, flags);
429 }
430 
433 {
435  return false;
436 }
437 
443 {
444  MakeRiver(tile, Random());
445  MarkTileDirtyByTile(tile);
446 
447  /* Remove desert directly around the river tile. */
449 }
450 
460 CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal)
461 {
462  if (start_tile >= Map::Size() || !IsValidWaterClass(wc)) return CMD_ERROR;
463 
464  /* Outside of the editor you can only build canals, not oceans */
465  if (wc != WATER_CLASS_CANAL && _game_mode != GM_EDITOR) return CMD_ERROR;
466 
468 
469  std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
470  for (; *iter != INVALID_TILE; ++(*iter)) {
471  TileIndex current_tile = *iter;
472  CommandCost ret;
473 
474  Slope slope = GetTileSlope(current_tile);
475  if (slope != SLOPE_FLAT && (wc != WATER_CLASS_RIVER || !IsInclinedSlope(slope))) {
476  return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
477  }
478 
479  bool water = IsWaterTile(current_tile);
480 
481  /* Outside the editor, prevent building canals over your own or OWNER_NONE owned canals */
482  if (water && IsCanal(current_tile) && _game_mode != GM_EDITOR && (IsTileOwner(current_tile, _current_company) || IsTileOwner(current_tile, OWNER_NONE))) continue;
483 
484  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
485  if (ret.Failed()) return ret;
486 
487  if (!water) cost.AddCost(ret);
488 
489  if (flags & DC_EXEC) {
490  if (IsTileType(current_tile, MP_WATER) && IsCanal(current_tile)) {
491  Owner owner = GetTileOwner(current_tile);
492  if (Company::IsValidID(owner)) {
493  Company::Get(owner)->infrastructure.water--;
495  }
496  }
497 
498  switch (wc) {
499  case WATER_CLASS_RIVER:
500  MakeRiver(current_tile, Random());
501  if (_game_mode == GM_EDITOR) {
502  TileIndex tile2 = current_tile;
504  }
505  break;
506 
507  case WATER_CLASS_SEA:
508  if (TileHeight(current_tile) == 0) {
509  MakeSea(current_tile);
510  break;
511  }
512  [[fallthrough]];
513 
514  default:
515  MakeCanal(current_tile, _current_company, Random());
517  Company::Get(_current_company)->infrastructure.water++;
519  }
520  break;
521  }
522  MarkTileDirtyByTile(current_tile);
523  MarkCanalsAndRiversAroundDirty(current_tile);
524  CheckForDockingTile(current_tile);
525  }
526 
527  cost.AddCost(_price[PR_BUILD_CANAL]);
528  }
529 
530  if (cost.GetCost() == 0) {
531  return_cmd_error(STR_ERROR_ALREADY_BUILT);
532  } else {
533  return cost;
534  }
535 }
536 
537 
538 static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags)
539 {
540  switch (GetWaterTileType(tile)) {
541  case WATER_TILE_CLEAR: {
542  if (flags & DC_NO_WATER) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
543 
544  Money base_cost = IsCanal(tile) ? _price[PR_CLEAR_CANAL] : _price[PR_CLEAR_WATER];
545  /* Make sure freeform edges are allowed or it's not an edge tile. */
547  !IsInsideMM(TileY(tile), 1, Map::MaxY() - 1))) {
548  return_cmd_error(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP);
549  }
550 
551  /* Make sure no vehicle is on the tile */
553  if (ret.Failed()) return ret;
554 
555  Owner owner = GetTileOwner(tile);
556  if (owner != OWNER_WATER && owner != OWNER_NONE) {
557  ret = CheckTileOwnership(tile);
558  if (ret.Failed()) return ret;
559  }
560 
561  if (flags & DC_EXEC) {
562  if (IsCanal(tile) && Company::IsValidID(owner)) {
563  Company::Get(owner)->infrastructure.water--;
565  }
566  DoClearSquare(tile);
568  }
569 
570  return CommandCost(EXPENSES_CONSTRUCTION, base_cost);
571  }
572 
573  case WATER_TILE_COAST: {
574  Slope slope = GetTileSlope(tile);
575 
576  /* Make sure no vehicle is on the tile */
578  if (ret.Failed()) return ret;
579 
580  if (flags & DC_EXEC) {
581  DoClearSquare(tile);
583  }
584  if (IsSlopeWithOneCornerRaised(slope)) {
585  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_WATER]);
586  } else {
587  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_ROUGH]);
588  }
589  }
590 
591  case WATER_TILE_LOCK: {
592  static const TileIndexDiffC _lock_tomiddle_offs[][DIAGDIR_END] = {
593  /* NE SE SW NW */
594  { { 0, 0}, {0, 0}, { 0, 0}, {0, 0} }, // LOCK_PART_MIDDLE
595  { {-1, 0}, {0, 1}, { 1, 0}, {0, -1} }, // LOCK_PART_LOWER
596  { { 1, 0}, {0, -1}, {-1, 0}, {0, 1} }, // LOCK_PART_UPPER
597  };
598 
599  if (flags & DC_AUTO) return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
600  if (_current_company == OWNER_WATER) return CMD_ERROR;
601  /* move to the middle tile.. */
602  return RemoveLock(tile + ToTileIndexDiff(_lock_tomiddle_offs[GetLockPart(tile)][GetLockDirection(tile)]), flags);
603  }
604 
605  case WATER_TILE_DEPOT:
606  if (flags & DC_AUTO) return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
607  return RemoveShipDepot(tile, flags);
608 
609  default:
610  NOT_REACHED();
611  }
612 }
613 
623 {
624  switch (GetTileType(tile)) {
625  case MP_WATER:
626  switch (GetWaterTileType(tile)) {
627  default: NOT_REACHED();
628  case WATER_TILE_DEPOT: case WATER_TILE_CLEAR: return true;
630 
631  case WATER_TILE_COAST:
632  switch (GetTileSlope(tile)) {
633  case SLOPE_W: return (from == DIR_SE) || (from == DIR_E) || (from == DIR_NE);
634  case SLOPE_S: return (from == DIR_NE) || (from == DIR_N) || (from == DIR_NW);
635  case SLOPE_E: return (from == DIR_NW) || (from == DIR_W) || (from == DIR_SW);
636  case SLOPE_N: return (from == DIR_SW) || (from == DIR_S) || (from == DIR_SE);
637  default: return false;
638  }
639  }
640 
641  case MP_RAILWAY:
642  if (GetRailGroundType(tile) == RAIL_GROUND_WATER) {
643  assert(IsPlainRail(tile));
644  switch (GetTileSlope(tile)) {
645  case SLOPE_W: return (from == DIR_SE) || (from == DIR_E) || (from == DIR_NE);
646  case SLOPE_S: return (from == DIR_NE) || (from == DIR_N) || (from == DIR_NW);
647  case SLOPE_E: return (from == DIR_NW) || (from == DIR_W) || (from == DIR_SW);
648  case SLOPE_N: return (from == DIR_SW) || (from == DIR_S) || (from == DIR_SE);
649  default: return false;
650  }
651  }
652  return false;
653 
654  case MP_STATION:
655  if (IsOilRig(tile)) {
656  /* Do not draw waterborders inside of industries.
657  * Note: There is no easy way to detect the industry of an oilrig tile. */
658  TileIndex src_tile = tile + TileOffsByDir(from);
659  if ((IsTileType(src_tile, MP_STATION) && IsOilRig(src_tile)) ||
660  (IsTileType(src_tile, MP_INDUSTRY))) return true;
661 
662  return IsTileOnWater(tile);
663  }
664  return (IsDock(tile) && IsTileFlat(tile)) || IsBuoy(tile);
665 
666  case MP_INDUSTRY: {
667  /* Do not draw waterborders inside of industries.
668  * Note: There is no easy way to detect the industry of an oilrig tile. */
669  TileIndex src_tile = tile + TileOffsByDir(from);
670  if ((IsTileType(src_tile, MP_STATION) && IsOilRig(src_tile)) ||
671  (IsTileType(src_tile, MP_INDUSTRY) && GetIndustryIndex(src_tile) == GetIndustryIndex(tile))) return true;
672 
673  return IsTileOnWater(tile);
674  }
675 
676  case MP_OBJECT: return IsTileOnWater(tile);
677 
679 
680  case MP_VOID: return true; // consider map border as water, esp. for rivers
681 
682  default: return false;
683  }
684 }
685 
693 static void DrawWaterSprite(SpriteID base, uint offset, CanalFeature feature, TileIndex tile)
694 {
695  if (base != SPR_FLAT_WATER_TILE) {
696  /* Only call offset callback if the sprite is NewGRF-provided. */
697  offset = GetCanalSpriteOffset(feature, tile, offset);
698  }
699  DrawGroundSprite(base + offset, PAL_NONE);
700 }
701 
708 static void DrawWaterEdges(bool canal, uint offset, TileIndex tile)
709 {
710  CanalFeature feature;
711  SpriteID base = 0;
712  if (canal) {
713  feature = CF_DIKES;
714  base = GetCanalSprite(CF_DIKES, tile);
715  if (base == 0) base = SPR_CANAL_DIKES_BASE;
716  } else {
717  feature = CF_RIVER_EDGE;
718  base = GetCanalSprite(CF_RIVER_EDGE, tile);
719  if (base == 0) return; // Don't draw if no sprites provided.
720  }
721 
722  uint wa;
723 
724  /* determine the edges around with water. */
725  wa = IsWateredTile(TileAddXY(tile, -1, 0), DIR_SW) << 0;
726  wa += IsWateredTile(TileAddXY(tile, 0, 1), DIR_NW) << 1;
727  wa += IsWateredTile(TileAddXY(tile, 1, 0), DIR_NE) << 2;
728  wa += IsWateredTile(TileAddXY(tile, 0, -1), DIR_SE) << 3;
729 
730  if (!(wa & 1)) DrawWaterSprite(base, offset, feature, tile);
731  if (!(wa & 2)) DrawWaterSprite(base, offset + 1, feature, tile);
732  if (!(wa & 4)) DrawWaterSprite(base, offset + 2, feature, tile);
733  if (!(wa & 8)) DrawWaterSprite(base, offset + 3, feature, tile);
734 
735  /* right corner */
736  switch (wa & 0x03) {
737  case 0: DrawWaterSprite(base, offset + 4, feature, tile); break;
738  case 3: if (!IsWateredTile(TileAddXY(tile, -1, 1), DIR_W)) DrawWaterSprite(base, offset + 8, feature, tile); break;
739  }
740 
741  /* bottom corner */
742  switch (wa & 0x06) {
743  case 0: DrawWaterSprite(base, offset + 5, feature, tile); break;
744  case 6: if (!IsWateredTile(TileAddXY(tile, 1, 1), DIR_N)) DrawWaterSprite(base, offset + 9, feature, tile); break;
745  }
746 
747  /* left corner */
748  switch (wa & 0x0C) {
749  case 0: DrawWaterSprite(base, offset + 6, feature, tile); break;
750  case 12: if (!IsWateredTile(TileAddXY(tile, 1, -1), DIR_E)) DrawWaterSprite(base, offset + 10, feature, tile); break;
751  }
752 
753  /* upper corner */
754  switch (wa & 0x09) {
755  case 0: DrawWaterSprite(base, offset + 7, feature, tile); break;
756  case 9: if (!IsWateredTile(TileAddXY(tile, -1, -1), DIR_S)) DrawWaterSprite(base, offset + 11, feature, tile); break;
757  }
758 }
759 
762 {
763  DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
764 }
765 
767 static void DrawCanalWater(TileIndex tile)
768 {
769  SpriteID image = SPR_FLAT_WATER_TILE;
770  if (HasBit(_water_feature[CF_WATERSLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
771  /* First water slope sprite is flat water. */
772  image = GetCanalSprite(CF_WATERSLOPE, tile);
773  if (image == 0) image = SPR_FLAT_WATER_TILE;
774  }
775  DrawWaterSprite(image, 0, CF_WATERSLOPE, tile);
776 
777  DrawWaterEdges(true, 0, tile);
778 }
779 
780 #include "table/water_land.h"
781 
791 static void DrawWaterTileStruct(const TileInfo *ti, const DrawTileSeqStruct *dtss, SpriteID base, uint offset, PaletteID palette, CanalFeature feature)
792 {
793  /* Don't draw if buildings are invisible. */
794  if (IsInvisibilitySet(TO_BUILDINGS)) return;
795 
796  for (; !dtss->IsTerminator(); dtss++) {
797  uint tile_offs = offset + dtss->image.sprite;
798  if (feature < CF_END) tile_offs = GetCanalSpriteOffset(feature, ti->tile, tile_offs);
799  AddSortableSpriteToDraw(base + tile_offs, palette,
800  ti->x + dtss->delta_x, ti->y + dtss->delta_y,
801  dtss->size_x, dtss->size_y,
802  dtss->size_z, ti->z + dtss->delta_z,
804  }
805 }
806 
808 static void DrawWaterLock(const TileInfo *ti)
809 {
810  int part = GetLockPart(ti->tile);
811  const DrawTileSprites &dts = _lock_display_data[part][GetLockDirection(ti->tile)];
812 
813  /* Draw ground sprite. */
814  SpriteID image = dts.ground.sprite;
815 
816  SpriteID water_base = GetCanalSprite(CF_WATERSLOPE, ti->tile);
817  if (water_base == 0) {
818  /* Use default sprites. */
819  water_base = SPR_CANALS_BASE;
820  } else if (HasBit(_water_feature[CF_WATERSLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
821  /* NewGRF supplies a flat sprite as first sprite. */
822  if (image == SPR_FLAT_WATER_TILE) {
823  image = water_base;
824  } else {
825  image++;
826  }
827  }
828 
829  if (image < 5) image += water_base;
830  DrawGroundSprite(image, PAL_NONE);
831 
832  /* Draw structures. */
833  uint zoffs = 0;
834  SpriteID base = GetCanalSprite(CF_LOCKS, ti->tile);
835 
836  if (base == 0) {
837  /* If no custom graphics, use defaults. */
838  base = SPR_LOCK_BASE;
839  uint8_t z_threshold = part == LOCK_PART_UPPER ? 8 : 0;
840  zoffs = ti->z > z_threshold ? 24 : 0;
841  }
842 
843  DrawWaterTileStruct(ti, dts.seq, base, zoffs, PAL_NONE, CF_LOCKS);
844 }
845 
847 static void DrawWaterDepot(const TileInfo *ti)
848 {
849  DrawWaterClassGround(ti);
850  DrawWaterTileStruct(ti, _shipdepot_display_data[GetShipDepotAxis(ti->tile)][GetShipDepotPart(ti->tile)].seq, 0, 0, COMPANY_SPRITE_COLOUR(GetTileOwner(ti->tile)), CF_END);
851 }
852 
853 static void DrawRiverWater(const TileInfo *ti)
854 {
855  SpriteID image = SPR_FLAT_WATER_TILE;
856  uint offset = 0;
857  uint edges_offset = 0;
858 
859  if (ti->tileh != SLOPE_FLAT || HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
860  image = GetCanalSprite(CF_RIVER_SLOPE, ti->tile);
861  if (image == 0) {
862  switch (ti->tileh) {
863  case SLOPE_NW: image = SPR_WATER_SLOPE_Y_DOWN; break;
864  case SLOPE_SW: image = SPR_WATER_SLOPE_X_UP; break;
865  case SLOPE_SE: image = SPR_WATER_SLOPE_Y_UP; break;
866  case SLOPE_NE: image = SPR_WATER_SLOPE_X_DOWN; break;
867  default: image = SPR_FLAT_WATER_TILE; break;
868  }
869  } else {
870  /* Flag bit 0 indicates that the first sprite is flat water. */
871  offset = HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE) ? 1 : 0;
872 
873  switch (ti->tileh) {
874  case SLOPE_SE: edges_offset += 12; break;
875  case SLOPE_NE: offset += 1; edges_offset += 24; break;
876  case SLOPE_SW: offset += 2; edges_offset += 36; break;
877  case SLOPE_NW: offset += 3; edges_offset += 48; break;
878  default: offset = 0; break;
879  }
880 
881  offset = GetCanalSpriteOffset(CF_RIVER_SLOPE, ti->tile, offset);
882  }
883  }
884 
885  DrawGroundSprite(image + offset, PAL_NONE);
886 
887  /* Draw river edges if available. */
888  DrawWaterEdges(false, edges_offset, ti->tile);
889 }
890 
891 void DrawShoreTile(Slope tileh)
892 {
893  /* Converts the enum Slope into an offset based on SPR_SHORE_BASE.
894  * This allows to calculate the proper sprite to display for this Slope */
895  static const uint8_t tileh_to_shoresprite[32] = {
896  0, 1, 2, 3, 4, 16, 6, 7, 8, 9, 17, 11, 12, 13, 14, 0,
897  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 10, 15, 0,
898  };
899 
900  assert(!IsHalftileSlope(tileh)); // Halftile slopes need to get handled earlier.
901  assert(tileh != SLOPE_FLAT); // Shore is never flat
902 
903  assert((tileh != SLOPE_EW) && (tileh != SLOPE_NS)); // No suitable sprites for current flooding behaviour
904 
905  DrawGroundSprite(SPR_SHORE_BASE + tileh_to_shoresprite[tileh], PAL_NONE);
906 }
907 
908 void DrawWaterClassGround(const TileInfo *ti)
909 {
910  switch (GetWaterClass(ti->tile)) {
911  case WATER_CLASS_SEA: DrawSeaWater(ti->tile); break;
912  case WATER_CLASS_CANAL: DrawCanalWater(ti->tile); break;
913  case WATER_CLASS_RIVER: DrawRiverWater(ti); break;
914  default: NOT_REACHED();
915  }
916 }
917 
918 static void DrawTile_Water(TileInfo *ti)
919 {
920  switch (GetWaterTileType(ti->tile)) {
921  case WATER_TILE_CLEAR:
922  DrawWaterClassGround(ti);
923  DrawBridgeMiddle(ti);
924  break;
925 
926  case WATER_TILE_COAST: {
927  DrawShoreTile(ti->tileh);
928  DrawBridgeMiddle(ti);
929  break;
930  }
931 
932  case WATER_TILE_LOCK:
933  DrawWaterLock(ti);
934  break;
935 
936  case WATER_TILE_DEPOT:
937  DrawWaterDepot(ti);
938  break;
939  }
940 }
941 
942 void DrawShipDepotSprite(int x, int y, Axis axis, DepotPart part)
943 {
944  const DrawTileSprites &dts = _shipdepot_display_data[axis][part];
945 
946  DrawSprite(dts.ground.sprite, dts.ground.pal, x, y);
947  DrawOrigTileSeqInGUI(x, y, &dts, COMPANY_SPRITE_COLOUR(_local_company));
948 }
949 
950 
951 static int GetSlopePixelZ_Water(TileIndex tile, uint x, uint y, bool)
952 {
953  auto [tileh, z] = GetTilePixelSlope(tile);
954 
955  return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
956 }
957 
958 static Foundation GetFoundation_Water(TileIndex, Slope)
959 {
960  return FOUNDATION_NONE;
961 }
962 
963 static void GetTileDesc_Water(TileIndex tile, TileDesc *td)
964 {
965  switch (GetWaterTileType(tile)) {
966  case WATER_TILE_CLEAR:
967  switch (GetWaterClass(tile)) {
968  case WATER_CLASS_SEA: td->str = STR_LAI_WATER_DESCRIPTION_WATER; break;
969  case WATER_CLASS_CANAL: td->str = STR_LAI_WATER_DESCRIPTION_CANAL; break;
970  case WATER_CLASS_RIVER: td->str = STR_LAI_WATER_DESCRIPTION_RIVER; break;
971  default: NOT_REACHED();
972  }
973  break;
974  case WATER_TILE_COAST: td->str = STR_LAI_WATER_DESCRIPTION_COAST_OR_RIVERBANK; break;
975  case WATER_TILE_LOCK : td->str = STR_LAI_WATER_DESCRIPTION_LOCK; break;
976  case WATER_TILE_DEPOT:
977  td->str = STR_LAI_WATER_DESCRIPTION_SHIP_DEPOT;
978  td->build_date = Depot::GetByTile(tile)->build_date;
979  break;
980  default: NOT_REACHED();
981  }
982 
983  td->owner[0] = GetTileOwner(tile);
984 }
985 
991 static void FloodVehicle(Vehicle *v)
992 {
993  uint victims = v->Crash(true);
994 
995  AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED, victims));
996  Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED, victims));
997  SetDParam(0, victims);
998  AddTileNewsItem(STR_NEWS_DISASTER_FLOOD_VEHICLE, NT_ACCIDENT, v->tile);
1000  if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
1001 }
1002 
1009 static Vehicle *FloodVehicleProc(Vehicle *v, void *data)
1010 {
1011  if ((v->vehstatus & VS_CRASHED) != 0) return nullptr;
1012 
1013  switch (v->type) {
1014  default: break;
1015 
1016  case VEH_AIRCRAFT: {
1017  if (!IsAirportTile(v->tile) || GetTileMaxZ(v->tile) != 0) break;
1018  if (v->subtype == AIR_SHADOW) break;
1019 
1020  /* We compare v->z_pos against delta_z + 1 because the shadow
1021  * is at delta_z and the actual aircraft at delta_z + 1. */
1022  const Station *st = Station::GetByTile(v->tile);
1023  const AirportFTAClass *airport = st->airport.GetFTA();
1024  if (v->z_pos != airport->delta_z + 1) break;
1025 
1026  FloodVehicle(v);
1027  break;
1028  }
1029 
1030  case VEH_TRAIN:
1031  case VEH_ROAD: {
1032  int z = *(int*)data;
1033  if (v->z_pos > z) break;
1034  FloodVehicle(v->First());
1035  break;
1036  }
1037  }
1038 
1039  return nullptr;
1040 }
1041 
1047 static void FloodVehicles(TileIndex tile)
1048 {
1049  int z = 0;
1050 
1051  if (IsAirportTile(tile)) {
1052  const Station *st = Station::GetByTile(tile);
1053  for (TileIndex airport_tile : st->airport) {
1054  if (st->TileBelongsToAirport(airport_tile)) FindVehicleOnPos(airport_tile, &z, &FloodVehicleProc);
1055  }
1056 
1057  /* No vehicle could be flooded on this airport anymore */
1058  return;
1059  }
1060 
1061  if (!IsBridgeTile(tile)) {
1062  FindVehicleOnPos(tile, &z, &FloodVehicleProc);
1063  return;
1064  }
1065 
1066  TileIndex end = GetOtherBridgeEnd(tile);
1067  z = GetBridgePixelHeight(tile);
1068 
1069  FindVehicleOnPos(tile, &z, &FloodVehicleProc);
1071 }
1072 
1079 {
1080  /* FLOOD_ACTIVE: 'single-corner-raised'-coast, sea, sea-shipdepots, sea-buoys, sea-docks (water part), rail with flooded halftile, sea-water-industries, sea-oilrigs
1081  * FLOOD_DRYUP: coast with more than one corner raised, coast with rail-track, coast with trees
1082  * FLOOD_PASSIVE: (not used)
1083  * FLOOD_NONE: canals, rivers, everything else
1084  */
1085  switch (GetTileType(tile)) {
1086  case MP_WATER:
1087  if (IsCoast(tile)) {
1088  Slope tileh = GetTileSlope(tile);
1090  }
1091  [[fallthrough]];
1092  case MP_STATION:
1093  case MP_INDUSTRY:
1094  case MP_OBJECT:
1095  return (GetWaterClass(tile) == WATER_CLASS_SEA) ? FLOOD_ACTIVE : FLOOD_NONE;
1096 
1097  case MP_RAILWAY:
1098  if (GetRailGroundType(tile) == RAIL_GROUND_WATER) {
1100  }
1101  return FLOOD_NONE;
1102 
1103  case MP_TREES:
1104  return (GetTreeGround(tile) == TREE_GROUND_SHORE ? FLOOD_DRYUP : FLOOD_NONE);
1105 
1106  case MP_VOID:
1107  return FLOOD_ACTIVE;
1108 
1109  default:
1110  return FLOOD_NONE;
1111  }
1112 }
1113 
1118 {
1119  assert(!IsTileType(target, MP_WATER));
1120 
1121  bool flooded = false; // Will be set to true if something is changed.
1122 
1124 
1125  Slope tileh = GetTileSlope(target);
1126  if (tileh != SLOPE_FLAT) {
1127  /* make coast.. */
1128  switch (GetTileType(target)) {
1129  case MP_RAILWAY: {
1130  if (!IsPlainRail(target)) break;
1131  FloodVehicles(target);
1132  flooded = FloodHalftile(target);
1133  break;
1134  }
1135 
1136  case MP_TREES:
1137  if (!IsSlopeWithOneCornerRaised(tileh)) {
1139  MarkTileDirtyByTile(target);
1140  flooded = true;
1141  break;
1142  }
1143  [[fallthrough]];
1144 
1145  case MP_CLEAR:
1146  if (Command<CMD_LANDSCAPE_CLEAR>::Do(DC_EXEC, target).Succeeded()) {
1147  MakeShore(target);
1148  MarkTileDirtyByTile(target);
1149  flooded = true;
1150  }
1151  break;
1152 
1153  default:
1154  break;
1155  }
1156  } else {
1157  /* Flood vehicles */
1158  FloodVehicles(target);
1159 
1160  /* flood flat tile */
1161  if (Command<CMD_LANDSCAPE_CLEAR>::Do(DC_EXEC, target).Succeeded()) {
1162  MakeSea(target);
1163  MarkTileDirtyByTile(target);
1164  flooded = true;
1165  }
1166  }
1167 
1168  if (flooded) {
1169  /* Mark surrounding canal tiles dirty too to avoid glitches */
1171 
1172  /* update signals if needed */
1174 
1175  if (IsPossibleDockingTile(target)) CheckForDockingTile(target);
1176  }
1177 
1178  cur_company.Restore();
1179 }
1180 
1184 static void DoDryUp(TileIndex tile)
1185 {
1187 
1188  switch (GetTileType(tile)) {
1189  case MP_RAILWAY:
1190  assert(IsPlainRail(tile));
1191  assert(GetRailGroundType(tile) == RAIL_GROUND_WATER);
1192 
1193  RailGroundType new_ground;
1194  switch (GetTrackBits(tile)) {
1195  case TRACK_BIT_UPPER: new_ground = RAIL_GROUND_FENCE_HORIZ1; break;
1196  case TRACK_BIT_LOWER: new_ground = RAIL_GROUND_FENCE_HORIZ2; break;
1197  case TRACK_BIT_LEFT: new_ground = RAIL_GROUND_FENCE_VERT1; break;
1198  case TRACK_BIT_RIGHT: new_ground = RAIL_GROUND_FENCE_VERT2; break;
1199  default: NOT_REACHED();
1200  }
1201  SetRailGroundType(tile, new_ground);
1202  MarkTileDirtyByTile(tile);
1203  break;
1204 
1205  case MP_TREES:
1207  MarkTileDirtyByTile(tile);
1208  break;
1209 
1210  case MP_WATER:
1211  assert(IsCoast(tile));
1212 
1213  if (Command<CMD_LANDSCAPE_CLEAR>::Do(DC_EXEC, tile).Succeeded()) {
1214  MakeClear(tile, CLEAR_GRASS, 3);
1215  MarkTileDirtyByTile(tile);
1216  }
1217  break;
1218 
1219  default: NOT_REACHED();
1220  }
1221 
1222  cur_company.Restore();
1223 }
1224 
1232 {
1233  if (IsTileType(tile, MP_WATER)) AmbientSoundEffect(tile);
1234 
1235  switch (GetFloodingBehaviour(tile)) {
1236  case FLOOD_ACTIVE:
1237  for (Direction dir = DIR_BEGIN; dir < DIR_END; dir++) {
1238  TileIndex dest = tile + TileOffsByDir(dir);
1239  if (!IsValidTile(dest)) continue;
1240  /* do not try to flood water tiles - increases performance a lot */
1241  if (IsTileType(dest, MP_WATER)) continue;
1242 
1243  /* TREE_GROUND_SHORE is the sign of a previous flood. */
1244  if (IsTileType(dest, MP_TREES) && GetTreeGround(dest) == TREE_GROUND_SHORE) continue;
1245 
1246  auto [slope_dest, z_dest] = GetFoundationSlope(dest);
1247  if (z_dest > 0) continue;
1248 
1249  if (!HasBit(_flood_from_dirs[slope_dest & ~SLOPE_HALFTILE_MASK & ~SLOPE_STEEP], ReverseDir(dir))) continue;
1250 
1251  DoFloodTile(dest);
1252  }
1253  break;
1254 
1255  case FLOOD_DRYUP: {
1256  Slope slope_here = std::get<0>(GetFoundationSlope(tile)) & ~SLOPE_HALFTILE_MASK & ~SLOPE_STEEP;
1257  for (uint dir : SetBitIterator(_flood_from_dirs[slope_here])) {
1258  TileIndex dest = tile + TileOffsByDir((Direction)dir);
1259  if (dest >= Map::Size()) continue;
1260 
1261  FloodingBehaviour dest_behaviour = GetFloodingBehaviour(dest);
1262  if ((dest_behaviour == FLOOD_ACTIVE) || (dest_behaviour == FLOOD_PASSIVE)) return;
1263  }
1264  DoDryUp(tile);
1265  break;
1266  }
1267 
1268  default: return;
1269  }
1270 }
1271 
1272 void ConvertGroundTilesIntoWaterTiles()
1273 {
1274  for (TileIndex tile = 0; tile < Map::Size(); ++tile) {
1275  auto [slope, z] = GetTileSlopeZ(tile);
1276  if (IsTileType(tile, MP_CLEAR) && z == 0) {
1277  /* Make both water for tiles at level 0
1278  * and make shore, as that looks much better
1279  * during the generation. */
1280  switch (slope) {
1281  case SLOPE_FLAT:
1282  MakeSea(tile);
1283  break;
1284 
1285  case SLOPE_N:
1286  case SLOPE_E:
1287  case SLOPE_S:
1288  case SLOPE_W:
1289  MakeShore(tile);
1290  break;
1291 
1292  default:
1293  for (uint dir : SetBitIterator(_flood_from_dirs[slope & ~SLOPE_STEEP])) {
1294  TileIndex dest = TileAddByDir(tile, (Direction)dir);
1295  Slope slope_dest = GetTileSlope(dest) & ~SLOPE_STEEP;
1296  if (slope_dest == SLOPE_FLAT || IsSlopeWithOneCornerRaised(slope_dest) || IsTileType(dest, MP_VOID)) {
1297  MakeShore(tile);
1298  break;
1299  }
1300  }
1301  break;
1302  }
1303  }
1304  }
1305 }
1306 
1307 static TrackStatus GetTileTrackStatus_Water(TileIndex tile, TransportType mode, uint, DiagDirection)
1308 {
1311 
1312  TrackBits ts;
1313 
1314  if (mode != TRANSPORT_WATER) return 0;
1315 
1316  switch (GetWaterTileType(tile)) {
1317  case WATER_TILE_CLEAR: ts = IsTileFlat(tile) ? TRACK_BIT_ALL : TRACK_BIT_NONE; break;
1318  case WATER_TILE_COAST: ts = coast_tracks[GetTileSlope(tile) & 0xF]; break;
1319  case WATER_TILE_LOCK: ts = DiagDirToDiagTrackBits(GetLockDirection(tile)); break;
1320  case WATER_TILE_DEPOT: ts = AxisToTrackBits(GetShipDepotAxis(tile)); break;
1321  default: return 0;
1322  }
1323  if (TileX(tile) == 0) {
1324  /* NE border: remove tracks that connects NE tile edge */
1326  }
1327  if (TileY(tile) == 0) {
1328  /* NW border: remove tracks that connects NW tile edge */
1330  }
1332 }
1333 
1334 static bool ClickTile_Water(TileIndex tile)
1335 {
1336  if (GetWaterTileType(tile) == WATER_TILE_DEPOT) {
1338  return true;
1339  }
1340  return false;
1341 }
1342 
1343 static void ChangeTileOwner_Water(TileIndex tile, Owner old_owner, Owner new_owner)
1344 {
1345  if (!IsTileOwner(tile, old_owner)) return;
1346 
1347  bool is_lock_middle = IsLock(tile) && GetLockPart(tile) == LOCK_PART_MIDDLE;
1348 
1349  /* No need to dirty company windows here, we'll redraw the whole screen anyway. */
1350  if (is_lock_middle) Company::Get(old_owner)->infrastructure.water -= 3 * LOCK_DEPOT_TILE_FACTOR; // Lock has three parts.
1351  if (new_owner != INVALID_OWNER) {
1352  if (is_lock_middle) Company::Get(new_owner)->infrastructure.water += 3 * LOCK_DEPOT_TILE_FACTOR; // Lock has three parts.
1353  /* Only subtract from the old owner here if the new owner is valid,
1354  * otherwise we clear ship depots and canal water below. */
1355  if (GetWaterClass(tile) == WATER_CLASS_CANAL && !is_lock_middle) {
1356  Company::Get(old_owner)->infrastructure.water--;
1357  Company::Get(new_owner)->infrastructure.water++;
1358  }
1359  if (IsShipDepot(tile)) {
1360  Company::Get(old_owner)->infrastructure.water -= LOCK_DEPOT_TILE_FACTOR;
1361  Company::Get(new_owner)->infrastructure.water += LOCK_DEPOT_TILE_FACTOR;
1362  }
1363 
1364  SetTileOwner(tile, new_owner);
1365  return;
1366  }
1367 
1368  /* Remove depot */
1370 
1371  /* Set owner of canals and locks ... and also canal under dock there was before.
1372  * Check if the new owner after removing depot isn't OWNER_WATER. */
1373  if (IsTileOwner(tile, old_owner)) {
1374  if (GetWaterClass(tile) == WATER_CLASS_CANAL && !is_lock_middle) Company::Get(old_owner)->infrastructure.water--;
1375  SetTileOwner(tile, OWNER_NONE);
1376  }
1377 }
1378 
1379 static VehicleEnterTileStatus VehicleEnter_Water(Vehicle *, TileIndex, int, int)
1380 {
1381  return VETSB_CONTINUE;
1382 }
1383 
1384 static CommandCost TerraformTile_Water(TileIndex tile, DoCommandFlag flags, int, Slope)
1385 {
1386  /* Canals can't be terraformed */
1387  if (IsWaterTile(tile) && IsCanal(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_CANAL_FIRST);
1388 
1389  return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
1390 }
1391 
1392 
1393 extern const TileTypeProcs _tile_type_water_procs = {
1394  DrawTile_Water, // draw_tile_proc
1395  GetSlopePixelZ_Water, // get_slope_z_proc
1396  ClearTile_Water, // clear_tile_proc
1397  nullptr, // add_accepted_cargo_proc
1398  GetTileDesc_Water, // get_tile_desc_proc
1399  GetTileTrackStatus_Water, // get_tile_track_status_proc
1400  ClickTile_Water, // click_tile_proc
1401  nullptr, // animate_tile_proc
1402  TileLoop_Water, // tile_loop_proc
1403  ChangeTileOwner_Water, // change_tile_owner_proc
1404  nullptr, // add_produced_cargo_proc
1405  VehicleEnter_Water, // vehicle_enter_tile_proc
1406  GetFoundation_Water, // get_foundation_proc
1407  TerraformTile_Water, // terraform_tile_proc
1408 };
SLOPE_E
@ SLOPE_E
the east corner of the tile is raised
Definition: slope_type.h:52
game.hpp
SLOPE_SE
@ SLOPE_SE
south and east corner are raised
Definition: slope_type.h:57
TileY
static debug_inline uint TileY(TileIndex tile)
Get the Y component of a tile.
Definition: map_func.h:437
TileInfo::z
int z
Height.
Definition: tile_cmd.h:48
MP_CLEAR
@ MP_CLEAR
A tile without any structures, i.e. grass, rocks, farm fields etc.
Definition: tile_type.h:48
IsTileFlat
bool IsTileFlat(TileIndex tile, int *h)
Check if a given tile is flat.
Definition: tile_map.cpp:95
FLOOD_DRYUP
@ FLOOD_DRYUP
The tile drys up if it is not constantly flooded from neighboured tiles.
Definition: water.h:23
TileOffsByDir
TileIndexDiff TileOffsByDir(Direction dir)
Convert a Direction to a TileIndexDiff.
Definition: map_func.h:579
LOCK_PART_UPPER
@ LOCK_PART_UPPER
Upper part of a lock.
Definition: water_map.h:76
TROPICZONE_DESERT
@ TROPICZONE_DESERT
Tile is desert.
Definition: tile_type.h:78
Station::docking_station
TileArea docking_station
Tile area the docking tiles cover.
Definition: station_base.h:455
ReverseDir
Direction ReverseDir(Direction d)
Return the reverse of a direction.
Definition: direction_func.h:54
sound_func.h
IsInclinedSlope
bool IsInclinedSlope(Slope s)
Tests if a specific slope is an inclined slope.
Definition: slope_func.h:228
DIR_SW
@ DIR_SW
Southwest.
Definition: direction_type.h:31
Pool::PoolItem<&_company_pool >::Get
static Titem * Get(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:339
GetOtherBridgeEnd
TileIndex GetOtherBridgeEnd(TileIndex tile)
Starting at one bridge end finds the other bridge end.
Definition: bridge_map.cpp:59
DIR_E
@ DIR_E
East.
Definition: direction_type.h:28
water.h
GetTileMaxZ
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition: tile_map.cpp:136
IsHalftileSlope
static constexpr bool IsHalftileSlope(Slope s)
Checks for non-continuous slope on halftile foundations.
Definition: slope_func.h:47
SPR_SHORE_BASE
static const SpriteID SPR_SHORE_BASE
shore tiles - action 05-0D
Definition: sprites.h:224
UpdateSignalsInBuffer
static SigSegState UpdateSignalsInBuffer(Owner owner)
Updates blocks in _globset buffer.
Definition: signal.cpp:482
command_func.h
IsInsideMM
constexpr bool IsInsideMM(const T x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition: math_func.hpp:268
GetLockPart
uint8_t GetLockPart(Tile t)
Get the part of a lock.
Definition: water_map.h:329
Pool::PoolItem<&_company_pool >::GetIfValid
static Titem * GetIfValid(size_t index)
Returns Titem with given index.
Definition: pool_type.hpp:350
CMD_ERROR
static const CommandCost CMD_ERROR
Define a default return value for a failed command.
Definition: command_func.h:28
TRACK_BIT_X
@ TRACK_BIT_X
X-axis track.
Definition: track_type.h:37
GetTreeGround
TreeGround GetTreeGround(Tile t)
Returns the groundtype for tree tiles.
Definition: tree_map.h:102
TO_BUILDINGS
@ TO_BUILDINGS
company buildings - depots, stations, HQ, ...
Definition: transparency.h:27
TileInfo
Tile information, used while rendering the tile.
Definition: tile_cmd.h:43
GetWaterClass
WaterClass GetWaterClass(Tile t)
Get the water class at a tile.
Definition: water_map.h:115
Backup
Class to backup a specific variable and restore it later.
Definition: backup_type.hpp:21
DIR_BEGIN
@ DIR_BEGIN
Used to iterate.
Definition: direction_type.h:25
Map::MaxX
static debug_inline uint MaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition: map_func.h:297
company_base.h
tunnelbridge_map.h
timer_game_calendar.h
DrawWaterLock
static void DrawWaterLock(const TileInfo *ti)
Draw a lock tile.
Definition: water_cmd.cpp:808
TileDesc::owner
Owner owner[4]
Name of the owner(s)
Definition: tile_cmd.h:55
SLOPE_NE
@ SLOPE_NE
north and east corner are raised
Definition: slope_type.h:58
WATER_CLASS_SEA
@ WATER_CLASS_SEA
Sea.
Definition: water_map.h:48
Station
Station data structure.
Definition: station_base.h:439
TRANSPORT_WATER
@ TRANSPORT_WATER
Transport over water.
Definition: transport_type.h:29
company_gui.h
GetTileSlope
Slope GetTileSlope(TileIndex tile)
Return the slope of a given tile inside the map.
Definition: tile_map.h:279
IsPlainRail
static debug_inline bool IsPlainRail(Tile t)
Returns whether this is plain rails, with or without signals.
Definition: rail_map.h:49
INVALID_OWNER
@ INVALID_OWNER
An invalid owner.
Definition: company_type.h:29
NT_ACCIDENT
@ NT_ACCIDENT
An accident or disaster has occurred.
Definition: news_type.h:26
FloodVehicles
static void FloodVehicles(TileIndex tile)
Finds a vehicle to flood.
Definition: water_cmd.cpp:1047
AmbientSoundEffect
void AmbientSoundEffect(TileIndex tile)
Play an ambient sound effect for an empty tile.
Definition: newgrf_generic.h:54
IsWateredTile
bool IsWateredTile(TileIndex tile, Direction from)
return true if a tile is a water tile wrt.
Definition: water_cmd.cpp:622
SLOPE_FLAT
@ SLOPE_FLAT
a flat tile
Definition: slope_type.h:49
Owner
Owner
Enum for all companies/owners.
Definition: company_type.h:18
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:48
depot_func.h
DIR_END
@ DIR_END
Used to iterate.
Definition: direction_type.h:34
TREE_GROUND_SHORE
@ TREE_GROUND_SHORE
shore
Definition: tree_map.h:56
Pool::PoolItem::index
Tindex index
Index of this pool item.
Definition: pool_type.hpp:238
Vehicle::Crash
virtual uint Crash(bool flooded=false)
Crash the (whole) vehicle chain.
Definition: vehicle.cpp:280
DiagDirToAxis
Axis DiagDirToAxis(DiagDirection d)
Convert a DiagDirection to the axis.
Definition: direction_func.h:214
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition: vehicle_type.h:24
TileAddXY
TileIndex TileAddXY(TileIndex tile, int x, int y)
Adds a given offset to a tile.
Definition: map_func.h:479
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:762
PalSpriteID::sprite
SpriteID sprite
The 'real' sprite.
Definition: gfx_type.h:24
DoBuildLock
static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag flags)
Builds a lock.
Definition: water_cmd.cpp:301
CLEAR_GRASS
@ CLEAR_GRASS
0-3
Definition: clear_map.h:20
INVALID_TILE
constexpr TileIndex INVALID_TILE
The very nice invalid tile marker.
Definition: tile_type.h:95
DIR_S
@ DIR_S
South.
Definition: direction_type.h:30
IsOilRig
bool IsOilRig(Tile t)
Is tile t part of an oilrig?
Definition: station_map.h:361
SND_12_EXPLOSION
@ SND_12_EXPLOSION
16 == 0x10 Destruction, crashes, disasters, ...
Definition: sound_type.h:55
RAIL_GROUND_FENCE_VERT1
@ RAIL_GROUND_FENCE_VERT1
Grass with a fence at the eastern side.
Definition: rail_map.h:494
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
GetCanalSpriteOffset
uint GetCanalSpriteOffset(CanalFeature feature, TileIndex tile, uint cur_offset)
Get the new sprite offset for a water tile.
Definition: newgrf_canal.cpp:171
VETSB_CONTINUE
@ VETSB_CONTINUE
Bit sets of the above specified bits.
Definition: tile_cmd.h:35
MP_RAILWAY
@ MP_RAILWAY
A railway.
Definition: tile_type.h:49
DrawWaterTileStruct
static void DrawWaterTileStruct(const TileInfo *ti, const DrawTileSeqStruct *dtss, SpriteID base, uint offset, PaletteID palette, CanalFeature feature)
Draw a build sprite sequence for water tiles.
Definition: water_cmd.cpp:791
GetPartialPixelZ
uint GetPartialPixelZ(int x, int y, Slope corners)
Determines height at given coordinate of a slope.
Definition: landscape.cpp:228
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition: vehicle_type.h:25
aircraft.h
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition: direction_type.h:73
DrawBridgeMiddle
void DrawBridgeMiddle(const TileInfo *ti)
Draw the middle bits of a bridge.
Definition: tunnelbridge_cmd.cpp:1541
Tile
Wrapper class to abstract away the way the tiles are stored.
Definition: map_func.h:25
water_land.h
SLOPE_NW
@ SLOPE_NW
north and west corner are raised
Definition: slope_type.h:55
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:56
RAIL_GROUND_FENCE_VERT2
@ RAIL_GROUND_FENCE_VERT2
Grass with a fence at the western side.
Definition: rail_map.h:495
DC_NO_WATER
@ DC_NO_WATER
don't allow building on water
Definition: command_type.h:379
CFF_HAS_FLAT_SPRITE
@ CFF_HAS_FLAT_SPRITE
Additional flat ground sprite in the beginning.
Definition: newgrf_canal.h:18
MP_INDUSTRY
@ MP_INDUSTRY
Part of an industry.
Definition: tile_type.h:56
town.h
TileInfo::y
int y
Y position of the tile in unit coordinates.
Definition: tile_cmd.h:45
OrthogonalTileArea::Add
void Add(TileIndex to_add)
Add a single tile to a tile area; enlarge if needed.
Definition: tilearea.cpp:43
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >
Company::infrastructure
CompanyInfrastructure infrastructure
NOSAVE: Counts of company owned infrastructure.
Definition: company_base.h:147
SLOPE_W
@ SLOPE_W
the west corner of the tile is raised
Definition: slope_type.h:50
IsWaterTile
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition: water_map.h:193
SLOPE_EW
@ SLOPE_EW
east and west corner are raised
Definition: slope_type.h:59
clear_map.h
Vehicle
Vehicle data structure.
Definition: vehicle_base.h:244
WATER_TILE_DEPOT
@ WATER_TILE_DEPOT
Water Depot.
Definition: water_map.h:43
Vehicle::owner
Owner owner
Which company owns the vehicle?
Definition: vehicle_base.h:309
EV_EXPLOSION_LARGE
@ EV_EXPLOSION_LARGE
Various explosions.
Definition: effectvehicle_func.h:22
DC_EXEC
@ DC_EXEC
execute the given command
Definition: command_type.h:376
PaletteID
uint32_t PaletteID
The number of the palette.
Definition: gfx_type.h:19
TileDesc
Tile description for the 'land area information' tool.
Definition: tile_cmd.h:52
DoCommandFlag
DoCommandFlag
List of flags for a command.
Definition: command_type.h:374
SLOPE_S
@ SLOPE_S
the south corner of the tile is raised
Definition: slope_type.h:51
Foundation
Foundation
Enumeration for Foundations.
Definition: slope_type.h:93
CmdBuildLock
CommandCost CmdBuildLock(DoCommandFlag flags, TileIndex tile)
Builds a lock.
Definition: water_cmd.cpp:423
IsLock
bool IsLock(Tile t)
Is there a lock on a given water tile?
Definition: water_map.h:306
EnsureNoVehicleOnGround
CommandCost EnsureNoVehicleOnGround(TileIndex tile)
Ensure there is no vehicle at the ground at the given position.
Definition: vehicle.cpp:546
newgrf_generic.h
Vehicle::vehstatus
uint8_t vehstatus
Status.
Definition: vehicle_base.h:354
AIR_SHADOW
@ AIR_SHADOW
shadow of the aircraft
Definition: aircraft.h:33
Industry::neutral_station
Station * neutral_station
Associated neutral station.
Definition: industry.h:98
CommandCost::Succeeded
bool Succeeded() const
Did this command succeed?
Definition: command_type.h:162
MakeSea
void MakeSea(Tile t)
Make a sea tile.
Definition: water_map.h:423
industry_map.h
DEPOT_PART_NORTH
@ DEPOT_PART_NORTH
Northern part of a depot.
Definition: water_map.h:67
GetTileTrackStatus
TrackStatus GetTileTrackStatus(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side)
Returns information about trackdirs and signal states.
Definition: landscape.cpp:553
effectvehicle_func.h
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:317
ai.hpp
IsCoast
bool IsCoast(Tile t)
Is it a coast tile?
Definition: water_map.h:204
GetOtherShipDepotTile
TileIndex GetOtherShipDepotTile(Tile t)
Get the other tile of the ship depot.
Definition: water_map.h:281
DiagDirToDiagTrackBits
TrackBits DiagDirToDiagTrackBits(DiagDirection diagdir)
Maps a (4-way) direction to the diagonal track bits incidating with that diagdir.
Definition: track_func.h:524
TileInfo::tileh
Slope tileh
Slope of the tile.
Definition: tile_cmd.h:46
GetTileType
static debug_inline TileType GetTileType(Tile tile)
Get the tiletype of a given tile.
Definition: tile_map.h:96
MakeClear
void MakeClear(Tile t, ClearGround g, uint density)
Make a clear tile.
Definition: clear_map.h:259
TRACK_BIT_NONE
@ TRACK_BIT_NONE
No track.
Definition: track_type.h:36
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:59
DrawTileSprites::ground
PalSpriteID ground
Palette and sprite for the ground.
Definition: sprite.h:59
IsDock
bool IsDock(Tile t)
Is tile t a dock tile?
Definition: station_map.h:372
TileDesc::build_date
TimerGameCalendar::Date build_date
Date of construction of tile contents.
Definition: tile_cmd.h:57
TransportType
TransportType
Available types of transport.
Definition: transport_type.h:19
WATER_TILE_COAST
@ WATER_TILE_COAST
Coast.
Definition: water_map.h:41
DIR_W
@ DIR_W
West.
Definition: direction_type.h:32
depot_base.h
landscape_cmd.h
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:505
return_cmd_error
#define return_cmd_error(errcode)
Returns from a function with a specific StringID as error.
Definition: command_func.h:38
TrackBitsToTrackdirBits
TrackdirBits TrackBitsToTrackdirBits(TrackBits bits)
Converts TrackBits to TrackdirBits while allowing both directions.
Definition: track_func.h:319
ToTileIndexDiff
TileIndexDiff ToTileIndexDiff(TileIndexDiffC tidc)
Return the offset between two tiles from a TileIndexDiffC struct.
Definition: map_func.h:452
GetLockDirection
DiagDirection GetLockDirection(Tile t)
Get the direction of the water lock.
Definition: water_map.h:317
AI::NewEvent
static void NewEvent(CompanyID company, ScriptEvent *event)
Queue a new event for an AI.
Definition: ai_core.cpp:243
CommandCost
Common return value for all commands.
Definition: command_type.h:23
SetBitIterator
Iterable ensemble of each set bit in a value.
Definition: bitmath_func.hpp:301
SLOPE_NS
@ SLOPE_NS
north and south corner are raised
Definition: slope_type.h:60
ClientSettings::sound
SoundSettings sound
sound effect settings
Definition: settings_type.h:614
CircularTileSearch
bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data)
Function performing a search around a center tile and going outward, thus in circle.
Definition: map.cpp:241
OWNER_NONE
@ OWNER_NONE
The tile has no ownership.
Definition: company_type.h:25
FloodVehicleProc
static Vehicle * FloodVehicleProc(Vehicle *v, void *data)
Flood a vehicle if we are allowed to flood it, i.e.
Definition: water_cmd.cpp:1009
Industry::GetByTile
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition: industry.h:240
WATER_TILE_CLEAR
@ WATER_TILE_CLEAR
Plain water.
Definition: water_map.h:40
TrackBits
TrackBits
Allow incrementing of Track variables.
Definition: track_type.h:35
INVALID_DIAGDIR
@ INVALID_DIAGDIR
Flag for an invalid DiagDirection.
Definition: direction_type.h:80
DirtyCompanyInfrastructureWindows
void DirtyCompanyInfrastructureWindows(CompanyID company)
Redraw all windows with company infrastructure counts.
Definition: company_gui.cpp:2584
GetTilePixelSlope
std::tuple< Slope, int > GetTilePixelSlope(TileIndex tile)
Return the slope of a given tile.
Definition: tile_map.h:289
Vehicle::tile
TileIndex tile
Current tile index.
Definition: vehicle_base.h:264
SLOPE_HALFTILE_MASK
@ SLOPE_HALFTILE_MASK
three bits used for halftile slopes
Definition: slope_type.h:72
DrawCanalWater
static void DrawCanalWater(TileIndex tile)
draw a canal styled water tile with dikes around
Definition: water_cmd.cpp:767
DIAGDIR_BEGIN
@ DIAGDIR_BEGIN
Used for iterations.
Definition: direction_type.h:74
MP_OBJECT
@ MP_OBJECT
Contains objects such as transmitters and owned land.
Definition: tile_type.h:58
VS_CRASHED
@ VS_CRASHED
Vehicle is crashed.
Definition: vehicle_base.h:40
DrawTileSeqStruct::delta_z
int8_t delta_z
0x80 identifies child sprites
Definition: sprite.h:28
_flood_from_dirs
static const uint8_t _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
TRACKDIR_BIT_NONE
@ TRACKDIR_BIT_NONE
No track build.
Definition: track_type.h:99
WATER_CLASS_INVALID
@ WATER_CLASS_INVALID
Used for industry tiles on land (also for oilrig if newgrf says so).
Definition: water_map.h:51
MP_WATER
@ MP_WATER
Water tile.
Definition: tile_type.h:54
ReverseDiagDir
DiagDirection ReverseDiagDir(DiagDirection d)
Returns the reverse direction of the given DiagDirection.
Definition: direction_func.h:118
CommandCost::Failed
bool Failed() const
Did this command fail?
Definition: command_type.h:171
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition: vehicle_type.h:26
RiverModifyDesertZone
bool RiverModifyDesertZone(TileIndex tile, void *)
Callback to create non-desert around a river tile.
Definition: water_cmd.cpp:432
TRACK_BIT_LEFT
@ TRACK_BIT_LEFT
Left track.
Definition: track_type.h:41
Station::airport
Airport airport
Tile area the airport covers.
Definition: station_base.h:453
water_regions.h
LOCK_PART_MIDDLE
@ LOCK_PART_MIDDLE
Middle part of a lock.
Definition: water_map.h:74
TileDiffXY
TileIndexDiff TileDiffXY(int x, int y)
Calculates an offset for the given coordinate(-offset).
Definition: map_func.h:401
_settings_game
GameSettings _settings_game
Game settings of a running game or the scenario editor.
Definition: settings.cpp:57
IsTileOnWater
bool IsTileOnWater(Tile t)
Tests if the tile was built on water.
Definition: water_map.h:139
_water_feature
WaterFeature _water_feature[CF_END]
Table of canal 'feature' sprite groups.
Definition: newgrf_canal.cpp:21
IsBridgeTile
bool IsBridgeTile(Tile t)
checks if there is a bridge on this tile
Definition: bridge_map.h:35
Game::NewEvent
static void NewEvent(class ScriptEvent *event)
Queue a new event for a Game Script.
Definition: game_core.cpp:146
DrawTileSeqStruct::IsTerminator
bool IsTerminator() const
Check whether this is a sequence terminator.
Definition: sprite.h:41
_local_company
CompanyID _local_company
Company controlled by the human player at this client. Can also be COMPANY_SPECTATOR.
Definition: company_cmd.cpp:52
GetIndustryIndex
IndustryID GetIndustryIndex(Tile t)
Get the industry ID of the given tile.
Definition: industry_map.h:63
industry.h
safeguards.h
ConstructionSettings::freeform_edges
bool freeform_edges
allow terraforming the tiles at the map edges
Definition: settings_type.h:395
GetCanalSprite
SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile)
Lookup the base sprite to use for a canal.
Definition: newgrf_canal.cpp:140
CommandCost::GetCost
Money GetCost() const
The costs as made up to this moment.
Definition: command_type.h:83
DirToDiagDir
DiagDirection DirToDiagDir(Direction dir)
Convert a Direction to a DiagDirection.
Definition: direction_func.h:166
DrawTileSprites
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:58
Depot::build_date
TimerGameCalendar::Date build_date
Date of construction.
Definition: depot_base.h:26
GetTileOwner
Owner GetTileOwner(Tile tile)
Returns the owner of a tile.
Definition: tile_map.h:178
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:988
MP_TUNNELBRIDGE
@ MP_TUNNELBRIDGE
Tunnel entry/exit and bridge heads.
Definition: tile_type.h:57
MakeCanal
void MakeCanal(Tile t, Owner o, uint8_t random_bits)
Make a canal tile.
Definition: water_map.h:444
AirportFTAClass
Finite sTate mAchine (FTA) of an airport.
Definition: airport.h:143
SoundSettings::disaster
bool disaster
Play disaster and accident sounds.
Definition: settings_type.h:250
TileIndexDiff
int32_t TileIndexDiff
An offset value between two tiles.
Definition: map_func.h:376
FOUNDATION_NONE
@ FOUNDATION_NONE
The tile has no foundation, the slope remains unchanged.
Definition: slope_type.h:94
DIR_NW
@ DIR_NW
Northwest.
Definition: direction_type.h:33
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
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
CombineTrackStatus
TrackStatus CombineTrackStatus(TrackdirBits trackdirbits, TrackdirBits red_signals)
Builds a TrackStatus.
Definition: track_func.h:388
SLOPE_N
@ SLOPE_N
the north corner of the tile is raised
Definition: slope_type.h:53
TrackStatusToTrackBits
TrackBits TrackStatusToTrackBits(TrackStatus ts)
Returns the present-track-information of a TrackStatus.
Definition: track_func.h:363
CommandCost::AddCost
void AddCost(const Money &cost)
Adds the given cost to the cost of the command.
Definition: command_type.h:63
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
IsValidAxis
bool IsValidAxis(Axis d)
Checks if an integer value is a valid Axis.
Definition: direction_func.h:43
stdafx.h
GetShipDepotPart
DepotPart GetShipDepotPart(Tile t)
Get the part of a ship depot.
Definition: water_map.h:258
TileAddByDir
TileIndex TileAddByDir(TileIndex tile, Direction dir)
Adds a Direction to a tile.
Definition: map_func.h:594
landscape.h
TileTypeProcs
Set of callback functions for performing tile operations of a given tile type.
Definition: tile_cmd.h:158
SetTileOwner
void SetTileOwner(Tile tile, Owner owner)
Sets the owner of a tile.
Definition: tile_map.h:198
SpriteID
uint32_t SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:18
DC_BANKRUPT
@ DC_BANKRUPT
company bankrupts, skip money check, skip vehicle on tile check in some cases
Definition: command_type.h:382
TileLoop_Water
void TileLoop_Water(TileIndex tile)
Let a water tile floods its diagonal adjoining tiles called from tunnelbridge_cmd,...
Definition: water_cmd.cpp:1231
viewport_func.h
RailGroundType
RailGroundType
The ground 'under' the rail.
Definition: rail_map.h:485
HasTileWaterClass
bool HasTileWaterClass(Tile t)
Checks whether the tile has an waterclass associated.
Definition: water_map.h:104
Vehicle::z_pos
int32_t z_pos
z coordinate.
Definition: vehicle_base.h:306
TRACK_BIT_ALL
@ TRACK_BIT_ALL
All possible tracks.
Definition: track_type.h:50
AddSortableSpriteToDraw
void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z, const SubSprite *sub)
Draw a (transparent) sprite at given coordinates with a given bounding box.
Definition: viewport.cpp:673
TREE_GROUND_GRASS
@ TREE_GROUND_GRASS
normal grass
Definition: tree_map.h:53
DIR_NE
@ DIR_NE
Northeast.
Definition: direction_type.h:27
AXIS_X
@ AXIS_X
The X axis.
Definition: direction_type.h:117
IsValidTile
bool IsValidTile(Tile tile)
Checks if a tile is valid.
Definition: tile_map.h:161
GetTrackBits
TrackBits GetTrackBits(Tile tile)
Gets the track bits of the given tile.
Definition: rail_map.h:136
RAIL_GROUND_WATER
@ RAIL_GROUND_WATER
Grass with a fence and shore or water on the free halftile.
Definition: rail_map.h:499
TileOffsByDiagDir
TileIndexDiff TileOffsByDiagDir(DiagDirection dir)
Convert a DiagDirection to a TileIndexDiff.
Definition: map_func.h:565
MP_TREES
@ MP_TREES
Tile got trees.
Definition: tile_type.h:52
TileIndexDiffC
A pair-construct of a TileIndexDiff.
Definition: map_type.h:31
CheckForDockingTile
void CheckForDockingTile(TileIndex t)
Mark the supplied tile as a docking tile if it is suitable for docking.
Definition: water_cmd.cpp:184
TRACK_BIT_UPPER
@ TRACK_BIT_UPPER
Upper track.
Definition: track_type.h:39
DEPOT_PART_SOUTH
@ DEPOT_PART_SOUTH
Southern part of a depot.
Definition: water_map.h:68
Vehicle::subtype
uint8_t subtype
subtype (Filled with values from AircraftSubType/DisasterSubType/EffectVehicleType/GroundVehicleSubty...
Definition: vehicle_base.h:355
MakeRiverAndModifyDesertZoneAround
void MakeRiverAndModifyDesertZoneAround(TileIndex tile)
Make a river tile and remove desert directly around it.
Definition: water_cmd.cpp:442
MakeDefaultName
void MakeDefaultName(T *obj)
Set the default name for a depot/waypoint.
Definition: town.h:253
_current_company
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:53
vehicle_func.h
FloodVehicle
static void FloodVehicle(Vehicle *v)
Handle the flooding of a vehicle.
Definition: water_cmd.cpp:991
FLOOD_PASSIVE
@ FLOOD_PASSIVE
The tile does not actively flood neighboured tiles, but it prevents them from drying up.
Definition: water.h:22
station_base.h
Map::MaxY
static uint MaxY()
Gets the maximum Y coordinate within the map, including MP_VOID.
Definition: map_func.h:306
strings_func.h
IsBuoy
bool IsBuoy(Tile t)
Is tile t a buoy tile?
Definition: station_map.h:393
Vehicle::First
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Definition: vehicle_base.h:645
RAIL_GROUND_FENCE_HORIZ1
@ RAIL_GROUND_FENCE_HORIZ1
Grass with a fence at the southern side.
Definition: rail_map.h:496
DC_FORCE_CLEAR_TILE
@ DC_FORCE_CLEAR_TILE
do not only remove the object on the tile, but also clear any water left on it
Definition: command_type.h:387
TRACK_BIT_RIGHT
@ TRACK_BIT_RIGHT
Right track.
Definition: track_type.h:42
WATER_CLASS_CANAL
@ WATER_CLASS_CANAL
Canal.
Definition: water_map.h:49
DoFloodTile
void DoFloodTile(TileIndex target)
Floods a tile.
Definition: water_cmd.cpp:1117
MP_VOID
@ MP_VOID
Invisible tiles at the SW and SE border.
Definition: tile_type.h:55
SLOPE_STEEP
@ SLOPE_STEEP
indicates the slope is steep
Definition: slope_type.h:54
Backup::Restore
void Restore()
Restore the variable.
Definition: backup_type.hpp:110
Slope
Slope
Enumeration for the slope-type.
Definition: slope_type.h:48
Axis
Axis
Allow incrementing of DiagDirDiff variables.
Definition: direction_type.h:116
Map::Size
static debug_inline uint Size()
Get the size of the map.
Definition: map_func.h:288
MakeShore
void MakeShore(Tile t)
Helper function to make a coast tile.
Definition: water_map.h:384
SetDParam
void SetDParam(size_t n, uint64_t v)
Set a string parameter v at index n in the global string parameter array.
Definition: strings.cpp:104
OWNER_WATER
@ OWNER_WATER
The tile/execution is done by "water".
Definition: company_type.h:26
SLOPE_SW
@ SLOPE_SW
south and west corner are raised
Definition: slope_type.h:56
tree_map.h
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:2054
SetDockingTile
void SetDockingTile(Tile t, bool b)
Set the docking tile state of a tile.
Definition: water_map.h:364
MP_STATION
@ MP_STATION
A tile of a station.
Definition: tile_type.h:53
FloodingBehaviour
FloodingBehaviour
Describes the behaviour of a tile during flooding.
Definition: water.h:19
SpecializedStation< Station, false >::GetByTile
static Station * GetByTile(TileIndex tile)
Get the station belonging to a specific tile.
Definition: base_station_base.h:273
RIVER_OFFSET_DESERT_DISTANCE
static const uint RIVER_OFFSET_DESERT_DISTANCE
Circular tile search radius to create non-desert around a river tile.
Definition: water.h:43
FindVehicleOnPos
void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc)
Find a vehicle from a specific location.
Definition: vehicle.cpp:505
FLOOD_NONE
@ FLOOD_NONE
The tile does not flood neighboured tiles.
Definition: water.h:20
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:309
DrawOrigTileSeqInGUI
void DrawOrigTileSeqInGUI(int x, int y, const DrawTileSprites *dts, PaletteID default_palette)
Draw TTD sprite sequence in GUI.
Definition: sprite.h:115
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
InvalidateWaterRegion
void InvalidateWaterRegion(TileIndex tile)
Marks the water region that tile is part of as invalid.
Definition: water_regions.cpp:311
AirportFTAClass::delta_z
uint8_t delta_z
Z adjustment for helicopter pads.
Definition: airport.h:183
DIAGDIR_END
@ DIAGDIR_END
Used for iterations.
Definition: direction_type.h:79
Direction
Direction
Defines the 8 directions on the map.
Definition: direction_type.h:24
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:382
IsBridgeAbove
bool IsBridgeAbove(Tile t)
checks if a bridge is set above the ground of this tile
Definition: bridge_map.h:45
TileDesc::str
StringID str
Description of the tile.
Definition: tile_cmd.h:53
TRACK_BIT_Y
@ TRACK_BIT_Y
Y-axis track.
Definition: track_type.h:38
DC_AUTO
@ DC_AUTO
don't allow building on structures
Definition: command_type.h:377
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:459
company_func.h
IsDockWaterPart
bool IsDockWaterPart(Tile t)
Check whether a dock tile is the tile on water.
Definition: station_map.h:598
LOCK_DEPOT_TILE_FACTOR
static const uint LOCK_DEPOT_TILE_FACTOR
Multiplier for how many regular tiles a lock counts.
Definition: economy_type.h:249
DrawWaterDepot
static void DrawWaterDepot(const TileInfo *ti)
Draw a ship depot tile.
Definition: water_cmd.cpp:847
GetShipDepotNorthTile
TileIndex GetShipDepotNorthTile(Tile t)
Get the most northern tile of a ship depot.
Definition: water_map.h:292
CheckTileOwnership
CommandCost CheckTileOwnership(TileIndex tile)
Check whether the current owner owns the stuff on the given tile.
Definition: company_cmd.cpp:381
CommandHelper
Definition: command_func.h:93
DrawTileSprites::seq
const DrawTileSeqStruct * seq
Array of child sprites. Terminated with a terminator entry.
Definition: sprite.h:60
FLOOD_ACTIVE
@ FLOOD_ACTIVE
The tile floods neighboured tiles.
Definition: water.h:21
Depot
Definition: depot_base.h:20
random_func.hpp
TileHeight
static debug_inline uint TileHeight(Tile tile)
Returns the height of a tile.
Definition: tile_map.h:29
newgrf_canal.h
OverflowSafeInt< int64_t >
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition: vehicle_type.h:27
RemoveLock
static CommandCost RemoveLock(TileIndex tile, DoCommandFlag flags)
Remove a lock.
Definition: water_cmd.cpp:379
TRACK_BIT_LOWER
@ TRACK_BIT_LOWER
Lower track.
Definition: track_type.h:40
GetFloodingBehaviour
FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
Returns the behaviour of a tile during flooding.
Definition: water_cmd.cpp:1078
DIR_SE
@ DIR_SE
Southeast.
Definition: direction_type.h:29
AxisToTrackBits
TrackBits AxisToTrackBits(Axis a)
Maps an Axis to the corresponding TrackBits value.
Definition: track_func.h:88
TileInfo::x
int x
X position of the tile in unit coordinates.
Definition: tile_cmd.h:44
RAIL_GROUND_FENCE_HORIZ2
@ RAIL_GROUND_FENCE_HORIZ2
Grass with a fence at the northern side.
Definition: rail_map.h:497
PalSpriteID::pal
PaletteID pal
The palette (use PAL_NONE) if not needed)
Definition: gfx_type.h:25
TimerGameCalendar::date
static Date date
Current date in days (day counter).
Definition: timer_game_calendar.h:34
TileInfo::tile
TileIndex tile
Tile index.
Definition: tile_cmd.h:47
GameSettings::construction
ConstructionSettings construction
construction of things in-game
Definition: settings_type.h:595
CmdBuildShipDepot
CommandCost CmdBuildShipDepot(DoCommandFlag flags, TileIndex tile, Axis axis)
Build a ship depot.
Definition: water_cmd.cpp:101
IsAirportTile
bool IsAirportTile(Tile t)
Is this tile a station tile and an airport tile?
Definition: station_map.h:167
IsDockTile
bool IsDockTile(Tile t)
Is tile t a dock tile?
Definition: station_map.h:382
IsTileType
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
Pool::PoolItem<&_company_pool >::IsValidID
static bool IsValidID(size_t index)
Tests whether given index can be used to get valid (non-nullptr) Titem.
Definition: pool_type.hpp:328
GetWaterTileType
WaterTileType GetWaterTileType(Tile t)
Get the water tile type at a tile.
Definition: water_map.h:86
BaseVehicle::type
VehicleType type
Type of vehicle.
Definition: vehicle_type.h:51
TROPICZONE_NORMAL
@ TROPICZONE_NORMAL
Normal tropiczone.
Definition: tile_type.h:77
TileX
static debug_inline uint TileX(TileIndex tile)
Get the X component of a tile.
Definition: map_func.h:427
DrawSeaWater
static void DrawSeaWater(TileIndex)
Draw a plain sea water tile with no edges.
Definition: water_cmd.cpp:761
GetBridgePixelHeight
int GetBridgePixelHeight(TileIndex tile)
Get the height ('z') of a bridge in pixels.
Definition: bridge_map.h:84
WATER_TILE_LOCK
@ WATER_TILE_LOCK
Water lock.
Definition: water_map.h:42
CmdBuildCanal
CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal)
Build a piece of canal.
Definition: water_cmd.cpp:460
DrawTileSeqStruct::delta_x
int8_t delta_x
0x80 is sequence terminator
Definition: sprite.h:26
WaterClass
WaterClass
classes of water (for WATER_TILE_CLEAR water tile type).
Definition: water_map.h:47
ShowDepotWindow
void ShowDepotWindow(TileIndex tile, VehicleType type)
Opens a depot window.
Definition: depot_gui.cpp:1141
Company
Definition: company_base.h:133
GetShipDepotAxis
Axis GetShipDepotAxis(Tile t)
Get the axis of the ship depot.
Definition: water_map.h:246
IsSlopeWithOneCornerRaised
bool IsSlopeWithOneCornerRaised(Slope s)
Tests if a specific slope has exactly one corner raised.
Definition: slope_func.h:88
IsCanal
bool IsCanal(Tile t)
Is it a canal tile?
Definition: water_map.h:172
IsTileOwner
bool IsTileOwner(Tile tile, Owner owner)
Checks if a tile belongs to the given owner.
Definition: tile_map.h:214
DepotPart
DepotPart
Sections of the water depot.
Definition: water_map.h:66
GetTropicZone
TropicZone GetTropicZone(Tile tile)
Get the tropic zone.
Definition: tile_map.h:238
WATER_CLASS_RIVER
@ WATER_CLASS_RIVER
River.
Definition: water_map.h:50
IsRiver
bool IsRiver(Tile t)
Is it a river water tile?
Definition: water_map.h:183
GetInclinedSlopeDirection
DiagDirection GetInclinedSlopeDirection(Slope s)
Returns the direction of an inclined slope.
Definition: slope_func.h:239
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:693
HasTileWaterGround
bool HasTileWaterGround(Tile t)
Checks whether the tile has water at the ground.
Definition: water_map.h:353
IsShipDepot
bool IsShipDepot(Tile t)
Is it a water tile with a ship depot on it?
Definition: water_map.h:225
SetTropicZone
void SetTropicZone(Tile tile, TropicZone type)
Set the tropic zone.
Definition: tile_map.h:225
CompanyInfrastructure::water
uint32_t water
Count of company owned track bits for canals.
Definition: company_base.h:36
GetTileSlopeZ
std::tuple< Slope, int > GetTileSlopeZ(TileIndex tile)
Return the slope of a given tile inside the map.
Definition: tile_map.cpp:55
DIR_N
@ DIR_N
North.
Definition: direction_type.h:26
VehicleEnterTileStatus
VehicleEnterTileStatus
The returned bits of VehicleEnterTile.
Definition: tile_cmd.h:21
IsValidWaterClass
bool IsValidWaterClass(WaterClass wc)
Checks if a water class is valid.
Definition: water_map.h:60
DrawWaterEdges
static void DrawWaterEdges(bool canal, uint offset, TileIndex tile)
Draw canal or river edges.
Definition: water_cmd.cpp:708
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:589
MarkTileDirtyIfCanalOrRiver
static void MarkTileDirtyIfCanalOrRiver(TileIndex tile)
Marks tile dirty if it is a canal or river tile.
Definition: water_cmd.cpp:75
news_func.h
GetTunnelBridgeDirection
DiagDirection GetTunnelBridgeDirection(Tile t)
Get the direction pointing to the other end.
Definition: tunnelbridge_map.h:26
water_cmd.h
DrawTileSeqStruct
A tile child sprite and palette to draw for stations etc, with 3D bounding box.
Definition: sprite.h:25
DoDryUp
static void DoDryUp(TileIndex tile)
Drys a tile up.
Definition: water_cmd.cpp:1184
EXPENSES_CONSTRUCTION
@ EXPENSES_CONSTRUCTION
Construction costs.
Definition: economy_type.h:173
backup_type.hpp
CanalFeature
CanalFeature
List of different canal 'features'.
Definition: newgrf.h:26
MakeRiver
void MakeRiver(Tile t, uint8_t random_bits)
Make a river tile.
Definition: water_map.h:433
HasBit
constexpr debug_inline bool HasBit(const T x, const uint8_t y)
Checks if a bit in a value is set.
Definition: bitmath_func.hpp:103