summaryrefslogtreecommitdiff
path: root/src/water_cmd.cpp
diff options
context:
space:
mode:
authorpeter1138 <peter1138@openttd.org>2008-02-02 09:28:43 +0000
committerpeter1138 <peter1138@openttd.org>2008-02-02 09:28:43 +0000
commit1d891a8b15f750ea7aaa14622536e87765c59e7a (patch)
tree44979390033d921d0bb48f8dddd3dec3c4d7267b /src/water_cmd.cpp
parent7cf2c834627ee41e89f5167ed05d18ec4cc7df62 (diff)
downloadopenttd-1d891a8b15f750ea7aaa14622536e87765c59e7a.tar.xz
(svn r12042) -Fix [FS#1676]: Reimplement how rivers and canals are stored in the map, allowing the sea/river/canal status to also be
stored for buoys, docks, locks and depots. All these are now allowed on rivers and removal of them will revert to the original water type.
Diffstat (limited to 'src/water_cmd.cpp')
-rw-r--r--src/water_cmd.cpp100
1 files changed, 59 insertions, 41 deletions
diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp
index 55e297f38..5f73b526c 100644
--- a/src/water_cmd.cpp
+++ b/src/water_cmd.cpp
@@ -101,21 +101,16 @@ static void MarkCanalsAndRiversAroundDirty(TileIndex tile)
* @param t the tile to change.
* @param o the owner of the new tile.
*/
-void MakeWaterOrCanalDependingOnSurroundings(TileIndex t, Owner o)
+void SetWaterClassDependingOnSurroundings(TileIndex t)
{
assert(GetTileSlope(t, NULL) == SLOPE_FLAT);
/* Mark tile dirty in all cases */
MarkTileDirtyByTile(t);
- /* Non-sealevel -> canal */
- if (TileHeight(t) != 0) {
- MakeCanal(t, o, Random());
- return;
- }
-
bool has_water = false;
bool has_canal = false;
+ bool has_river = false;
for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
TileIndex neighbour = TileAddByDiagDir(t, dir);
@@ -123,6 +118,7 @@ void MakeWaterOrCanalDependingOnSurroundings(TileIndex t, Owner o)
case MP_WATER:
has_water |= IsSea(neighbour) || IsCoast(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) == OWNER_WATER);
has_canal |= IsCanal(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) != OWNER_WATER);
+ has_river |= IsRiver(neighbour);
break;
case MP_RAILWAY:
@@ -138,10 +134,13 @@ void MakeWaterOrCanalDependingOnSurroundings(TileIndex t, Owner o)
default: break;
}
}
- if (has_canal || !has_water) {
- MakeCanal(t, o, Random());
+
+ if (has_river && !has_canal) {
+ SetWaterClass(t, WATER_CLASS_RIVER);
+ } else if (has_canal || !has_water) {
+ SetWaterClass(t, WATER_CLASS_CANAL);
} else {
- MakeWater(t);
+ SetWaterClass(t, WATER_CLASS_SEA);
}
}
@@ -162,11 +161,19 @@ CommandCost CmdBuildShipDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
tile2 = tile + (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
- if (!IsWaterTile(tile) || !IsWaterTile(tile2))
+ if (!IsWaterTile(tile) || !IsWaterTile(tile2)) {
return_cmd_error(STR_3801_MUST_BE_BUILT_ON_WATER);
+ }
if (IsBridgeAbove(tile) || IsBridgeAbove(tile2)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
+ if (GetTileSlope(tile, NULL) != SLOPE_FLAT || GetTileSlope(tile2, NULL) != SLOPE_FLAT) {
+ /* Prevent depots on rapids */
+ return_cmd_error(STR_0239_SITE_UNSUITABLE);
+ }
+
+ WaterClass wc1 = GetWaterClass(tile);
+ WaterClass wc2 = GetWaterClass(tile2);
Owner o1 = GetTileOwner(tile);
Owner o2 = GetTileOwner(tile2);
ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
@@ -181,8 +188,8 @@ CommandCost CmdBuildShipDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
if (flags & DC_EXEC) {
depot->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
- MakeShipDepot(tile, _current_player, DEPOT_NORTH, axis, o1);
- MakeShipDepot(tile2, _current_player, DEPOT_SOUTH, axis, o2);
+ MakeShipDepot(tile, _current_player, DEPOT_NORTH, axis, wc1, o1);
+ MakeShipDepot(tile2, _current_player, DEPOT_SOUTH, axis, wc2, o2);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile2);
d_auto_delete.Detach();
@@ -191,12 +198,14 @@ CommandCost CmdBuildShipDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
return CommandCost(EXPENSES_CONSTRUCTION, _price.build_ship_depot);
}
-void MakeWaterOrCanalDependingOnOwner(TileIndex tile, Owner o)
+void MakeWaterKeepingClass(TileIndex tile, Owner o)
{
- if (o == OWNER_WATER) {
- MakeWater(tile);
- } else {
- MakeCanal(tile, o, Random());
+ assert(IsTileType(tile, MP_WATER) || (IsTileType(tile, MP_STATION) && (IsBuoy(tile) || IsDock(tile))));
+
+ switch (GetWaterClass(tile)) {
+ case WATER_CLASS_SEA: MakeWater(tile); break;
+ case WATER_CLASS_CANAL: MakeCanal(tile, o, Random()); break;
+ case WATER_CLASS_RIVER: MakeRiver(tile, Random()); break;
}
}
@@ -216,8 +225,8 @@ static CommandCost RemoveShipDepot(TileIndex tile, uint32 flags)
/* Kill the depot, which is registered at the northernmost tile. Use that one */
delete GetDepotByTile(tile2 < tile ? tile2 : tile);
- MakeWaterOrCanalDependingOnOwner(tile, GetShipDepotWaterOwner(tile));
- MakeWaterOrCanalDependingOnOwner(tile2, GetShipDepotWaterOwner(tile2));
+ MakeWaterKeepingClass(tile, GetShipDepotWaterOwner(tile));
+ MakeWaterKeepingClass(tile2, GetShipDepotWaterOwner(tile2));
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile2);
}
@@ -237,6 +246,8 @@ static CommandCost DoBuildShiplift(TileIndex tile, DiagDirection dir, uint32 fla
delta = TileOffsByDiagDir(dir);
/* lower tile */
+ WaterClass wc_lower = IsWaterTile(tile - delta) ? GetWaterClass(tile - delta) : WATER_CLASS_CANAL;
+
ret = DoCommand(tile - delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return CMD_ERROR;
if (GetTileSlope(tile - delta, NULL) != SLOPE_FLAT) {
@@ -244,6 +255,8 @@ static CommandCost DoBuildShiplift(TileIndex tile, DiagDirection dir, uint32 fla
}
/* upper tile */
+ WaterClass wc_upper = IsWaterTile(tile + delta) ? GetWaterClass(tile + delta) : WATER_CLASS_CANAL;
+
ret = DoCommand(tile + delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return CMD_ERROR;
if (GetTileSlope(tile + delta, NULL) != SLOPE_FLAT) {
@@ -257,7 +270,7 @@ static CommandCost DoBuildShiplift(TileIndex tile, DiagDirection dir, uint32 fla
}
if (flags & DC_EXEC) {
- MakeLock(tile, _current_player, dir);
+ MakeLock(tile, _current_player, dir, wc_lower, wc_upper);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile - delta);
MarkTileDirtyByTile(tile + delta);
@@ -280,8 +293,10 @@ static CommandCost RemoveShiplift(TileIndex tile, uint32 flags)
if (flags & DC_EXEC) {
DoClearSquare(tile);
- MakeWaterOrCanalDependingOnSurroundings(tile + delta, _current_player);
- MakeWaterOrCanalDependingOnSurroundings(tile - delta, _current_player);
+ MakeWaterKeepingClass(tile + delta, GetTileOwner(tile));
+ MakeWaterKeepingClass(tile - delta, GetTileOwner(tile));
+ MarkTileDirtyByTile(tile - delta);
+ MarkTileDirtyByTile(tile + delta);
MarkCanalsAndRiversAroundDirty(tile - delta);
MarkCanalsAndRiversAroundDirty(tile + delta);
}
@@ -301,7 +316,7 @@ CommandCost CmdBuildLock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (dir == INVALID_DIAGDIR) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
/* Disallow building of locks on river rapids */
- if (IsRiverTile(tile)) return_cmd_error(STR_0239_SITE_UNSUITABLE);
+ if (IsWaterTile(tile)) return_cmd_error(STR_0239_SITE_UNSUITABLE);
return DoBuildShiplift(tile, dir, flags);
}
@@ -379,7 +394,6 @@ static CommandCost ClearTile_Water(TileIndex tile, byte flags)
{
switch (GetWaterTileType(tile)) {
case WATER_TILE_CLEAR:
- case WATER_TILE_RIVER:
if (flags & DC_NO_WATER) return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
/* Make sure it's not an edge tile. */
@@ -472,7 +486,7 @@ static bool IsWateredTile(TileIndex tile, Direction from)
}
return false;
- case MP_STATION: return IsOilRig(tile) || IsDock(tile) || IsBuoy(tile);
+ case MP_STATION: return IsOilRig(tile) || (IsDock(tile) && GetTileSlope(tile, NULL) == SLOPE_FLAT) || IsBuoy(tile);
case MP_INDUSTRY: return (GetIndustrySpec(GetIndustryType(tile))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0;
default: return false;
}
@@ -518,9 +532,17 @@ static void DrawWaterEdges(SpriteID base, TileIndex tile)
}
}
+/** Draw a plain sea water tile with no edges */
+void DrawSeaWater(TileIndex tile)
+{
+ DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
+}
+
/** draw a canal styled water tile with dikes around */
-void DrawCanalWater(TileIndex tile)
+void DrawCanalWater(TileIndex tile, bool draw_base)
{
+ if (draw_base) DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
+
/* Test for custom graphics, else use the default */
SpriteID dikes_base = GetCanalSprite(CF_DIKES, tile);
if (dikes_base == 0) dikes_base = SPR_CANAL_DIKES_BASE;
@@ -566,7 +588,7 @@ static void DrawWaterStuff(const TileInfo *ti, const WaterDrawTileStruct *wdts,
}
}
-static void DrawRiverWater(const TileInfo *ti)
+void DrawRiverWater(const TileInfo *ti, bool draw_base)
{
SpriteID image = SPR_FLAT_WATER_TILE;
SpriteID edges_base = GetCanalSprite(CF_RIVER_EDGE, ti->tile);
@@ -592,7 +614,7 @@ static void DrawRiverWater(const TileInfo *ti)
}
}
- DrawGroundSprite(image, PAL_NONE);
+ if (draw_base) DrawGroundSprite(image, PAL_NONE);
/* Draw river edges if available. */
if (edges_base > 48) DrawWaterEdges(edges_base, ti->tile);
@@ -619,8 +641,11 @@ static void DrawTile_Water(TileInfo *ti)
{
switch (GetWaterTileType(ti->tile)) {
case WATER_TILE_CLEAR:
- DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
- if (IsCanal(ti->tile)) DrawCanalWater(ti->tile);
+ switch (GetWaterClass(ti->tile)) {
+ case WATER_CLASS_SEA: DrawSeaWater(ti->tile); break;
+ case WATER_CLASS_CANAL: DrawCanalWater(ti->tile, true); break;
+ case WATER_CLASS_RIVER: DrawRiverWater(ti, true); break;
+ }
DrawBridgeMiddle(ti);
break;
@@ -637,11 +662,6 @@ static void DrawTile_Water(TileInfo *ti)
case WATER_TILE_DEPOT:
DrawWaterStuff(ti, _shipdepot_display_seq[GetSection(ti->tile)], PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile)), 0);
break;
-
- case WATER_TILE_RIVER:
- DrawRiverWater(ti);
- DrawBridgeMiddle(ti);
- break;
}
}
@@ -680,7 +700,6 @@ static void GetTileDesc_Water(TileIndex tile, TileDesc *td)
{
switch (GetWaterTileType(tile)) {
case WATER_TILE_CLEAR:
- case WATER_TILE_RIVER:
if (!IsCanal(tile)) {
td->str = STR_3804_WATER;
} else {
@@ -842,7 +861,7 @@ static FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
Slope tileh = GetTileSlope(tile, NULL);
return (IsSlopeWithOneCornerRaised(tileh) ? FLOOD_ACTIVE : FLOOD_DRYUP);
} else {
- return ((IsSea(tile) || (IsShipDepot(tile) && (GetShipDepotWaterOwner(tile) == OWNER_WATER))) ? FLOOD_ACTIVE : FLOOD_NONE);
+ return (GetWaterClass(tile) == WATER_CLASS_SEA) ? FLOOD_ACTIVE : FLOOD_NONE;
}
case MP_RAILWAY:
@@ -855,7 +874,7 @@ static FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
return (GetTreeGround(tile) == TREE_GROUND_SHORE ? FLOOD_DRYUP : FLOOD_NONE);
case MP_STATION:
- if (IsSeaBuoyTile(tile)) return FLOOD_ACTIVE;
+ if (IsBuoy(tile) && GetWaterClass(tile) == WATER_CLASS_SEA) return FLOOD_ACTIVE;
if (IsOilRig(tile) || IsDock(tile)) return FLOOD_PASSIVE;
return FLOOD_NONE;
@@ -1073,11 +1092,10 @@ static uint32 GetTileTrackStatus_Water(TileIndex tile, TransportType mode, uint
if (mode != TRANSPORT_WATER) return 0;
switch (GetWaterTileType(tile)) {
- case WATER_TILE_CLEAR: ts = TRACK_BIT_ALL; break;
+ case WATER_TILE_CLEAR: ts = (GetTileSlope(tile, NULL) == SLOPE_FLAT) ? TRACK_BIT_ALL : TRACK_BIT_NONE; break;
case WATER_TILE_COAST: ts = (TrackBits)coast_tracks[GetTileSlope(tile, NULL) & 0xF]; break;
case WATER_TILE_LOCK: ts = AxisToTrackBits(DiagDirToAxis(GetLockDirection(tile))); break;
case WATER_TILE_DEPOT: ts = AxisToTrackBits(GetShipDepotAxis(tile)); break;
- case WATER_TILE_RIVER: ts = (GetTileSlope(tile, NULL) == SLOPE_FLAT) ? TRACK_BIT_ALL : TRACK_BIT_NONE; break;
default: return 0;
}
if (TileX(tile) == 0) {