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