OpenTTD Source  14.1
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  int z;
214  Slope slope = GetTileSlope(tile, &z);
215 
216  if (slope != SLOPE_FLAT) {
217  if (wc == WATER_CLASS_CANAL) {
218  /* If we clear the canal, we have to remove it from the infrastructure count as well. */
220  if (c != nullptr) {
221  c->infrastructure.water--;
223  }
224  /* Sloped canals are locks and no natural water remains whatever the slope direction */
225  wc = WATER_CLASS_INVALID;
226  }
227 
228  /* Only river water should be restored on appropriate slopes. Other water would be invalid on slopes */
230  wc = WATER_CLASS_INVALID;
231  }
232  }
233 
234  if (wc == WATER_CLASS_SEA && z > 0) {
235  /* Update company infrastructure count. */
237  if (c != nullptr) {
238  c->infrastructure.water++;
240  }
241 
242  wc = WATER_CLASS_CANAL;
243  }
244 
245  /* Zero map array and terminate animation */
246  DoClearSquare(tile);
247 
248  /* Maybe change to water */
249  switch (wc) {
250  case WATER_CLASS_SEA: MakeSea(tile); break;
251  case WATER_CLASS_CANAL: MakeCanal(tile, o, Random()); break;
252  case WATER_CLASS_RIVER: MakeRiver(tile, Random()); break;
253  default: break;
254  }
255 
256  if (wc != WATER_CLASS_INVALID) CheckForDockingTile(tile);
257  MarkTileDirtyByTile(tile);
258 }
259 
260 static CommandCost RemoveShipDepot(TileIndex tile, DoCommandFlag flags)
261 {
262  if (!IsShipDepot(tile)) return CMD_ERROR;
263 
264  CommandCost ret = CheckTileOwnership(tile);
265  if (ret.Failed()) return ret;
266 
267  TileIndex tile2 = GetOtherShipDepotTile(tile);
268 
269  /* do not check for ship on tile when company goes bankrupt */
270  if (!(flags & DC_BANKRUPT)) {
271  ret = EnsureNoVehicleOnGround(tile);
272  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile2);
273  if (ret.Failed()) return ret;
274  }
275 
276  bool do_clear = (flags & DC_FORCE_CLEAR_TILE) != 0;
277 
278  if (flags & DC_EXEC) {
279  delete Depot::GetByTile(tile);
280 
282  if (c != nullptr) {
284  if (do_clear && GetWaterClass(tile) == WATER_CLASS_CANAL) c->infrastructure.water--;
286  }
287 
288  if (!do_clear) MakeWaterKeepingClass(tile, GetTileOwner(tile));
289  MakeWaterKeepingClass(tile2, GetTileOwner(tile2));
290  }
291 
292  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_DEPOT_SHIP]);
293 }
294 
303 {
305 
306  int delta = TileOffsByDiagDir(dir);
308  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile + delta);
309  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile - delta);
310  if (ret.Failed()) return ret;
311 
312  /* middle tile */
313  WaterClass wc_middle = HasTileWaterGround(tile) ? GetWaterClass(tile) : WATER_CLASS_CANAL;
314  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
315  if (ret.Failed()) return ret;
316  cost.AddCost(ret);
317 
318  /* lower tile */
319  if (!IsWaterTile(tile - delta)) {
320  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile - delta);
321  if (ret.Failed()) return ret;
322  cost.AddCost(ret);
323  cost.AddCost(_price[PR_BUILD_CANAL]);
324  }
325  if (!IsTileFlat(tile - delta)) {
326  return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
327  }
328  WaterClass wc_lower = IsWaterTile(tile - delta) ? GetWaterClass(tile - delta) : WATER_CLASS_CANAL;
329 
330  /* upper tile */
331  if (!IsWaterTile(tile + delta)) {
332  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile + delta);
333  if (ret.Failed()) return ret;
334  cost.AddCost(ret);
335  cost.AddCost(_price[PR_BUILD_CANAL]);
336  }
337  if (!IsTileFlat(tile + delta)) {
338  return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
339  }
340  WaterClass wc_upper = IsWaterTile(tile + delta) ? GetWaterClass(tile + delta) : WATER_CLASS_CANAL;
341 
342  if (IsBridgeAbove(tile) || IsBridgeAbove(tile - delta) || IsBridgeAbove(tile + delta)) {
343  return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
344  }
345 
346  if (flags & DC_EXEC) {
347  /* Update company infrastructure counts. */
349  if (c != nullptr) {
350  /* Counts for the water. */
351  if (!IsWaterTile(tile - delta)) c->infrastructure.water++;
352  if (!IsWaterTile(tile + delta)) c->infrastructure.water++;
353  /* Count for the lock itself. */
354  c->infrastructure.water += 3 * LOCK_DEPOT_TILE_FACTOR; // Lock is three tiles.
356  }
357 
358  MakeLock(tile, _current_company, dir, wc_lower, wc_upper, wc_middle);
359  CheckForDockingTile(tile - delta);
360  CheckForDockingTile(tile + delta);
361  MarkTileDirtyByTile(tile);
362  MarkTileDirtyByTile(tile - delta);
363  MarkTileDirtyByTile(tile + delta);
364  MarkCanalsAndRiversAroundDirty(tile - delta);
365  MarkCanalsAndRiversAroundDirty(tile + delta);
366  InvalidateWaterRegion(tile - delta);
367  InvalidateWaterRegion(tile + delta);
368  }
369  cost.AddCost(_price[PR_BUILD_LOCK]);
370 
371  return cost;
372 }
373 
381 {
382  if (GetTileOwner(tile) != OWNER_NONE) {
383  CommandCost ret = CheckTileOwnership(tile);
384  if (ret.Failed()) return ret;
385  }
386 
388 
389  /* make sure no vehicle is on the tile. */
391  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile + delta);
392  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile - delta);
393  if (ret.Failed()) return ret;
394 
395  if (flags & DC_EXEC) {
396  /* Remove middle part from company infrastructure count. */
398  if (c != nullptr) {
399  c->infrastructure.water -= 3 * LOCK_DEPOT_TILE_FACTOR; // three parts of the lock.
401  }
402 
403  if (GetWaterClass(tile) == WATER_CLASS_RIVER) {
404  MakeRiver(tile, Random());
405  } else {
406  DoClearSquare(tile);
407  }
408  MakeWaterKeepingClass(tile + delta, GetTileOwner(tile + delta));
409  MakeWaterKeepingClass(tile - delta, GetTileOwner(tile - delta));
411  MarkCanalsAndRiversAroundDirty(tile - delta);
412  MarkCanalsAndRiversAroundDirty(tile + delta);
413  }
414 
415  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_LOCK]);
416 }
417 
425 {
427  if (dir == INVALID_DIAGDIR) return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
428 
429  return DoBuildLock(tile, dir, flags);
430 }
431 
434 {
436  return false;
437 }
438 
444 {
445  MakeRiver(tile, Random());
446  MarkTileDirtyByTile(tile);
447 
448  /* Remove desert directly around the river tile. */
450 }
451 
461 CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal)
462 {
463  if (start_tile >= Map::Size() || !IsValidWaterClass(wc)) return CMD_ERROR;
464 
465  /* Outside of the editor you can only build canals, not oceans */
466  if (wc != WATER_CLASS_CANAL && _game_mode != GM_EDITOR) return CMD_ERROR;
467 
469 
470  std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
471  for (; *iter != INVALID_TILE; ++(*iter)) {
472  TileIndex current_tile = *iter;
473  CommandCost ret;
474 
475  Slope slope = GetTileSlope(current_tile);
476  if (slope != SLOPE_FLAT && (wc != WATER_CLASS_RIVER || !IsInclinedSlope(slope))) {
477  return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
478  }
479 
480  bool water = IsWaterTile(current_tile);
481 
482  /* Outside the editor, prevent building canals over your own or OWNER_NONE owned canals */
483  if (water && IsCanal(current_tile) && _game_mode != GM_EDITOR && (IsTileOwner(current_tile, _current_company) || IsTileOwner(current_tile, OWNER_NONE))) continue;
484 
485  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
486  if (ret.Failed()) return ret;
487 
488  if (!water) cost.AddCost(ret);
489 
490  if (flags & DC_EXEC) {
491  if (IsTileType(current_tile, MP_WATER) && IsCanal(current_tile)) {
492  Owner owner = GetTileOwner(current_tile);
493  if (Company::IsValidID(owner)) {
494  Company::Get(owner)->infrastructure.water--;
496  }
497  }
498 
499  switch (wc) {
500  case WATER_CLASS_RIVER:
501  MakeRiver(current_tile, Random());
502  if (_game_mode == GM_EDITOR) {
503  TileIndex tile2 = current_tile;
505  }
506  break;
507 
508  case WATER_CLASS_SEA:
509  if (TileHeight(current_tile) == 0) {
510  MakeSea(current_tile);
511  break;
512  }
513  [[fallthrough]];
514 
515  default:
516  MakeCanal(current_tile, _current_company, Random());
518  Company::Get(_current_company)->infrastructure.water++;
520  }
521  break;
522  }
523  MarkTileDirtyByTile(current_tile);
524  MarkCanalsAndRiversAroundDirty(current_tile);
525  CheckForDockingTile(current_tile);
526  }
527 
528  cost.AddCost(_price[PR_BUILD_CANAL]);
529  }
530 
531  if (cost.GetCost() == 0) {
532  return_cmd_error(STR_ERROR_ALREADY_BUILT);
533  } else {
534  return cost;
535  }
536 }
537 
538 
539 static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags)
540 {
541  switch (GetWaterTileType(tile)) {
542  case WATER_TILE_CLEAR: {
543  if (flags & DC_NO_WATER) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
544 
545  Money base_cost = IsCanal(tile) ? _price[PR_CLEAR_CANAL] : _price[PR_CLEAR_WATER];
546  /* Make sure freeform edges are allowed or it's not an edge tile. */
548  !IsInsideMM(TileY(tile), 1, Map::MaxY() - 1))) {
549  return_cmd_error(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP);
550  }
551 
552  /* Make sure no vehicle is on the tile */
554  if (ret.Failed()) return ret;
555 
556  Owner owner = GetTileOwner(tile);
557  if (owner != OWNER_WATER && owner != OWNER_NONE) {
558  ret = CheckTileOwnership(tile);
559  if (ret.Failed()) return ret;
560  }
561 
562  if (flags & DC_EXEC) {
563  if (IsCanal(tile) && Company::IsValidID(owner)) {
564  Company::Get(owner)->infrastructure.water--;
566  }
567  DoClearSquare(tile);
569  }
570 
571  return CommandCost(EXPENSES_CONSTRUCTION, base_cost);
572  }
573 
574  case WATER_TILE_COAST: {
575  Slope slope = GetTileSlope(tile);
576 
577  /* Make sure no vehicle is on the tile */
579  if (ret.Failed()) return ret;
580 
581  if (flags & DC_EXEC) {
582  DoClearSquare(tile);
584  }
585  if (IsSlopeWithOneCornerRaised(slope)) {
586  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_WATER]);
587  } else {
588  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_ROUGH]);
589  }
590  }
591 
592  case WATER_TILE_LOCK: {
593  static const TileIndexDiffC _lock_tomiddle_offs[][DIAGDIR_END] = {
594  /* NE SE SW NW */
595  { { 0, 0}, {0, 0}, { 0, 0}, {0, 0} }, // LOCK_PART_MIDDLE
596  { {-1, 0}, {0, 1}, { 1, 0}, {0, -1} }, // LOCK_PART_LOWER
597  { { 1, 0}, {0, -1}, {-1, 0}, {0, 1} }, // LOCK_PART_UPPER
598  };
599 
600  if (flags & DC_AUTO) return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
601  if (_current_company == OWNER_WATER) return CMD_ERROR;
602  /* move to the middle tile.. */
603  return RemoveLock(tile + ToTileIndexDiff(_lock_tomiddle_offs[GetLockPart(tile)][GetLockDirection(tile)]), flags);
604  }
605 
606  case WATER_TILE_DEPOT:
607  if (flags & DC_AUTO) return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
608  return RemoveShipDepot(tile, flags);
609 
610  default:
611  NOT_REACHED();
612  }
613 }
614 
624 {
625  switch (GetTileType(tile)) {
626  case MP_WATER:
627  switch (GetWaterTileType(tile)) {
628  default: NOT_REACHED();
629  case WATER_TILE_DEPOT: case WATER_TILE_CLEAR: return true;
631 
632  case WATER_TILE_COAST:
633  switch (GetTileSlope(tile)) {
634  case SLOPE_W: return (from == DIR_SE) || (from == DIR_E) || (from == DIR_NE);
635  case SLOPE_S: return (from == DIR_NE) || (from == DIR_N) || (from == DIR_NW);
636  case SLOPE_E: return (from == DIR_NW) || (from == DIR_W) || (from == DIR_SW);
637  case SLOPE_N: return (from == DIR_SW) || (from == DIR_S) || (from == DIR_SE);
638  default: return false;
639  }
640  }
641 
642  case MP_RAILWAY:
643  if (GetRailGroundType(tile) == RAIL_GROUND_WATER) {
644  assert(IsPlainRail(tile));
645  switch (GetTileSlope(tile)) {
646  case SLOPE_W: return (from == DIR_SE) || (from == DIR_E) || (from == DIR_NE);
647  case SLOPE_S: return (from == DIR_NE) || (from == DIR_N) || (from == DIR_NW);
648  case SLOPE_E: return (from == DIR_NW) || (from == DIR_W) || (from == DIR_SW);
649  case SLOPE_N: return (from == DIR_SW) || (from == DIR_S) || (from == DIR_SE);
650  default: return false;
651  }
652  }
653  return false;
654 
655  case MP_STATION:
656  if (IsOilRig(tile)) {
657  /* Do not draw waterborders inside of industries.
658  * Note: There is no easy way to detect the industry of an oilrig tile. */
659  TileIndex src_tile = tile + TileOffsByDir(from);
660  if ((IsTileType(src_tile, MP_STATION) && IsOilRig(src_tile)) ||
661  (IsTileType(src_tile, MP_INDUSTRY))) return true;
662 
663  return IsTileOnWater(tile);
664  }
665  return (IsDock(tile) && IsTileFlat(tile)) || IsBuoy(tile);
666 
667  case MP_INDUSTRY: {
668  /* Do not draw waterborders inside of industries.
669  * Note: There is no easy way to detect the industry of an oilrig tile. */
670  TileIndex src_tile = tile + TileOffsByDir(from);
671  if ((IsTileType(src_tile, MP_STATION) && IsOilRig(src_tile)) ||
672  (IsTileType(src_tile, MP_INDUSTRY) && GetIndustryIndex(src_tile) == GetIndustryIndex(tile))) return true;
673 
674  return IsTileOnWater(tile);
675  }
676 
677  case MP_OBJECT: return IsTileOnWater(tile);
678 
680 
681  case MP_VOID: return true; // consider map border as water, esp. for rivers
682 
683  default: return false;
684  }
685 }
686 
694 static void DrawWaterSprite(SpriteID base, uint offset, CanalFeature feature, TileIndex tile)
695 {
696  if (base != SPR_FLAT_WATER_TILE) {
697  /* Only call offset callback if the sprite is NewGRF-provided. */
698  offset = GetCanalSpriteOffset(feature, tile, offset);
699  }
700  DrawGroundSprite(base + offset, PAL_NONE);
701 }
702 
709 static void DrawWaterEdges(bool canal, uint offset, TileIndex tile)
710 {
711  CanalFeature feature;
712  SpriteID base = 0;
713  if (canal) {
714  feature = CF_DIKES;
715  base = GetCanalSprite(CF_DIKES, tile);
716  if (base == 0) base = SPR_CANAL_DIKES_BASE;
717  } else {
718  feature = CF_RIVER_EDGE;
719  base = GetCanalSprite(CF_RIVER_EDGE, tile);
720  if (base == 0) return; // Don't draw if no sprites provided.
721  }
722 
723  uint wa;
724 
725  /* determine the edges around with water. */
726  wa = IsWateredTile(TILE_ADDXY(tile, -1, 0), DIR_SW) << 0;
727  wa += IsWateredTile(TILE_ADDXY(tile, 0, 1), DIR_NW) << 1;
728  wa += IsWateredTile(TILE_ADDXY(tile, 1, 0), DIR_NE) << 2;
729  wa += IsWateredTile(TILE_ADDXY(tile, 0, -1), DIR_SE) << 3;
730 
731  if (!(wa & 1)) DrawWaterSprite(base, offset, feature, tile);
732  if (!(wa & 2)) DrawWaterSprite(base, offset + 1, feature, tile);
733  if (!(wa & 4)) DrawWaterSprite(base, offset + 2, feature, tile);
734  if (!(wa & 8)) DrawWaterSprite(base, offset + 3, feature, tile);
735 
736  /* right corner */
737  switch (wa & 0x03) {
738  case 0: DrawWaterSprite(base, offset + 4, feature, tile); break;
739  case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1), DIR_W)) DrawWaterSprite(base, offset + 8, feature, tile); break;
740  }
741 
742  /* bottom corner */
743  switch (wa & 0x06) {
744  case 0: DrawWaterSprite(base, offset + 5, feature, tile); break;
745  case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1), DIR_N)) DrawWaterSprite(base, offset + 9, feature, tile); break;
746  }
747 
748  /* left corner */
749  switch (wa & 0x0C) {
750  case 0: DrawWaterSprite(base, offset + 6, feature, tile); break;
751  case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1), DIR_E)) DrawWaterSprite(base, offset + 10, feature, tile); break;
752  }
753 
754  /* upper corner */
755  switch (wa & 0x09) {
756  case 0: DrawWaterSprite(base, offset + 7, feature, tile); break;
757  case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1), DIR_S)) DrawWaterSprite(base, offset + 11, feature, tile); break;
758  }
759 }
760 
763 {
764  DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
765 }
766 
768 static void DrawCanalWater(TileIndex tile)
769 {
770  SpriteID image = SPR_FLAT_WATER_TILE;
771  if (HasBit(_water_feature[CF_WATERSLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
772  /* First water slope sprite is flat water. */
773  image = GetCanalSprite(CF_WATERSLOPE, tile);
774  if (image == 0) image = SPR_FLAT_WATER_TILE;
775  }
776  DrawWaterSprite(image, 0, CF_WATERSLOPE, tile);
777 
778  DrawWaterEdges(true, 0, tile);
779 }
780 
781 #include "table/water_land.h"
782 
792 static void DrawWaterTileStruct(const TileInfo *ti, const DrawTileSeqStruct *dtss, SpriteID base, uint offset, PaletteID palette, CanalFeature feature)
793 {
794  /* Don't draw if buildings are invisible. */
795  if (IsInvisibilitySet(TO_BUILDINGS)) return;
796 
797  for (; !dtss->IsTerminator(); dtss++) {
798  uint tile_offs = offset + dtss->image.sprite;
799  if (feature < CF_END) tile_offs = GetCanalSpriteOffset(feature, ti->tile, tile_offs);
800  AddSortableSpriteToDraw(base + tile_offs, palette,
801  ti->x + dtss->delta_x, ti->y + dtss->delta_y,
802  dtss->size_x, dtss->size_y,
803  dtss->size_z, ti->z + dtss->delta_z,
805  }
806 }
807 
809 static void DrawWaterLock(const TileInfo *ti)
810 {
811  int part = GetLockPart(ti->tile);
812  const DrawTileSprites &dts = _lock_display_data[part][GetLockDirection(ti->tile)];
813 
814  /* Draw ground sprite. */
815  SpriteID image = dts.ground.sprite;
816 
817  SpriteID water_base = GetCanalSprite(CF_WATERSLOPE, ti->tile);
818  if (water_base == 0) {
819  /* Use default sprites. */
820  water_base = SPR_CANALS_BASE;
821  } else if (HasBit(_water_feature[CF_WATERSLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
822  /* NewGRF supplies a flat sprite as first sprite. */
823  if (image == SPR_FLAT_WATER_TILE) {
824  image = water_base;
825  } else {
826  image++;
827  }
828  }
829 
830  if (image < 5) image += water_base;
831  DrawGroundSprite(image, PAL_NONE);
832 
833  /* Draw structures. */
834  uint zoffs = 0;
835  SpriteID base = GetCanalSprite(CF_LOCKS, ti->tile);
836 
837  if (base == 0) {
838  /* If no custom graphics, use defaults. */
839  base = SPR_LOCK_BASE;
840  uint8_t z_threshold = part == LOCK_PART_UPPER ? 8 : 0;
841  zoffs = ti->z > z_threshold ? 24 : 0;
842  }
843 
844  DrawWaterTileStruct(ti, dts.seq, base, zoffs, PAL_NONE, CF_LOCKS);
845 }
846 
848 static void DrawWaterDepot(const TileInfo *ti)
849 {
850  DrawWaterClassGround(ti);
851  DrawWaterTileStruct(ti, _shipdepot_display_data[GetShipDepotAxis(ti->tile)][GetShipDepotPart(ti->tile)].seq, 0, 0, COMPANY_SPRITE_COLOUR(GetTileOwner(ti->tile)), CF_END);
852 }
853 
854 static void DrawRiverWater(const TileInfo *ti)
855 {
856  SpriteID image = SPR_FLAT_WATER_TILE;
857  uint offset = 0;
858  uint edges_offset = 0;
859 
860  if (ti->tileh != SLOPE_FLAT || HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
861  image = GetCanalSprite(CF_RIVER_SLOPE, ti->tile);
862  if (image == 0) {
863  switch (ti->tileh) {
864  case SLOPE_NW: image = SPR_WATER_SLOPE_Y_DOWN; break;
865  case SLOPE_SW: image = SPR_WATER_SLOPE_X_UP; break;
866  case SLOPE_SE: image = SPR_WATER_SLOPE_Y_UP; break;
867  case SLOPE_NE: image = SPR_WATER_SLOPE_X_DOWN; break;
868  default: image = SPR_FLAT_WATER_TILE; break;
869  }
870  } else {
871  /* Flag bit 0 indicates that the first sprite is flat water. */
872  offset = HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE) ? 1 : 0;
873 
874  switch (ti->tileh) {
875  case SLOPE_SE: edges_offset += 12; break;
876  case SLOPE_NE: offset += 1; edges_offset += 24; break;
877  case SLOPE_SW: offset += 2; edges_offset += 36; break;
878  case SLOPE_NW: offset += 3; edges_offset += 48; break;
879  default: offset = 0; break;
880  }
881 
882  offset = GetCanalSpriteOffset(CF_RIVER_SLOPE, ti->tile, offset);
883  }
884  }
885 
886  DrawGroundSprite(image + offset, PAL_NONE);
887 
888  /* Draw river edges if available. */
889  DrawWaterEdges(false, edges_offset, ti->tile);
890 }
891 
892 void DrawShoreTile(Slope tileh)
893 {
894  /* Converts the enum Slope into an offset based on SPR_SHORE_BASE.
895  * This allows to calculate the proper sprite to display for this Slope */
896  static const byte tileh_to_shoresprite[32] = {
897  0, 1, 2, 3, 4, 16, 6, 7, 8, 9, 17, 11, 12, 13, 14, 0,
898  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 10, 15, 0,
899  };
900 
901  assert(!IsHalftileSlope(tileh)); // Halftile slopes need to get handled earlier.
902  assert(tileh != SLOPE_FLAT); // Shore is never flat
903 
904  assert((tileh != SLOPE_EW) && (tileh != SLOPE_NS)); // No suitable sprites for current flooding behaviour
905 
906  DrawGroundSprite(SPR_SHORE_BASE + tileh_to_shoresprite[tileh], PAL_NONE);
907 }
908 
909 void DrawWaterClassGround(const TileInfo *ti)
910 {
911  switch (GetWaterClass(ti->tile)) {
912  case WATER_CLASS_SEA: DrawSeaWater(ti->tile); break;
913  case WATER_CLASS_CANAL: DrawCanalWater(ti->tile); break;
914  case WATER_CLASS_RIVER: DrawRiverWater(ti); break;
915  default: NOT_REACHED();
916  }
917 }
918 
919 static void DrawTile_Water(TileInfo *ti)
920 {
921  switch (GetWaterTileType(ti->tile)) {
922  case WATER_TILE_CLEAR:
923  DrawWaterClassGround(ti);
924  DrawBridgeMiddle(ti);
925  break;
926 
927  case WATER_TILE_COAST: {
928  DrawShoreTile(ti->tileh);
929  DrawBridgeMiddle(ti);
930  break;
931  }
932 
933  case WATER_TILE_LOCK:
934  DrawWaterLock(ti);
935  break;
936 
937  case WATER_TILE_DEPOT:
938  DrawWaterDepot(ti);
939  break;
940  }
941 }
942 
943 void DrawShipDepotSprite(int x, int y, Axis axis, DepotPart part)
944 {
945  const DrawTileSprites &dts = _shipdepot_display_data[axis][part];
946 
947  DrawSprite(dts.ground.sprite, dts.ground.pal, x, y);
948  DrawOrigTileSeqInGUI(x, y, &dts, COMPANY_SPRITE_COLOUR(_local_company));
949 }
950 
951 
952 static int GetSlopePixelZ_Water(TileIndex tile, uint x, uint y, bool)
953 {
954  int z;
955  Slope tileh = GetTilePixelSlope(tile, &z);
956 
957  return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
958 }
959 
960 static Foundation GetFoundation_Water(TileIndex, Slope)
961 {
962  return FOUNDATION_NONE;
963 }
964 
965 static void GetTileDesc_Water(TileIndex tile, TileDesc *td)
966 {
967  switch (GetWaterTileType(tile)) {
968  case WATER_TILE_CLEAR:
969  switch (GetWaterClass(tile)) {
970  case WATER_CLASS_SEA: td->str = STR_LAI_WATER_DESCRIPTION_WATER; break;
971  case WATER_CLASS_CANAL: td->str = STR_LAI_WATER_DESCRIPTION_CANAL; break;
972  case WATER_CLASS_RIVER: td->str = STR_LAI_WATER_DESCRIPTION_RIVER; break;
973  default: NOT_REACHED();
974  }
975  break;
976  case WATER_TILE_COAST: td->str = STR_LAI_WATER_DESCRIPTION_COAST_OR_RIVERBANK; break;
977  case WATER_TILE_LOCK : td->str = STR_LAI_WATER_DESCRIPTION_LOCK; break;
978  case WATER_TILE_DEPOT:
979  td->str = STR_LAI_WATER_DESCRIPTION_SHIP_DEPOT;
980  td->build_date = Depot::GetByTile(tile)->build_date;
981  break;
982  default: NOT_REACHED();
983  }
984 
985  td->owner[0] = GetTileOwner(tile);
986 }
987 
993 static void FloodVehicle(Vehicle *v)
994 {
995  uint pass = v->Crash(true);
996 
997  AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED));
998  Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED));
999  SetDParam(0, pass);
1000  AddTileNewsItem(STR_NEWS_DISASTER_FLOOD_VEHICLE, NT_ACCIDENT, v->tile);
1002  if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
1003 }
1004 
1011 static Vehicle *FloodVehicleProc(Vehicle *v, void *data)
1012 {
1013  if ((v->vehstatus & VS_CRASHED) != 0) return nullptr;
1014 
1015  switch (v->type) {
1016  default: break;
1017 
1018  case VEH_AIRCRAFT: {
1019  if (!IsAirportTile(v->tile) || GetTileMaxZ(v->tile) != 0) break;
1020  if (v->subtype == AIR_SHADOW) break;
1021 
1022  /* We compare v->z_pos against delta_z + 1 because the shadow
1023  * is at delta_z and the actual aircraft at delta_z + 1. */
1024  const Station *st = Station::GetByTile(v->tile);
1025  const AirportFTAClass *airport = st->airport.GetFTA();
1026  if (v->z_pos != airport->delta_z + 1) break;
1027 
1028  FloodVehicle(v);
1029  break;
1030  }
1031 
1032  case VEH_TRAIN:
1033  case VEH_ROAD: {
1034  int z = *(int*)data;
1035  if (v->z_pos > z) break;
1036  FloodVehicle(v->First());
1037  break;
1038  }
1039  }
1040 
1041  return nullptr;
1042 }
1043 
1049 static void FloodVehicles(TileIndex tile)
1050 {
1051  int z = 0;
1052 
1053  if (IsAirportTile(tile)) {
1054  const Station *st = Station::GetByTile(tile);
1055  for (TileIndex airport_tile : st->airport) {
1056  if (st->TileBelongsToAirport(airport_tile)) FindVehicleOnPos(airport_tile, &z, &FloodVehicleProc);
1057  }
1058 
1059  /* No vehicle could be flooded on this airport anymore */
1060  return;
1061  }
1062 
1063  if (!IsBridgeTile(tile)) {
1064  FindVehicleOnPos(tile, &z, &FloodVehicleProc);
1065  return;
1066  }
1067 
1068  TileIndex end = GetOtherBridgeEnd(tile);
1069  z = GetBridgePixelHeight(tile);
1070 
1071  FindVehicleOnPos(tile, &z, &FloodVehicleProc);
1073 }
1074 
1081 {
1082  /* FLOOD_ACTIVE: 'single-corner-raised'-coast, sea, sea-shipdepots, sea-buoys, sea-docks (water part), rail with flooded halftile, sea-water-industries, sea-oilrigs
1083  * FLOOD_DRYUP: coast with more than one corner raised, coast with rail-track, coast with trees
1084  * FLOOD_PASSIVE: (not used)
1085  * FLOOD_NONE: canals, rivers, everything else
1086  */
1087  switch (GetTileType(tile)) {
1088  case MP_WATER:
1089  if (IsCoast(tile)) {
1090  Slope tileh = GetTileSlope(tile);
1092  }
1093  [[fallthrough]];
1094  case MP_STATION:
1095  case MP_INDUSTRY:
1096  case MP_OBJECT:
1097  return (GetWaterClass(tile) == WATER_CLASS_SEA) ? FLOOD_ACTIVE : FLOOD_NONE;
1098 
1099  case MP_RAILWAY:
1100  if (GetRailGroundType(tile) == RAIL_GROUND_WATER) {
1102  }
1103  return FLOOD_NONE;
1104 
1105  case MP_TREES:
1106  return (GetTreeGround(tile) == TREE_GROUND_SHORE ? FLOOD_DRYUP : FLOOD_NONE);
1107 
1108  case MP_VOID:
1109  return FLOOD_ACTIVE;
1110 
1111  default:
1112  return FLOOD_NONE;
1113  }
1114 }
1115 
1120 {
1121  assert(!IsTileType(target, MP_WATER));
1122 
1123  bool flooded = false; // Will be set to true if something is changed.
1124 
1125  Backup<CompanyID> cur_company(_current_company, OWNER_WATER, FILE_LINE);
1126 
1127  Slope tileh = GetTileSlope(target);
1128  if (tileh != SLOPE_FLAT) {
1129  /* make coast.. */
1130  switch (GetTileType(target)) {
1131  case MP_RAILWAY: {
1132  if (!IsPlainRail(target)) break;
1133  FloodVehicles(target);
1134  flooded = FloodHalftile(target);
1135  break;
1136  }
1137 
1138  case MP_TREES:
1139  if (!IsSlopeWithOneCornerRaised(tileh)) {
1141  MarkTileDirtyByTile(target);
1142  flooded = true;
1143  break;
1144  }
1145  [[fallthrough]];
1146 
1147  case MP_CLEAR:
1148  if (Command<CMD_LANDSCAPE_CLEAR>::Do(DC_EXEC, target).Succeeded()) {
1149  MakeShore(target);
1150  MarkTileDirtyByTile(target);
1151  flooded = true;
1152  }
1153  break;
1154 
1155  default:
1156  break;
1157  }
1158  } else {
1159  /* Flood vehicles */
1160  FloodVehicles(target);
1161 
1162  /* flood flat tile */
1163  if (Command<CMD_LANDSCAPE_CLEAR>::Do(DC_EXEC, target).Succeeded()) {
1164  MakeSea(target);
1165  MarkTileDirtyByTile(target);
1166  flooded = true;
1167  }
1168  }
1169 
1170  if (flooded) {
1171  /* Mark surrounding canal tiles dirty too to avoid glitches */
1173 
1174  /* update signals if needed */
1176 
1177  if (IsPossibleDockingTile(target)) CheckForDockingTile(target);
1178  }
1179 
1180  cur_company.Restore();
1181 }
1182 
1186 static void DoDryUp(TileIndex tile)
1187 {
1188  Backup<CompanyID> cur_company(_current_company, OWNER_WATER, FILE_LINE);
1189 
1190  switch (GetTileType(tile)) {
1191  case MP_RAILWAY:
1192  assert(IsPlainRail(tile));
1193  assert(GetRailGroundType(tile) == RAIL_GROUND_WATER);
1194 
1195  RailGroundType new_ground;
1196  switch (GetTrackBits(tile)) {
1197  case TRACK_BIT_UPPER: new_ground = RAIL_GROUND_FENCE_HORIZ1; break;
1198  case TRACK_BIT_LOWER: new_ground = RAIL_GROUND_FENCE_HORIZ2; break;
1199  case TRACK_BIT_LEFT: new_ground = RAIL_GROUND_FENCE_VERT1; break;
1200  case TRACK_BIT_RIGHT: new_ground = RAIL_GROUND_FENCE_VERT2; break;
1201  default: NOT_REACHED();
1202  }
1203  SetRailGroundType(tile, new_ground);
1204  MarkTileDirtyByTile(tile);
1205  break;
1206 
1207  case MP_TREES:
1209  MarkTileDirtyByTile(tile);
1210  break;
1211 
1212  case MP_WATER:
1213  assert(IsCoast(tile));
1214 
1215  if (Command<CMD_LANDSCAPE_CLEAR>::Do(DC_EXEC, tile).Succeeded()) {
1216  MakeClear(tile, CLEAR_GRASS, 3);
1217  MarkTileDirtyByTile(tile);
1218  }
1219  break;
1220 
1221  default: NOT_REACHED();
1222  }
1223 
1224  cur_company.Restore();
1225 }
1226 
1234 {
1235  if (IsTileType(tile, MP_WATER)) AmbientSoundEffect(tile);
1236 
1237  switch (GetFloodingBehaviour(tile)) {
1238  case FLOOD_ACTIVE:
1239  for (Direction dir = DIR_BEGIN; dir < DIR_END; dir++) {
1240  TileIndex dest = tile + TileOffsByDir(dir);
1241  if (!IsValidTile(dest)) continue;
1242  /* do not try to flood water tiles - increases performance a lot */
1243  if (IsTileType(dest, MP_WATER)) continue;
1244 
1245  /* TREE_GROUND_SHORE is the sign of a previous flood. */
1246  if (IsTileType(dest, MP_TREES) && GetTreeGround(dest) == TREE_GROUND_SHORE) continue;
1247 
1248  int z_dest;
1249  Slope slope_dest = GetFoundationSlope(dest, &z_dest) & ~SLOPE_HALFTILE_MASK & ~SLOPE_STEEP;
1250  if (z_dest > 0) continue;
1251 
1252  if (!HasBit(_flood_from_dirs[slope_dest], ReverseDir(dir))) continue;
1253 
1254  DoFloodTile(dest);
1255  }
1256  break;
1257 
1258  case FLOOD_DRYUP: {
1259  Slope slope_here = GetFoundationSlope(tile) & ~SLOPE_HALFTILE_MASK & ~SLOPE_STEEP;
1260  for (uint dir : SetBitIterator(_flood_from_dirs[slope_here])) {
1261  TileIndex dest = tile + TileOffsByDir((Direction)dir);
1262  if (dest >= Map::Size()) continue;
1263 
1264  FloodingBehaviour dest_behaviour = GetFloodingBehaviour(dest);
1265  if ((dest_behaviour == FLOOD_ACTIVE) || (dest_behaviour == FLOOD_PASSIVE)) return;
1266  }
1267  DoDryUp(tile);
1268  break;
1269  }
1270 
1271  default: return;
1272  }
1273 }
1274 
1275 void ConvertGroundTilesIntoWaterTiles()
1276 {
1277  int z;
1278 
1279  for (TileIndex tile = 0; tile < Map::Size(); ++tile) {
1280  Slope slope = GetTileSlope(tile, &z);
1281  if (IsTileType(tile, MP_CLEAR) && z == 0) {
1282  /* Make both water for tiles at level 0
1283  * and make shore, as that looks much better
1284  * during the generation. */
1285  switch (slope) {
1286  case SLOPE_FLAT:
1287  MakeSea(tile);
1288  break;
1289 
1290  case SLOPE_N:
1291  case SLOPE_E:
1292  case SLOPE_S:
1293  case SLOPE_W:
1294  MakeShore(tile);
1295  break;
1296 
1297  default:
1298  for (uint dir : SetBitIterator(_flood_from_dirs[slope & ~SLOPE_STEEP])) {
1299  TileIndex dest = TileAddByDir(tile, (Direction)dir);
1300  Slope slope_dest = GetTileSlope(dest) & ~SLOPE_STEEP;
1301  if (slope_dest == SLOPE_FLAT || IsSlopeWithOneCornerRaised(slope_dest) || IsTileType(dest, MP_VOID)) {
1302  MakeShore(tile);
1303  break;
1304  }
1305  }
1306  break;
1307  }
1308  }
1309  }
1310 }
1311 
1312 static TrackStatus GetTileTrackStatus_Water(TileIndex tile, TransportType mode, uint, DiagDirection)
1313 {
1316 
1317  TrackBits ts;
1318 
1319  if (mode != TRANSPORT_WATER) return 0;
1320 
1321  switch (GetWaterTileType(tile)) {
1322  case WATER_TILE_CLEAR: ts = IsTileFlat(tile) ? TRACK_BIT_ALL : TRACK_BIT_NONE; break;
1323  case WATER_TILE_COAST: ts = coast_tracks[GetTileSlope(tile) & 0xF]; break;
1324  case WATER_TILE_LOCK: ts = DiagDirToDiagTrackBits(GetLockDirection(tile)); break;
1325  case WATER_TILE_DEPOT: ts = AxisToTrackBits(GetShipDepotAxis(tile)); break;
1326  default: return 0;
1327  }
1328  if (TileX(tile) == 0) {
1329  /* NE border: remove tracks that connects NE tile edge */
1331  }
1332  if (TileY(tile) == 0) {
1333  /* NW border: remove tracks that connects NW tile edge */
1335  }
1337 }
1338 
1339 static bool ClickTile_Water(TileIndex tile)
1340 {
1341  if (GetWaterTileType(tile) == WATER_TILE_DEPOT) {
1343  return true;
1344  }
1345  return false;
1346 }
1347 
1348 static void ChangeTileOwner_Water(TileIndex tile, Owner old_owner, Owner new_owner)
1349 {
1350  if (!IsTileOwner(tile, old_owner)) return;
1351 
1352  bool is_lock_middle = IsLock(tile) && GetLockPart(tile) == LOCK_PART_MIDDLE;
1353 
1354  /* No need to dirty company windows here, we'll redraw the whole screen anyway. */
1355  if (is_lock_middle) Company::Get(old_owner)->infrastructure.water -= 3 * LOCK_DEPOT_TILE_FACTOR; // Lock has three parts.
1356  if (new_owner != INVALID_OWNER) {
1357  if (is_lock_middle) Company::Get(new_owner)->infrastructure.water += 3 * LOCK_DEPOT_TILE_FACTOR; // Lock has three parts.
1358  /* Only subtract from the old owner here if the new owner is valid,
1359  * otherwise we clear ship depots and canal water below. */
1360  if (GetWaterClass(tile) == WATER_CLASS_CANAL && !is_lock_middle) {
1361  Company::Get(old_owner)->infrastructure.water--;
1362  Company::Get(new_owner)->infrastructure.water++;
1363  }
1364  if (IsShipDepot(tile)) {
1365  Company::Get(old_owner)->infrastructure.water -= LOCK_DEPOT_TILE_FACTOR;
1366  Company::Get(new_owner)->infrastructure.water += LOCK_DEPOT_TILE_FACTOR;
1367  }
1368 
1369  SetTileOwner(tile, new_owner);
1370  return;
1371  }
1372 
1373  /* Remove depot */
1375 
1376  /* Set owner of canals and locks ... and also canal under dock there was before.
1377  * Check if the new owner after removing depot isn't OWNER_WATER. */
1378  if (IsTileOwner(tile, old_owner)) {
1379  if (GetWaterClass(tile) == WATER_CLASS_CANAL && !is_lock_middle) Company::Get(old_owner)->infrastructure.water--;
1380  SetTileOwner(tile, OWNER_NONE);
1381  }
1382 }
1383 
1384 static VehicleEnterTileStatus VehicleEnter_Water(Vehicle *, TileIndex, int, int)
1385 {
1386  return VETSB_CONTINUE;
1387 }
1388 
1389 static CommandCost TerraformTile_Water(TileIndex tile, DoCommandFlag flags, int, Slope)
1390 {
1391  /* Canals can't be terraformed */
1392  if (IsWaterTile(tile) && IsCanal(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_CANAL_FIRST);
1393 
1394  return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
1395 }
1396 
1397 
1398 extern const TileTypeProcs _tile_type_water_procs = {
1399  DrawTile_Water, // draw_tile_proc
1400  GetSlopePixelZ_Water, // get_slope_z_proc
1401  ClearTile_Water, // clear_tile_proc
1402  nullptr, // add_accepted_cargo_proc
1403  GetTileDesc_Water, // get_tile_desc_proc
1404  GetTileTrackStatus_Water, // get_tile_track_status_proc
1405  ClickTile_Water, // click_tile_proc
1406  nullptr, // animate_tile_proc
1407  TileLoop_Water, // tile_loop_proc
1408  ChangeTileOwner_Water, // change_tile_owner_proc
1409  nullptr, // add_produced_cargo_proc
1410  VehicleEnter_Water, // vehicle_enter_tile_proc
1411  GetFoundation_Water, // get_foundation_proc
1412  TerraformTile_Water, // terraform_tile_proc
1413 };
VEH_AIRCRAFT
@ VEH_AIRCRAFT
Aircraft vehicle type.
Definition: vehicle_type.h:27
game.hpp
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:100
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:577
SLOPE_SE
@ SLOPE_SE
south and east corner are raised
Definition: slope_type.h:57
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:458
ReverseDir
Direction ReverseDir(Direction d)
Return the reverse of a direction.
Definition: direction_func.h:54
DIR_SW
@ DIR_SW
Southwest.
Definition: direction_type.h:31
sound_func.h
IsInclinedSlope
bool IsInclinedSlope(Slope s)
Tests if a specific slope is an inclined slope.
Definition: slope_func.h:228
TRACK_BIT_NONE
@ TRACK_BIT_NONE
No track.
Definition: track_type.h:36
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
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
water.h
GetTileMaxZ
int GetTileMaxZ(TileIndex t)
Get top height of the tile inside the map.
Definition: tile_map.cpp:141
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:468
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
DIR_SE
@ DIR_SE
Southeast.
Definition: direction_type.h:29
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
GetTreeGround
TreeGround GetTreeGround(Tile t)
Returns the groundtype for tree tiles.
Definition: tree_map.h:88
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
Map::MaxX
static debug_inline uint MaxX()
Gets the maximum X coordinate within the map, including MP_VOID.
Definition: map_func.h:297
GetLockPart
byte GetLockPart(Tile t)
Get the part of a lock.
Definition: water_map.h:329
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:809
TileDesc::owner
Owner owner[4]
Name of the owner(s)
Definition: tile_cmd.h:55
Axis
Axis
Allow incrementing of DiagDirDiff variables.
Definition: direction_type.h:116
SLOPE_NW
@ SLOPE_NW
north and west corner are raised
Definition: slope_type.h:55
Station
Station data structure.
Definition: station_base.h:442
company_gui.h
IsPlainRail
static debug_inline bool IsPlainRail(Tile t)
Returns whether this is plain rails, with or without signals.
Definition: rail_map.h:49
FloodVehicles
static void FloodVehicles(TileIndex tile)
Finds a vehicle to flood.
Definition: water_cmd.cpp:1049
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:623
DIR_NW
@ DIR_NW
Northwest.
Definition: direction_type.h:33
Vehicle::vehstatus
byte vehstatus
Status.
Definition: vehicle_base.h:349
DIAGDIR_END
@ DIAGDIR_END
Used for iterations.
Definition: direction_type.h:79
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
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
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:23
DoBuildLock
static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag flags)
Builds a lock.
Definition: water_cmd.cpp:302
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
IsOilRig
bool IsOilRig(Tile t)
Is tile t part of an oilrig?
Definition: station_map.h:275
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:792
GetPartialPixelZ
uint GetPartialPixelZ(int x, int y, Slope corners)
Determines height at given coordinate of a slope.
Definition: landscape.cpp:224
aircraft.h
DrawBridgeMiddle
void DrawBridgeMiddle(const TileInfo *ti)
Draw the middle bits of a bridge.
Definition: tunnelbridge_cmd.cpp:1544
Tile
Wrapper class to abstract away the way the tiles are stored.
Definition: map_func.h:25
water_land.h
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:54
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:374
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
TRANSPORT_WATER
@ TRANSPORT_WATER
Transport over water.
Definition: transport_type.h:29
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 > >
SLOPE_S
@ SLOPE_S
the south corner of the tile is raised
Definition: slope_type.h:51
Company::infrastructure
CompanyInfrastructure infrastructure
NOSAVE: Counts of company owned infrastructure.
Definition: company_base.h:143
IsWaterTile
bool IsWaterTile(Tile t)
Is it a water tile with plain water?
Definition: water_map.h:193
DIR_W
@ DIR_W
West.
Definition: direction_type.h:32
clear_map.h
VEH_ROAD
@ VEH_ROAD
Road vehicle type.
Definition: vehicle_type.h:25
Vehicle
Vehicle data structure.
Definition: vehicle_base.h:240
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:305
Owner
Owner
Enum for all companies/owners.
Definition: company_type.h:18
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:371
PaletteID
uint32_t PaletteID
The number of the palette.
Definition: gfx_type.h:18
DIR_N
@ DIR_N
North.
Definition: direction_type.h:26
WATER_CLASS_INVALID
@ WATER_CLASS_INVALID
Used for industry tiles on land (also for oilrig if newgrf says so).
Definition: water_map.h:51
TileDesc
Tile description for the 'land area information' tool.
Definition: tile_cmd.h:52
SLOPE_E
@ SLOPE_E
the east corner of the tile is raised
Definition: slope_type.h:52
DoCommandFlag
DoCommandFlag
List of flags for a command.
Definition: command_type.h:369
Foundation
Foundation
Enumeration for Foundations.
Definition: slope_type.h:93
CmdBuildLock
CommandCost CmdBuildLock(DoCommandFlag flags, TileIndex tile)
Builds a lock.
Definition: water_cmd.cpp:424
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
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
TRACK_BIT_UPPER
@ TRACK_BIT_UPPER
Upper track.
Definition: track_type.h:39
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:556
effectvehicle_func.h
TRACK_BIT_RIGHT
@ TRACK_BIT_RIGHT
Right track.
Definition: track_type.h:42
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
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:286
TileDesc::build_date
TimerGameCalendar::Date build_date
Date of construction of tile contents.
Definition: tile_cmd.h:57
Slope
Slope
Enumeration for the slope-type.
Definition: slope_type.h:48
WATER_TILE_COAST
@ WATER_TILE_COAST
Coast.
Definition: water_map.h:41
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
EXPENSES_CONSTRUCTION
@ EXPENSES_CONSTRUCTION
Construction costs.
Definition: economy_type.h:173
AI::NewEvent
static void NewEvent(CompanyID company, ScriptEvent *event)
Queue a new event for an AI.
Definition: ai_core.cpp:244
CommandCost
Common return value for all commands.
Definition: command_type.h:23
WaterClass
WaterClass
classes of water (for WATER_TILE_CLEAR water tile type).
Definition: water_map.h:47
SetBitIterator
Iterable ensemble of each set bit in a value.
Definition: bitmath_func.hpp:282
ClientSettings::sound
SoundSettings sound
sound effect settings
Definition: settings_type.h:638
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:260
FloodVehicleProc
static Vehicle * FloodVehicleProc(Vehicle *v, void *data)
Flood a vehicle if we are allowed to flood it, i.e.
Definition: water_cmd.cpp:1011
SLOPE_NE
@ SLOPE_NE
north and east corner are raised
Definition: slope_type.h:58
Industry::GetByTile
static Industry * GetByTile(TileIndex tile)
Get the industry of the given tile.
Definition: industry.h:207
WATER_TILE_CLEAR
@ WATER_TILE_CLEAR
Plain water.
Definition: water_map.h:40
DirtyCompanyInfrastructureWindows
void DirtyCompanyInfrastructureWindows(CompanyID company)
Redraw all windows with company infrastructure counts.
Definition: company_gui.cpp:2670
DIR_E
@ DIR_E
East.
Definition: direction_type.h:28
Vehicle::tile
TileIndex tile
Current tile index.
Definition: vehicle_base.h:260
DrawCanalWater
static void DrawCanalWater(TileIndex tile)
draw a canal styled water tile with dikes around
Definition: water_cmd.cpp:768
MP_OBJECT
@ MP_OBJECT
Contains objects such as transmitters and owned land.
Definition: tile_type.h:58
TransportType
TransportType
Available types of transport.
Definition: transport_type.h:19
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
INVALID_OWNER
@ INVALID_OWNER
An invalid owner.
Definition: company_type.h:29
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
WATER_CLASS_CANAL
@ WATER_CLASS_CANAL
Canal.
Definition: water_map.h:49
RiverModifyDesertZone
bool RiverModifyDesertZone(TileIndex tile, void *)
Callback to create non-desert around a river tile.
Definition: water_cmd.cpp:433
Station::airport
Airport airport
Tile area the airport covers.
Definition: station_base.h:456
DIR_NE
@ DIR_NE
Northeast.
Definition: direction_type.h:27
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:55
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:50
TRACK_BIT_X
@ TRACK_BIT_X
X-axis track.
Definition: track_type.h:37
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:382
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
GetTileSlope
Slope GetTileSlope(TileIndex tile, int *h)
Return the slope of a given tile inside the map.
Definition: tile_map.cpp:59
DirToDiagDir
DiagDirection DirToDiagDir(Direction dir)
Convert a Direction to a DiagDirection.
Definition: direction_func.h:166
DIR_S
@ DIR_S
South.
Definition: direction_type.h:30
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
INVALID_DIAGDIR
@ INVALID_DIAGDIR
Flag for an invalid DiagDirection.
Definition: direction_type.h:80
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:1003
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:242
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
SLOPE_NS
@ SLOPE_NS
north and south corner are raised
Definition: slope_type.h:60
DiagDirection
DiagDirection
Enumeration for diagonal directions.
Definition: direction_type.h:73
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
WATER_CLASS_RIVER
@ WATER_CLASS_RIVER
River.
Definition: water_map.h:50
GetFoundationSlope
Slope GetFoundationSlope(TileIndex tile, int *z)
Get slope of a tile on top of a (possible) foundation If a tile does not have a foundation,...
Definition: landscape.cpp:379
TRACK_BIT_ALL
@ TRACK_BIT_ALL
All possible tracks.
Definition: track_type.h:50
SLOPE_HALFTILE_MASK
@ SLOPE_HALFTILE_MASK
three bits used for halftile slopes
Definition: slope_type.h:72
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:638
CombineTrackStatus
TrackStatus CombineTrackStatus(TrackdirBits trackdirbits, TrackdirBits red_signals)
Builds a TrackStatus.
Definition: track_func.h:388
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
TRACK_BIT_LOWER
@ TRACK_BIT_LOWER
Lower track.
Definition: track_type.h:40
SetTreeGroundDensity
void SetTreeGroundDensity(Tile t, TreeGround g, uint d)
Set the density and ground type of a tile with trees.
Definition: tree_map.h:130
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:592
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:17
DC_BANKRUPT
@ DC_BANKRUPT
company bankrupts, skip money check, skip vehicle on tile check in some cases
Definition: command_type.h:377
WATER_CLASS_SEA
@ WATER_CLASS_SEA
Sea.
Definition: water_map.h:48
TileLoop_Water
void TileLoop_Water(TileIndex tile)
Let a water tile floods its diagonal adjoining tiles called from tunnelbridge_cmd,...
Definition: water_cmd.cpp:1233
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:302
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
SLOPE_W
@ SLOPE_W
the west corner of the tile is raised
Definition: slope_type.h:50
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:563
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
AirportFTAClass::delta_z
byte delta_z
Z adjustment for helicopter pads.
Definition: airport.h:183
DEPOT_PART_SOUTH
@ DEPOT_PART_SOUTH
Southern part of a depot.
Definition: water_map.h:68
MakeRiverAndModifyDesertZoneAround
void MakeRiverAndModifyDesertZoneAround(TileIndex tile)
Make a river tile and remove desert directly around it.
Definition: water_cmd.cpp:443
MakeDefaultName
void MakeDefaultName(T *obj)
Set the default name for a depot/waypoint.
Definition: town.h:249
_current_company
CompanyID _current_company
Company currently doing an action.
Definition: company_cmd.cpp:51
vehicle_func.h
NT_ACCIDENT
@ NT_ACCIDENT
An accident or disaster has occurred.
Definition: news_type.h:26
FloodVehicle
static void FloodVehicle(Vehicle *v)
Handle the flooding of a vehicle.
Definition: water_cmd.cpp:993
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:307
Vehicle::First
Vehicle * First() const
Get the first vehicle of this vehicle chain.
Definition: vehicle_base.h:641
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:382
DoFloodTile
void DoFloodTile(TileIndex target)
Floods a tile.
Definition: water_cmd.cpp:1119
SLOPE_EW
@ SLOPE_EW
east and west corner are raised
Definition: slope_type.h:59
TRACK_BIT_LEFT
@ TRACK_BIT_LEFT
Left track.
Definition: track_type.h:41
MP_VOID
@ MP_VOID
Invisible tiles at the SW and SE border.
Definition: tile_type.h:55
Backup::Restore
void Restore()
Restore the variable.
Definition: backup_type.hpp:112
SLOPE_N
@ SLOPE_N
the north corner of the tile is raised
Definition: slope_type.h:53
GetTilePixelSlope
Slope GetTilePixelSlope(TileIndex tile, int *h)
Return the slope of a given tile.
Definition: tile_map.h:280
DIR_END
@ DIR_END
Used to iterate.
Definition: direction_type.h:34
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
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:2051
OWNER_NONE
@ OWNER_NONE
The tile has no ownership.
Definition: company_type.h:25
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:278
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:316
DIAGDIR_BEGIN
@ DIAGDIR_BEGIN
Used for iterations.
Definition: direction_type.h:74
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
DC_AUTO
@ DC_AUTO
don't allow building on structures
Definition: command_type.h:372
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:512
AXIS_X
@ AXIS_X
The X axis.
Definition: direction_type.h:117
TILE_ADDXY
#define TILE_ADDXY(tile, x, y)
Adds a given offset to a tile.
Definition: map_func.h:480
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:848
TrackBits
TrackBits
Allow incrementing of Track variables.
Definition: track_type.h:35
Vehicle::subtype
byte subtype
subtype (Filled with values from AircraftSubType/DisasterSubType/EffectVehicleType/GroundVehicleSubty...
Definition: vehicle_base.h:359
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:379
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 >
RemoveLock
static CommandCost RemoveLock(TileIndex tile, DoCommandFlag flags)
Remove a lock.
Definition: water_cmd.cpp:380
GetFloodingBehaviour
FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
Returns the behaviour of a tile during flooding.
Definition: water_cmd.cpp:1080
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:24
TRACK_BIT_Y
@ TRACK_BIT_Y
Y-axis track.
Definition: track_type.h:38
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:619
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:296
IsTileType
static debug_inline bool IsTileType(Tile tile, TileType type)
Checks if a tile is a given tiletype.
Definition: tile_map.h:150
VEH_TRAIN
@ VEH_TRAIN
Train vehicle type.
Definition: vehicle_type.h:24
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:762
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:461
SLOPE_FLAT
@ SLOPE_FLAT
a flat tile
Definition: slope_type.h:49
DrawTileSeqStruct::delta_x
int8_t delta_x
0x80 is sequence terminator
Definition: sprite.h:26
ShowDepotWindow
void ShowDepotWindow(TileIndex tile, VehicleType type)
Opens a depot window.
Definition: depot_gui.cpp:1141
VEH_SHIP
@ VEH_SHIP
Ship vehicle type.
Definition: vehicle_type.h:26
Company
Definition: company_base.h:129
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
OWNER_WATER
@ OWNER_WATER
The tile/execution is done by "water".
Definition: company_type.h:26
GetTropicZone
TropicZone GetTropicZone(Tile tile)
Get the tropic zone.
Definition: tile_map.h:238
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:694
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
SLOPE_STEEP
@ SLOPE_STEEP
indicates the slope is steep
Definition: slope_type.h:54
CompanyInfrastructure::water
uint32_t water
Count of company owned track bits for canals.
Definition: company_base.h:36
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:709
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:1186
backup_type.hpp
CanalFeature
CanalFeature
List of different canal 'features'.
Definition: newgrf.h:25
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