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