OpenTTD Source  14.0-beta3
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  if (flags & DC_EXEC) {
277  delete Depot::GetByTile(tile);
278 
280  if (c != nullptr) {
283  }
284 
285  MakeWaterKeepingClass(tile, GetTileOwner(tile));
286  MakeWaterKeepingClass(tile2, GetTileOwner(tile2));
287  }
288 
289  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_DEPOT_SHIP]);
290 }
291 
300 {
302 
303  int delta = TileOffsByDiagDir(dir);
305  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile + delta);
306  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile - delta);
307  if (ret.Failed()) return ret;
308 
309  /* middle tile */
310  WaterClass wc_middle = HasTileWaterGround(tile) ? GetWaterClass(tile) : WATER_CLASS_CANAL;
311  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
312  if (ret.Failed()) return ret;
313  cost.AddCost(ret);
314 
315  /* lower tile */
316  if (!IsWaterTile(tile - delta)) {
317  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile - delta);
318  if (ret.Failed()) return ret;
319  cost.AddCost(ret);
320  cost.AddCost(_price[PR_BUILD_CANAL]);
321  }
322  if (!IsTileFlat(tile - delta)) {
323  return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
324  }
325  WaterClass wc_lower = IsWaterTile(tile - delta) ? GetWaterClass(tile - delta) : WATER_CLASS_CANAL;
326 
327  /* upper tile */
328  if (!IsWaterTile(tile + delta)) {
329  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile + delta);
330  if (ret.Failed()) return ret;
331  cost.AddCost(ret);
332  cost.AddCost(_price[PR_BUILD_CANAL]);
333  }
334  if (!IsTileFlat(tile + delta)) {
335  return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
336  }
337  WaterClass wc_upper = IsWaterTile(tile + delta) ? GetWaterClass(tile + delta) : WATER_CLASS_CANAL;
338 
339  if (IsBridgeAbove(tile) || IsBridgeAbove(tile - delta) || IsBridgeAbove(tile + delta)) {
340  return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
341  }
342 
343  if (flags & DC_EXEC) {
344  /* Update company infrastructure counts. */
346  if (c != nullptr) {
347  /* Counts for the water. */
348  if (!IsWaterTile(tile - delta)) c->infrastructure.water++;
349  if (!IsWaterTile(tile + delta)) c->infrastructure.water++;
350  /* Count for the lock itself. */
351  c->infrastructure.water += 3 * LOCK_DEPOT_TILE_FACTOR; // Lock is three tiles.
353  }
354 
355  MakeLock(tile, _current_company, dir, wc_lower, wc_upper, wc_middle);
356  CheckForDockingTile(tile - delta);
357  CheckForDockingTile(tile + delta);
358  MarkTileDirtyByTile(tile);
359  MarkTileDirtyByTile(tile - delta);
360  MarkTileDirtyByTile(tile + delta);
361  MarkCanalsAndRiversAroundDirty(tile - delta);
362  MarkCanalsAndRiversAroundDirty(tile + delta);
363  InvalidateWaterRegion(tile - delta);
364  InvalidateWaterRegion(tile + delta);
365  }
366  cost.AddCost(_price[PR_BUILD_LOCK]);
367 
368  return cost;
369 }
370 
378 {
379  if (GetTileOwner(tile) != OWNER_NONE) {
380  CommandCost ret = CheckTileOwnership(tile);
381  if (ret.Failed()) return ret;
382  }
383 
385 
386  /* make sure no vehicle is on the tile. */
388  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile + delta);
389  if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile - delta);
390  if (ret.Failed()) return ret;
391 
392  if (flags & DC_EXEC) {
393  /* Remove middle part from company infrastructure count. */
395  if (c != nullptr) {
396  c->infrastructure.water -= 3 * LOCK_DEPOT_TILE_FACTOR; // three parts of the lock.
398  }
399 
400  if (GetWaterClass(tile) == WATER_CLASS_RIVER) {
401  MakeRiver(tile, Random());
402  } else {
403  DoClearSquare(tile);
404  }
405  MakeWaterKeepingClass(tile + delta, GetTileOwner(tile + delta));
406  MakeWaterKeepingClass(tile - delta, GetTileOwner(tile - delta));
408  MarkCanalsAndRiversAroundDirty(tile - delta);
409  MarkCanalsAndRiversAroundDirty(tile + delta);
410  }
411 
412  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_LOCK]);
413 }
414 
422 {
424  if (dir == INVALID_DIAGDIR) return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
425 
426  return DoBuildLock(tile, dir, flags);
427 }
428 
431 {
433  return false;
434 }
435 
441 {
442  MakeRiver(tile, Random());
443  MarkTileDirtyByTile(tile);
444 
445  /* Remove desert directly around the river tile. */
447 }
448 
458 CommandCost CmdBuildCanal(DoCommandFlag flags, TileIndex tile, TileIndex start_tile, WaterClass wc, bool diagonal)
459 {
460  if (start_tile >= Map::Size() || !IsValidWaterClass(wc)) return CMD_ERROR;
461 
462  /* Outside of the editor you can only build canals, not oceans */
463  if (wc != WATER_CLASS_CANAL && _game_mode != GM_EDITOR) return CMD_ERROR;
464 
466 
467  std::unique_ptr<TileIterator> iter = TileIterator::Create(tile, start_tile, diagonal);
468  for (; *iter != INVALID_TILE; ++(*iter)) {
469  TileIndex current_tile = *iter;
470  CommandCost ret;
471 
472  Slope slope = GetTileSlope(current_tile);
473  if (slope != SLOPE_FLAT && (wc != WATER_CLASS_RIVER || !IsInclinedSlope(slope))) {
474  return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED);
475  }
476 
477  bool water = IsWaterTile(current_tile);
478 
479  /* Outside the editor, prevent building canals over your own or OWNER_NONE owned canals */
480  if (water && IsCanal(current_tile) && _game_mode != GM_EDITOR && (IsTileOwner(current_tile, _current_company) || IsTileOwner(current_tile, OWNER_NONE))) continue;
481 
482  ret = Command<CMD_LANDSCAPE_CLEAR>::Do(flags, current_tile);
483  if (ret.Failed()) return ret;
484 
485  if (!water) cost.AddCost(ret);
486 
487  if (flags & DC_EXEC) {
488  if (IsTileType(current_tile, MP_WATER) && IsCanal(current_tile)) {
489  Owner owner = GetTileOwner(current_tile);
490  if (Company::IsValidID(owner)) {
491  Company::Get(owner)->infrastructure.water--;
493  }
494  }
495 
496  switch (wc) {
497  case WATER_CLASS_RIVER:
498  MakeRiver(current_tile, Random());
499  if (_game_mode == GM_EDITOR) {
500  TileIndex tile2 = current_tile;
502  }
503  break;
504 
505  case WATER_CLASS_SEA:
506  if (TileHeight(current_tile) == 0) {
507  MakeSea(current_tile);
508  break;
509  }
510  [[fallthrough]];
511 
512  default:
513  MakeCanal(current_tile, _current_company, Random());
515  Company::Get(_current_company)->infrastructure.water++;
517  }
518  break;
519  }
520  MarkTileDirtyByTile(current_tile);
521  MarkCanalsAndRiversAroundDirty(current_tile);
522  CheckForDockingTile(current_tile);
523  }
524 
525  cost.AddCost(_price[PR_BUILD_CANAL]);
526  }
527 
528  if (cost.GetCost() == 0) {
529  return_cmd_error(STR_ERROR_ALREADY_BUILT);
530  } else {
531  return cost;
532  }
533 }
534 
535 
536 static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags)
537 {
538  switch (GetWaterTileType(tile)) {
539  case WATER_TILE_CLEAR: {
540  if (flags & DC_NO_WATER) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
541 
542  Money base_cost = IsCanal(tile) ? _price[PR_CLEAR_CANAL] : _price[PR_CLEAR_WATER];
543  /* Make sure freeform edges are allowed or it's not an edge tile. */
545  !IsInsideMM(TileY(tile), 1, Map::MaxY() - 1))) {
546  return_cmd_error(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP);
547  }
548 
549  /* Make sure no vehicle is on the tile */
551  if (ret.Failed()) return ret;
552 
553  Owner owner = GetTileOwner(tile);
554  if (owner != OWNER_WATER && owner != OWNER_NONE) {
555  ret = CheckTileOwnership(tile);
556  if (ret.Failed()) return ret;
557  }
558 
559  if (flags & DC_EXEC) {
560  if (IsCanal(tile) && Company::IsValidID(owner)) {
561  Company::Get(owner)->infrastructure.water--;
563  }
564  DoClearSquare(tile);
566  }
567 
568  return CommandCost(EXPENSES_CONSTRUCTION, base_cost);
569  }
570 
571  case WATER_TILE_COAST: {
572  Slope slope = GetTileSlope(tile);
573 
574  /* Make sure no vehicle is on the tile */
576  if (ret.Failed()) return ret;
577 
578  if (flags & DC_EXEC) {
579  DoClearSquare(tile);
581  }
582  if (IsSlopeWithOneCornerRaised(slope)) {
583  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_WATER]);
584  } else {
585  return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_ROUGH]);
586  }
587  }
588 
589  case WATER_TILE_LOCK: {
590  static const TileIndexDiffC _lock_tomiddle_offs[][DIAGDIR_END] = {
591  /* NE SE SW NW */
592  { { 0, 0}, {0, 0}, { 0, 0}, {0, 0} }, // LOCK_PART_MIDDLE
593  { {-1, 0}, {0, 1}, { 1, 0}, {0, -1} }, // LOCK_PART_LOWER
594  { { 1, 0}, {0, -1}, {-1, 0}, {0, 1} }, // LOCK_PART_UPPER
595  };
596 
597  if (flags & DC_AUTO) return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
598  if (_current_company == OWNER_WATER) return CMD_ERROR;
599  /* move to the middle tile.. */
600  return RemoveLock(tile + ToTileIndexDiff(_lock_tomiddle_offs[GetLockPart(tile)][GetLockDirection(tile)]), flags);
601  }
602 
603  case WATER_TILE_DEPOT:
604  if (flags & DC_AUTO) return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
605  return RemoveShipDepot(tile, flags);
606 
607  default:
608  NOT_REACHED();
609  }
610 }
611 
621 {
622  switch (GetTileType(tile)) {
623  case MP_WATER:
624  switch (GetWaterTileType(tile)) {
625  default: NOT_REACHED();
626  case WATER_TILE_DEPOT: case WATER_TILE_CLEAR: return true;
628 
629  case WATER_TILE_COAST:
630  switch (GetTileSlope(tile)) {
631  case SLOPE_W: return (from == DIR_SE) || (from == DIR_E) || (from == DIR_NE);
632  case SLOPE_S: return (from == DIR_NE) || (from == DIR_N) || (from == DIR_NW);
633  case SLOPE_E: return (from == DIR_NW) || (from == DIR_W) || (from == DIR_SW);
634  case SLOPE_N: return (from == DIR_SW) || (from == DIR_S) || (from == DIR_SE);
635  default: return false;
636  }
637  }
638 
639  case MP_RAILWAY:
640  if (GetRailGroundType(tile) == RAIL_GROUND_WATER) {
641  assert(IsPlainRail(tile));
642  switch (GetTileSlope(tile)) {
643  case SLOPE_W: return (from == DIR_SE) || (from == DIR_E) || (from == DIR_NE);
644  case SLOPE_S: return (from == DIR_NE) || (from == DIR_N) || (from == DIR_NW);
645  case SLOPE_E: return (from == DIR_NW) || (from == DIR_W) || (from == DIR_SW);
646  case SLOPE_N: return (from == DIR_SW) || (from == DIR_S) || (from == DIR_SE);
647  default: return false;
648  }
649  }
650  return false;
651 
652  case MP_STATION:
653  if (IsOilRig(tile)) {
654  /* Do not draw waterborders inside of industries.
655  * Note: There is no easy way to detect the industry of an oilrig tile. */
656  TileIndex src_tile = tile + TileOffsByDir(from);
657  if ((IsTileType(src_tile, MP_STATION) && IsOilRig(src_tile)) ||
658  (IsTileType(src_tile, MP_INDUSTRY))) return true;
659 
660  return IsTileOnWater(tile);
661  }
662  return (IsDock(tile) && IsTileFlat(tile)) || IsBuoy(tile);
663 
664  case MP_INDUSTRY: {
665  /* Do not draw waterborders inside of industries.
666  * Note: There is no easy way to detect the industry of an oilrig tile. */
667  TileIndex src_tile = tile + TileOffsByDir(from);
668  if ((IsTileType(src_tile, MP_STATION) && IsOilRig(src_tile)) ||
669  (IsTileType(src_tile, MP_INDUSTRY) && GetIndustryIndex(src_tile) == GetIndustryIndex(tile))) return true;
670 
671  return IsTileOnWater(tile);
672  }
673 
674  case MP_OBJECT: return IsTileOnWater(tile);
675 
677 
678  case MP_VOID: return true; // consider map border as water, esp. for rivers
679 
680  default: return false;
681  }
682 }
683 
691 static void DrawWaterSprite(SpriteID base, uint offset, CanalFeature feature, TileIndex tile)
692 {
693  if (base != SPR_FLAT_WATER_TILE) {
694  /* Only call offset callback if the sprite is NewGRF-provided. */
695  offset = GetCanalSpriteOffset(feature, tile, offset);
696  }
697  DrawGroundSprite(base + offset, PAL_NONE);
698 }
699 
706 static void DrawWaterEdges(bool canal, uint offset, TileIndex tile)
707 {
708  CanalFeature feature;
709  SpriteID base = 0;
710  if (canal) {
711  feature = CF_DIKES;
712  base = GetCanalSprite(CF_DIKES, tile);
713  if (base == 0) base = SPR_CANAL_DIKES_BASE;
714  } else {
715  feature = CF_RIVER_EDGE;
716  base = GetCanalSprite(CF_RIVER_EDGE, tile);
717  if (base == 0) return; // Don't draw if no sprites provided.
718  }
719 
720  uint wa;
721 
722  /* determine the edges around with water. */
723  wa = IsWateredTile(TILE_ADDXY(tile, -1, 0), DIR_SW) << 0;
724  wa += IsWateredTile(TILE_ADDXY(tile, 0, 1), DIR_NW) << 1;
725  wa += IsWateredTile(TILE_ADDXY(tile, 1, 0), DIR_NE) << 2;
726  wa += IsWateredTile(TILE_ADDXY(tile, 0, -1), DIR_SE) << 3;
727 
728  if (!(wa & 1)) DrawWaterSprite(base, offset, feature, tile);
729  if (!(wa & 2)) DrawWaterSprite(base, offset + 1, feature, tile);
730  if (!(wa & 4)) DrawWaterSprite(base, offset + 2, feature, tile);
731  if (!(wa & 8)) DrawWaterSprite(base, offset + 3, feature, tile);
732 
733  /* right corner */
734  switch (wa & 0x03) {
735  case 0: DrawWaterSprite(base, offset + 4, feature, tile); break;
736  case 3: if (!IsWateredTile(TILE_ADDXY(tile, -1, 1), DIR_W)) DrawWaterSprite(base, offset + 8, feature, tile); break;
737  }
738 
739  /* bottom corner */
740  switch (wa & 0x06) {
741  case 0: DrawWaterSprite(base, offset + 5, feature, tile); break;
742  case 6: if (!IsWateredTile(TILE_ADDXY(tile, 1, 1), DIR_N)) DrawWaterSprite(base, offset + 9, feature, tile); break;
743  }
744 
745  /* left corner */
746  switch (wa & 0x0C) {
747  case 0: DrawWaterSprite(base, offset + 6, feature, tile); break;
748  case 12: if (!IsWateredTile(TILE_ADDXY(tile, 1, -1), DIR_E)) DrawWaterSprite(base, offset + 10, feature, tile); break;
749  }
750 
751  /* upper corner */
752  switch (wa & 0x09) {
753  case 0: DrawWaterSprite(base, offset + 7, feature, tile); break;
754  case 9: if (!IsWateredTile(TILE_ADDXY(tile, -1, -1), DIR_S)) DrawWaterSprite(base, offset + 11, feature, tile); break;
755  }
756 }
757 
760 {
761  DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
762 }
763 
765 static void DrawCanalWater(TileIndex tile)
766 {
767  SpriteID image = SPR_FLAT_WATER_TILE;
768  if (HasBit(_water_feature[CF_WATERSLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
769  /* First water slope sprite is flat water. */
770  image = GetCanalSprite(CF_WATERSLOPE, tile);
771  if (image == 0) image = SPR_FLAT_WATER_TILE;
772  }
773  DrawWaterSprite(image, 0, CF_WATERSLOPE, tile);
774 
775  DrawWaterEdges(true, 0, tile);
776 }
777 
778 #include "table/water_land.h"
779 
789 static void DrawWaterTileStruct(const TileInfo *ti, const DrawTileSeqStruct *dtss, SpriteID base, uint offset, PaletteID palette, CanalFeature feature)
790 {
791  /* Don't draw if buildings are invisible. */
792  if (IsInvisibilitySet(TO_BUILDINGS)) return;
793 
794  for (; !dtss->IsTerminator(); dtss++) {
795  uint tile_offs = offset + dtss->image.sprite;
796  if (feature < CF_END) tile_offs = GetCanalSpriteOffset(feature, ti->tile, tile_offs);
797  AddSortableSpriteToDraw(base + tile_offs, palette,
798  ti->x + dtss->delta_x, ti->y + dtss->delta_y,
799  dtss->size_x, dtss->size_y,
800  dtss->size_z, ti->z + dtss->delta_z,
802  }
803 }
804 
806 static void DrawWaterLock(const TileInfo *ti)
807 {
808  int part = GetLockPart(ti->tile);
809  const DrawTileSprites &dts = _lock_display_data[part][GetLockDirection(ti->tile)];
810 
811  /* Draw ground sprite. */
812  SpriteID image = dts.ground.sprite;
813 
814  SpriteID water_base = GetCanalSprite(CF_WATERSLOPE, ti->tile);
815  if (water_base == 0) {
816  /* Use default sprites. */
817  water_base = SPR_CANALS_BASE;
818  } else if (HasBit(_water_feature[CF_WATERSLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
819  /* NewGRF supplies a flat sprite as first sprite. */
820  if (image == SPR_FLAT_WATER_TILE) {
821  image = water_base;
822  } else {
823  image++;
824  }
825  }
826 
827  if (image < 5) image += water_base;
828  DrawGroundSprite(image, PAL_NONE);
829 
830  /* Draw structures. */
831  uint zoffs = 0;
832  SpriteID base = GetCanalSprite(CF_LOCKS, ti->tile);
833 
834  if (base == 0) {
835  /* If no custom graphics, use defaults. */
836  base = SPR_LOCK_BASE;
837  uint8_t z_threshold = part == LOCK_PART_UPPER ? 8 : 0;
838  zoffs = ti->z > z_threshold ? 24 : 0;
839  }
840 
841  DrawWaterTileStruct(ti, dts.seq, base, zoffs, PAL_NONE, CF_LOCKS);
842 }
843 
845 static void DrawWaterDepot(const TileInfo *ti)
846 {
847  DrawWaterClassGround(ti);
848  DrawWaterTileStruct(ti, _shipdepot_display_data[GetShipDepotAxis(ti->tile)][GetShipDepotPart(ti->tile)].seq, 0, 0, COMPANY_SPRITE_COLOUR(GetTileOwner(ti->tile)), CF_END);
849 }
850 
851 static void DrawRiverWater(const TileInfo *ti)
852 {
853  SpriteID image = SPR_FLAT_WATER_TILE;
854  uint offset = 0;
855  uint edges_offset = 0;
856 
857  if (ti->tileh != SLOPE_FLAT || HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE)) {
858  image = GetCanalSprite(CF_RIVER_SLOPE, ti->tile);
859  if (image == 0) {
860  switch (ti->tileh) {
861  case SLOPE_NW: image = SPR_WATER_SLOPE_Y_DOWN; break;
862  case SLOPE_SW: image = SPR_WATER_SLOPE_X_UP; break;
863  case SLOPE_SE: image = SPR_WATER_SLOPE_Y_UP; break;
864  case SLOPE_NE: image = SPR_WATER_SLOPE_X_DOWN; break;
865  default: image = SPR_FLAT_WATER_TILE; break;
866  }
867  } else {
868  /* Flag bit 0 indicates that the first sprite is flat water. */
869  offset = HasBit(_water_feature[CF_RIVER_SLOPE].flags, CFF_HAS_FLAT_SPRITE) ? 1 : 0;
870 
871  switch (ti->tileh) {
872  case SLOPE_SE: edges_offset += 12; break;
873  case SLOPE_NE: offset += 1; edges_offset += 24; break;
874  case SLOPE_SW: offset += 2; edges_offset += 36; break;
875  case SLOPE_NW: offset += 3; edges_offset += 48; break;
876  default: offset = 0; break;
877  }
878 
879  offset = GetCanalSpriteOffset(CF_RIVER_SLOPE, ti->tile, offset);
880  }
881  }
882 
883  DrawGroundSprite(image + offset, PAL_NONE);
884 
885  /* Draw river edges if available. */
886  DrawWaterEdges(false, edges_offset, ti->tile);
887 }
888 
889 void DrawShoreTile(Slope tileh)
890 {
891  /* Converts the enum Slope into an offset based on SPR_SHORE_BASE.
892  * This allows to calculate the proper sprite to display for this Slope */
893  static const byte tileh_to_shoresprite[32] = {
894  0, 1, 2, 3, 4, 16, 6, 7, 8, 9, 17, 11, 12, 13, 14, 0,
895  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 10, 15, 0,
896  };
897 
898  assert(!IsHalftileSlope(tileh)); // Halftile slopes need to get handled earlier.
899  assert(tileh != SLOPE_FLAT); // Shore is never flat
900 
901  assert((tileh != SLOPE_EW) && (tileh != SLOPE_NS)); // No suitable sprites for current flooding behaviour
902 
903  DrawGroundSprite(SPR_SHORE_BASE + tileh_to_shoresprite[tileh], PAL_NONE);
904 }
905 
906 void DrawWaterClassGround(const TileInfo *ti)
907 {
908  switch (GetWaterClass(ti->tile)) {
909  case WATER_CLASS_SEA: DrawSeaWater(ti->tile); break;
910  case WATER_CLASS_CANAL: DrawCanalWater(ti->tile); break;
911  case WATER_CLASS_RIVER: DrawRiverWater(ti); break;
912  default: NOT_REACHED();
913  }
914 }
915 
916 static void DrawTile_Water(TileInfo *ti)
917 {
918  switch (GetWaterTileType(ti->tile)) {
919  case WATER_TILE_CLEAR:
920  DrawWaterClassGround(ti);
921  DrawBridgeMiddle(ti);
922  break;
923 
924  case WATER_TILE_COAST: {
925  DrawShoreTile(ti->tileh);
926  DrawBridgeMiddle(ti);
927  break;
928  }
929 
930  case WATER_TILE_LOCK:
931  DrawWaterLock(ti);
932  break;
933 
934  case WATER_TILE_DEPOT:
935  DrawWaterDepot(ti);
936  break;
937  }
938 }
939 
940 void DrawShipDepotSprite(int x, int y, Axis axis, DepotPart part)
941 {
942  const DrawTileSprites &dts = _shipdepot_display_data[axis][part];
943 
944  DrawSprite(dts.ground.sprite, dts.ground.pal, x, y);
945  DrawOrigTileSeqInGUI(x, y, &dts, COMPANY_SPRITE_COLOUR(_local_company));
946 }
947 
948 
949 static int GetSlopePixelZ_Water(TileIndex tile, uint x, uint y, bool)
950 {
951  int z;
952  Slope tileh = GetTilePixelSlope(tile, &z);
953 
954  return z + GetPartialPixelZ(x & 0xF, y & 0xF, tileh);
955 }
956 
957 static Foundation GetFoundation_Water(TileIndex, Slope)
958 {
959  return FOUNDATION_NONE;
960 }
961 
962 static void GetTileDesc_Water(TileIndex tile, TileDesc *td)
963 {
964  switch (GetWaterTileType(tile)) {
965  case WATER_TILE_CLEAR:
966  switch (GetWaterClass(tile)) {
967  case WATER_CLASS_SEA: td->str = STR_LAI_WATER_DESCRIPTION_WATER; break;
968  case WATER_CLASS_CANAL: td->str = STR_LAI_WATER_DESCRIPTION_CANAL; break;
969  case WATER_CLASS_RIVER: td->str = STR_LAI_WATER_DESCRIPTION_RIVER; break;
970  default: NOT_REACHED();
971  }
972  break;
973  case WATER_TILE_COAST: td->str = STR_LAI_WATER_DESCRIPTION_COAST_OR_RIVERBANK; break;
974  case WATER_TILE_LOCK : td->str = STR_LAI_WATER_DESCRIPTION_LOCK; break;
975  case WATER_TILE_DEPOT:
976  td->str = STR_LAI_WATER_DESCRIPTION_SHIP_DEPOT;
977  td->build_date = Depot::GetByTile(tile)->build_date;
978  break;
979  default: NOT_REACHED();
980  }
981 
982  td->owner[0] = GetTileOwner(tile);
983 }
984 
990 static void FloodVehicle(Vehicle *v)
991 {
992  uint pass = v->Crash(true);
993 
994  AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED));
995  Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, ScriptEventVehicleCrashed::CRASH_FLOODED));
996  SetDParam(0, pass);
997  AddTileNewsItem(STR_NEWS_DISASTER_FLOOD_VEHICLE, NT_ACCIDENT, v->tile);
999  if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v);
1000 }
1001 
1008 static Vehicle *FloodVehicleProc(Vehicle *v, void *data)
1009 {
1010  if ((v->vehstatus & VS_CRASHED) != 0) return nullptr;
1011 
1012  switch (v->type) {
1013  default: break;
1014 
1015  case VEH_AIRCRAFT: {
1016  if (!IsAirportTile(v->tile) || GetTileMaxZ(v->tile) != 0) break;
1017  if (v->subtype == AIR_SHADOW) break;
1018 
1019  /* We compare v->z_pos against delta_z + 1 because the shadow
1020  * is at delta_z and the actual aircraft at delta_z + 1. */
1021  const Station *st = Station::GetByTile(v->tile);
1022  const AirportFTAClass *airport = st->airport.GetFTA();
1023  if (v->z_pos != airport->delta_z + 1) break;
1024 
1025  FloodVehicle(v);
1026  break;
1027  }
1028 
1029  case VEH_TRAIN:
1030  case VEH_ROAD: {
1031  int z = *(int*)data;
1032  if (v->z_pos > z) break;
1033  FloodVehicle(v->First());
1034  break;
1035  }
1036  }
1037 
1038  return nullptr;
1039 }
1040 
1046 static void FloodVehicles(TileIndex tile)
1047 {
1048  int z = 0;
1049 
1050  if (IsAirportTile(tile)) {
1051  const Station *st = Station::GetByTile(tile);
1052  for (TileIndex airport_tile : st->airport) {
1053  if (st->TileBelongsToAirport(airport_tile)) FindVehicleOnPos(airport_tile, &z, &FloodVehicleProc);
1054  }
1055 
1056  /* No vehicle could be flooded on this airport anymore */
1057  return;
1058  }
1059 
1060  if (!IsBridgeTile(tile)) {
1061  FindVehicleOnPos(tile, &z, &FloodVehicleProc);
1062  return;
1063  }
1064 
1065  TileIndex end = GetOtherBridgeEnd(tile);
1066  z = GetBridgePixelHeight(tile);
1067 
1068  FindVehicleOnPos(tile, &z, &FloodVehicleProc);
1070 }
1071 
1078 {
1079  /* FLOOD_ACTIVE: 'single-corner-raised'-coast, sea, sea-shipdepots, sea-buoys, sea-docks (water part), rail with flooded halftile, sea-water-industries, sea-oilrigs
1080  * FLOOD_DRYUP: coast with more than one corner raised, coast with rail-track, coast with trees
1081  * FLOOD_PASSIVE: (not used)
1082  * FLOOD_NONE: canals, rivers, everything else
1083  */
1084  switch (GetTileType(tile)) {
1085  case MP_WATER:
1086  if (IsCoast(tile)) {
1087  Slope tileh = GetTileSlope(tile);
1089  }
1090  [[fallthrough]];
1091  case MP_STATION:
1092  case MP_INDUSTRY:
1093  case MP_OBJECT:
1094  return (GetWaterClass(tile) == WATER_CLASS_SEA) ? FLOOD_ACTIVE : FLOOD_NONE;
1095 
1096  case MP_RAILWAY:
1097  if (GetRailGroundType(tile) == RAIL_GROUND_WATER) {
1099  }
1100  return FLOOD_NONE;
1101 
1102  case MP_TREES:
1103  return (GetTreeGround(tile) == TREE_GROUND_SHORE ? FLOOD_DRYUP : FLOOD_NONE);
1104 
1105  case MP_VOID:
1106  return FLOOD_ACTIVE;
1107 
1108  default:
1109  return FLOOD_NONE;
1110  }
1111 }
1112 
1117 {
1118  assert(!IsTileType(target, MP_WATER));
1119 
1120  bool flooded = false; // Will be set to true if something is changed.
1121 
1122  Backup<CompanyID> cur_company(_current_company, OWNER_WATER, FILE_LINE);
1123 
1124  Slope tileh = GetTileSlope(target);
1125  if (tileh != SLOPE_FLAT) {
1126  /* make coast.. */
1127  switch (GetTileType(target)) {
1128  case MP_RAILWAY: {
1129  if (!IsPlainRail(target)) break;
1130  FloodVehicles(target);
1131  flooded = FloodHalftile(target);
1132  break;
1133  }
1134 
1135  case MP_TREES:
1136  if (!IsSlopeWithOneCornerRaised(tileh)) {
1138  MarkTileDirtyByTile(target);
1139  flooded = true;
1140  break;
1141  }
1142  [[fallthrough]];
1143 
1144  case MP_CLEAR:
1145  if (Command<CMD_LANDSCAPE_CLEAR>::Do(DC_EXEC, target).Succeeded()) {
1146  MakeShore(target);
1147  MarkTileDirtyByTile(target);
1148  flooded = true;
1149  }
1150  break;
1151 
1152  default:
1153  break;
1154  }
1155  } else {
1156  /* Flood vehicles */
1157  FloodVehicles(target);
1158 
1159  /* flood flat tile */
1160  if (Command<CMD_LANDSCAPE_CLEAR>::Do(DC_EXEC, target).Succeeded()) {
1161  MakeSea(target);
1162  MarkTileDirtyByTile(target);
1163  flooded = true;
1164  }
1165  }
1166 
1167  if (flooded) {
1168  /* Mark surrounding canal tiles dirty too to avoid glitches */
1170 
1171  /* update signals if needed */
1173 
1174  if (IsPossibleDockingTile(target)) CheckForDockingTile(target);
1175  }
1176 
1177  cur_company.Restore();
1178 }
1179 
1183 static void DoDryUp(TileIndex tile)
1184 {
1185  Backup<CompanyID> cur_company(_current_company, OWNER_WATER, FILE_LINE);
1186 
1187  switch (GetTileType(tile)) {
1188  case MP_RAILWAY:
1189  assert(IsPlainRail(tile));
1190  assert(GetRailGroundType(tile) == RAIL_GROUND_WATER);
1191 
1192  RailGroundType new_ground;
1193  switch (GetTrackBits(tile)) {
1194  case TRACK_BIT_UPPER: new_ground = RAIL_GROUND_FENCE_HORIZ1; break;
1195  case TRACK_BIT_LOWER: new_ground = RAIL_GROUND_FENCE_HORIZ2; break;
1196  case TRACK_BIT_LEFT: new_ground = RAIL_GROUND_FENCE_VERT1; break;
1197  case TRACK_BIT_RIGHT: new_ground = RAIL_GROUND_FENCE_VERT2; break;
1198  default: NOT_REACHED();
1199  }
1200  SetRailGroundType(tile, new_ground);
1201  MarkTileDirtyByTile(tile);
1202  break;
1203 
1204  case MP_TREES:
1206  MarkTileDirtyByTile(tile);
1207  break;
1208 
1209  case MP_WATER:
1210  assert(IsCoast(tile));
1211 
1212  if (Command<CMD_LANDSCAPE_CLEAR>::Do(DC_EXEC, tile).Succeeded()) {
1213  MakeClear(tile, CLEAR_GRASS, 3);
1214  MarkTileDirtyByTile(tile);
1215  }
1216  break;
1217 
1218  default: NOT_REACHED();
1219  }
1220 
1221  cur_company.Restore();
1222 }
1223 
1231 {
1232  if (IsTileType(tile, MP_WATER)) AmbientSoundEffect(tile);
1233 
1234  switch (GetFloodingBehaviour(tile)) {
1235  case FLOOD_ACTIVE:
1236  for (Direction dir = DIR_BEGIN; dir < DIR_END; dir++) {
1237  TileIndex dest = tile + TileOffsByDir(dir);
1238  if (!IsValidTile(dest)) continue;
1239  /* do not try to flood water tiles - increases performance a lot */
1240  if (IsTileType(dest, MP_WATER)) continue;
1241 
1242  /* TREE_GROUND_SHORE is the sign of a previous flood. */
1243  if (IsTileType(dest, MP_TREES) && GetTreeGround(dest) == TREE_GROUND_SHORE) continue;
1244 
1245  int z_dest;
1246  Slope slope_dest = GetFoundationSlope(dest, &z_dest) & ~SLOPE_HALFTILE_MASK & ~SLOPE_STEEP;
1247  if (z_dest > 0) continue;
1248 
1249  if (!HasBit(_flood_from_dirs[slope_dest], ReverseDir(dir))) continue;
1250 
1251  DoFloodTile(dest);
1252  }
1253  break;
1254 
1255  case FLOOD_DRYUP: {
1256  Slope slope_here = 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  int z;
1275 
1276  for (TileIndex tile = 0; tile < Map::Size(); ++tile) {
1277  Slope slope = GetTileSlope(tile, &z);
1278  if (IsTileType(tile, MP_CLEAR) && z == 0) {
1279  /* Make both water for tiles at level 0
1280  * and make shore, as that looks much better
1281  * during the generation. */
1282  switch (slope) {
1283  case SLOPE_FLAT:
1284  MakeSea(tile);
1285  break;
1286 
1287  case SLOPE_N:
1288  case SLOPE_E:
1289  case SLOPE_S:
1290  case SLOPE_W:
1291  MakeShore(tile);
1292  break;
1293 
1294  default:
1295  for (uint dir : SetBitIterator(_flood_from_dirs[slope & ~SLOPE_STEEP])) {
1296  TileIndex dest = TileAddByDir(tile, (Direction)dir);
1297  Slope slope_dest = GetTileSlope(dest) & ~SLOPE_STEEP;
1298  if (slope_dest == SLOPE_FLAT || IsSlopeWithOneCornerRaised(slope_dest) || IsTileType(dest, MP_VOID)) {
1299  MakeShore(tile);
1300  break;
1301  }
1302  }
1303  break;
1304  }
1305  }
1306  }
1307 }
1308 
1309 static TrackStatus GetTileTrackStatus_Water(TileIndex tile, TransportType mode, uint, DiagDirection)
1310 {
1313 
1314  TrackBits ts;
1315 
1316  if (mode != TRANSPORT_WATER) return 0;
1317 
1318  switch (GetWaterTileType(tile)) {
1319  case WATER_TILE_CLEAR: ts = IsTileFlat(tile) ? TRACK_BIT_ALL : TRACK_BIT_NONE; break;
1320  case WATER_TILE_COAST: ts = coast_tracks[GetTileSlope(tile) & 0xF]; break;
1321  case WATER_TILE_LOCK: ts = DiagDirToDiagTrackBits(GetLockDirection(tile)); break;
1322  case WATER_TILE_DEPOT: ts = AxisToTrackBits(GetShipDepotAxis(tile)); break;
1323  default: return 0;
1324  }
1325  if (TileX(tile) == 0) {
1326  /* NE border: remove tracks that connects NE tile edge */
1328  }
1329  if (TileY(tile) == 0) {
1330  /* NW border: remove tracks that connects NW tile edge */
1332  }
1334 }
1335 
1336 static bool ClickTile_Water(TileIndex tile)
1337 {
1338  if (GetWaterTileType(tile) == WATER_TILE_DEPOT) {
1340  return true;
1341  }
1342  return false;
1343 }
1344 
1345 static void ChangeTileOwner_Water(TileIndex tile, Owner old_owner, Owner new_owner)
1346 {
1347  if (!IsTileOwner(tile, old_owner)) return;
1348 
1349  bool is_lock_middle = IsLock(tile) && GetLockPart(tile) == LOCK_PART_MIDDLE;
1350 
1351  /* No need to dirty company windows here, we'll redraw the whole screen anyway. */
1352  if (is_lock_middle) Company::Get(old_owner)->infrastructure.water -= 3 * LOCK_DEPOT_TILE_FACTOR; // Lock has three parts.
1353  if (new_owner != INVALID_OWNER) {
1354  if (is_lock_middle) Company::Get(new_owner)->infrastructure.water += 3 * LOCK_DEPOT_TILE_FACTOR; // Lock has three parts.
1355  /* Only subtract from the old owner here if the new owner is valid,
1356  * otherwise we clear ship depots and canal water below. */
1357  if (GetWaterClass(tile) == WATER_CLASS_CANAL && !is_lock_middle) {
1358  Company::Get(old_owner)->infrastructure.water--;
1359  Company::Get(new_owner)->infrastructure.water++;
1360  }
1361  if (IsShipDepot(tile)) {
1362  Company::Get(old_owner)->infrastructure.water -= LOCK_DEPOT_TILE_FACTOR;
1363  Company::Get(new_owner)->infrastructure.water += LOCK_DEPOT_TILE_FACTOR;
1364  }
1365 
1366  SetTileOwner(tile, new_owner);
1367  return;
1368  }
1369 
1370  /* Remove depot */
1372 
1373  /* Set owner of canals and locks ... and also canal under dock there was before.
1374  * Check if the new owner after removing depot isn't OWNER_WATER. */
1375  if (IsTileOwner(tile, old_owner)) {
1376  if (GetWaterClass(tile) == WATER_CLASS_CANAL && !is_lock_middle) Company::Get(old_owner)->infrastructure.water--;
1377  SetTileOwner(tile, OWNER_NONE);
1378  }
1379 }
1380 
1381 static VehicleEnterTileStatus VehicleEnter_Water(Vehicle *, TileIndex, int, int)
1382 {
1383  return VETSB_CONTINUE;
1384 }
1385 
1386 static CommandCost TerraformTile_Water(TileIndex tile, DoCommandFlag flags, int, Slope)
1387 {
1388  /* Canals can't be terraformed */
1389  if (IsWaterTile(tile) && IsCanal(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_CANAL_FIRST);
1390 
1391  return Command<CMD_LANDSCAPE_CLEAR>::Do(flags, tile);
1392 }
1393 
1394 
1395 extern const TileTypeProcs _tile_type_water_procs = {
1396  DrawTile_Water, // draw_tile_proc
1397  GetSlopePixelZ_Water, // get_slope_z_proc
1398  ClearTile_Water, // clear_tile_proc
1399  nullptr, // add_accepted_cargo_proc
1400  GetTileDesc_Water, // get_tile_desc_proc
1401  GetTileTrackStatus_Water, // get_tile_track_status_proc
1402  ClickTile_Water, // click_tile_proc
1403  nullptr, // animate_tile_proc
1404  TileLoop_Water, // tile_loop_proc
1405  ChangeTileOwner_Water, // change_tile_owner_proc
1406  nullptr, // add_produced_cargo_proc
1407  VehicleEnter_Water, // vehicle_enter_tile_proc
1408  GetFoundation_Water, // get_foundation_proc
1409  TerraformTile_Water, // terraform_tile_proc
1410 };
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:335
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:346
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:806
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:1046
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:620
DIR_NW
@ DIR_NW
Northwest.
Definition: direction_type.h:33
Vehicle::vehstatus
byte vehstatus
Status.
Definition: vehicle_base.h:348
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:234
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:299
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:789
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:129
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:304
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:421
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:235
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:639
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:1008
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:2651
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:765
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:430
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:147
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:49
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:383
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:1007
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:1230
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:301
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:440
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:50
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:990
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:640
RAIL_GROUND_FENCE_HORIZ1
@ RAIL_GROUND_FENCE_HORIZ1
Grass with a fence at the southern side.
Definition: rail_map.h:496
DoFloodTile
void DoFloodTile(TileIndex target)
Floods a tile.
Definition: water_cmd.cpp:1116
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:305
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:300
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:845
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:358
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:378
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:377
GetFloodingBehaviour
FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
Returns the behaviour of a tile during flooding.
Definition: water_cmd.cpp:1077
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:620
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:324
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:759
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:458
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:116
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:691
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:706
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:1183
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