1
0
Fork 0

(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.
release/0.6
peter1138 2008-02-02 09:28:43 +00:00
parent 7cf2c83462
commit 1d891a8b15
12 changed files with 162 additions and 108 deletions

View File

@ -794,6 +794,7 @@
<li>m3 bits 7..4: persistent random data for newstations</li> <li>m3 bits 7..4: persistent random data for newstations</li>
<li>m3 bits 3..0: <a href="#TrackType">track type</a> for railway stations</li> <li>m3 bits 3..0: <a href="#TrackType">track type</a> for railway stations</li>
<li>m3 bits 2..0: present road types for road stops</li> <li>m3 bits 2..0: present road types for road stops</li>
<li>m3 bits 1..0: water class for buoys and water part of docks</li>
<li>m4: custom station id; 0 means standard graphics</li> <li>m4: custom station id; 0 means standard graphics</li>
<li>m5: graphics index (range from 0..255 for each station type): <li>m5: graphics index (range from 0..255 for each station type):
<table> <table>
@ -906,13 +907,14 @@
<td> <td>
<ul> <ul>
<li>m1: <a href="#OwnershipInfo">owner</a> (for sea, rivers, and coasts normally <tt>11</tt>)</li> <li>m1: <a href="#OwnershipInfo">owner</a> (for sea, rivers, and coasts normally <tt>11</tt>)</li>
<li>m3 bits 1..0 : Water class (sea, canal or river)
<li>m4: Owner of the water when ship depot</li> <li>m4: Owner of the water when ship depot</li>
<li>m4: Random data for canal or river tiles</li> <li>m4: Random data for canal or river tiles</li>
<li>m5: tile type: <li>m5: tile type:
<table> <table>
<tr> <tr>
<td nowrap valign=top><tt>00</tt>&nbsp; </td> <td nowrap valign=top><tt>00</tt>&nbsp; </td>
<td align=left>water</td> <td align=left>water, canal or river</td>
</tr> </tr>
<tr> <tr>
@ -920,11 +922,6 @@
<td align=left>coast or riverbank</td> <td align=left>coast or riverbank</td>
</tr> </tr>
<tr>
<td noswap valign=top><tt>02</tt>&nbsp; </td>
<td align=left>river</td>
</tr>
<tr> <tr>
<td nowrap valign=top><tt>10</tt>..<tt>1B</tt>&nbsp; </td> <td nowrap valign=top><tt>10</tt>..<tt>1B</tt>&nbsp; </td>
<td align=left>canal locks <td align=left>canal locks

View File

@ -216,7 +216,7 @@ the array so you can quickly see what is used and what is not.
<td class="bits">-inherit-</td> <td class="bits">-inherit-</td>
<td class="bits">-inherit-</td> <td class="bits">-inherit-</td>
<td class="bits">-inherit-</td> <td class="bits">-inherit-</td>
<td class="bits"><span class="free">OOOO OOOO</span></td> <td class="bits"><span class="free">OOOO OO</span>XX</td>
<td class="bits"><span class="option">~~~~ ~~~~</span></td> <td class="bits"><span class="option">~~~~ ~~~~</span></td>
<td class="bits"><span class="option">~~~~ ~</span>XXX</td> <td class="bits"><span class="option">~~~~ ~</span>XXX</td>
<td class="bits"><span class="free">OO</span>XX X<span class="free">O</span>XX</td> <td class="bits"><span class="free">OO</span>XX X<span class="free">O</span>XX</td>
@ -238,7 +238,7 @@ the array so you can quickly see what is used and what is not.
<td class="bits">-inherit-</td> <td class="bits">-inherit-</td>
<td class="bits">-inherit-</td> <td class="bits">-inherit-</td>
<td class="bits">-inherit-</td> <td class="bits">-inherit-</td>
<td class="bits"><span class="free">OOOO OOOO</span></td> <td class="bits"><span class="free">OOOO OO</span>XX</td>
<td class="bits"><span class="option">~~~~ ~~~~</span></td> <td class="bits"><span class="option">~~~~ ~~~~</span></td>
<td class="bits"><span class="option">~~~~ ~~~~</span></td> <td class="bits"><span class="option">~~~~ ~~~~</span></td>
<td class="bits"><span class="free">OO</span>XX X<span class="free">O</span>XX</td> <td class="bits"><span class="free">OO</span>XX X<span class="free">O</span>XX</td>
@ -261,7 +261,7 @@ the array so you can quickly see what is used and what is not.
<td class="bits">XXXX XXXX</td> <td class="bits">XXXX XXXX</td>
<td class="bits"><span class="option">~~~</span>X XXXX</td> <td class="bits"><span class="option">~~~</span>X XXXX</td>
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td> <td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td> <td class="bits"><span class="free">OOOO OO</span>XX</td>
<td class="bits"><span class="free">OOOO OOOO</span></td> <td class="bits"><span class="free">OOOO OOOO</span></td>
<td class="bits">X<span class="option">~~</span>X XXXX</td> <td class="bits">X<span class="option">~~</span>X XXXX</td>
<td class="bits">XX<span class="free">OO OO</span>XX</td> <td class="bits">XX<span class="free">OO OO</span>XX</td>
@ -272,7 +272,7 @@ the array so you can quickly see what is used and what is not.
<td class="bits">-inherit-</td> <td class="bits">-inherit-</td>
<td class="bits">-inherit-</td> <td class="bits">-inherit-</td>
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td> <td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td> <td class="bits"><span class="free">OOOO OO</span>XX</td>
<td class="bits">XXXX XXXX</td> <td class="bits">XXXX XXXX</td>
<td class="bits">-inherit-</td> <td class="bits">-inherit-</td>
<td class="bits">XX<span class="free">OO OO</span>XX</td> <td class="bits">XX<span class="free">OO OO</span>XX</td>
@ -283,7 +283,7 @@ the array so you can quickly see what is used and what is not.
<td class="bits">-inherit-</td> <td class="bits">-inherit-</td>
<td class="bits">-inherit-</td> <td class="bits">-inherit-</td>
<td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td> <td class="bits"><span class="free">OOOO OOOO OOOO OOOO</span></td>
<td class="bits"><span class="free">OOOO OOOO</span></td> <td class="bits"><span class="free">OOOO OO</span>XX</td>
<td class="bits">XXXX XXXX</td> <td class="bits">XXXX XXXX</td>
<td class="bits">-inherit-</td> <td class="bits">-inherit-</td>
<td class="bits">XX<span class="free">OO OO</span>XX</td> <td class="bits">XX<span class="free">OO OO</span>XX</td>

View File

@ -1226,7 +1226,7 @@ static bool CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable
IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour; IndustryBehaviour ind_behav = GetIndustrySpec(type)->behaviour;
/* Perform land/water check if not disabled */ /* Perform land/water check if not disabled */
if (!HasBit(its->slopes_refused, 5) && ((IsWaterTile(cur_tile) || IsRiverTile(cur_tile)) == !(ind_behav & INDUSTRYBEH_BUILT_ONWATER))) return false; if (!HasBit(its->slopes_refused, 5) && (IsWaterTile(cur_tile) == !(ind_behav & INDUSTRYBEH_BUILT_ONWATER))) return false;
if (HasBit(its->callback_flags, CBM_INDT_SHAPE_CHECK)) { if (HasBit(its->callback_flags, CBM_INDT_SHAPE_CHECK)) {
custom_shape = true; custom_shape = true;

View File

@ -22,7 +22,8 @@ WaterFeature _water_feature[CF_END];
* three functions are stubs. */ * three functions are stubs. */
static uint32 CanalGetRandomBits(const ResolverObject *object) static uint32 CanalGetRandomBits(const ResolverObject *object)
{ {
return GetWaterTileRandomBits(object->u.canal.tile); /* Return random bits only for water tiles, not station tiles */
return IsTileType(object->u.canal.tile, MP_WATER) ? GetWaterTileRandomBits(object->u.canal.tile) : 0;
} }

View File

@ -77,6 +77,7 @@
#include "tree_map.h" #include "tree_map.h"
#include "tunnelbridge_map.h" #include "tunnelbridge_map.h"
#include "void_map.h" #include "void_map.h"
#include "water.h"
#include <stdarg.h> #include <stdarg.h>
@ -2323,9 +2324,31 @@ bool AfterLoadGame()
} }
if (CheckSavegameVersion(86)) { if (CheckSavegameVersion(86)) {
/* Now all crossings should be in correct state */
for (TileIndex t = 0; t < map_size; t++) { for (TileIndex t = 0; t < map_size; t++) {
/* Now all crossings should be in correct state */
if (IsLevelCrossingTile(t)) UpdateLevelCrossing(t, false); if (IsLevelCrossingTile(t)) UpdateLevelCrossing(t, false);
/* Move river flag and update canals to use water class */
if (IsTileType(t, MP_WATER)) {
if (_m[t].m5 == 2) {
MakeRiver(t, Random());
} else {
Owner o = GetTileOwner(t);
if (IsWater(t) && o != OWNER_WATER) {
MakeCanal(t, o, Random());
}
}
}
}
/* Update locks, depots, docks and buoys to have a water class based
* on its neighbouring tiles. Done after river and canal updates to
* ensure neighbours are correct. */
for (TileIndex t = 0; t < map_size; t++) {
if (GetTileSlope(t, NULL) != SLOPE_FLAT) continue;
if (IsTileType(t, MP_WATER) && (GetWaterTileType(t) == WATER_TILE_LOCK || IsShipDepot(t))) SetWaterClassDependingOnSurroundings(t);
if (IsTileType(t, MP_STATION) && (IsDock(t) || IsBuoy(t))) SetWaterClassDependingOnSurroundings(t);
} }
} }

View File

@ -34,7 +34,7 @@
#include "table/strings.h" #include "table/strings.h"
extern const uint16 SAVEGAME_VERSION = 85; extern const uint16 SAVEGAME_VERSION = 86;
uint16 _sl_version; ///< the major savegame version identifier uint16 _sl_version; ///< the major savegame version identifier
byte _sl_minor_version; ///< the minor savegame version, DO NOT USE! byte _sl_minor_version; ///< the minor savegame version, DO NOT USE!

View File

@ -1837,6 +1837,8 @@ CommandCost CmdBuildBuoy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (!IsWaterTile(tile) || tile == 0) return_cmd_error(STR_304B_SITE_UNSUITABLE); if (!IsWaterTile(tile) || tile == 0) return_cmd_error(STR_304B_SITE_UNSUITABLE);
if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
if (GetTileSlope(tile, NULL) != SLOPE_FLAT) return_cmd_error(STR_304B_SITE_UNSUITABLE);
/* allocate and initialize new station */ /* allocate and initialize new station */
Station *st = new Station(tile); Station *st = new Station(tile);
if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING); if (st == NULL) return_cmd_error(STR_3008_TOO_MANY_STATIONS_LOADING);
@ -1859,7 +1861,7 @@ CommandCost CmdBuildBuoy(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
st->build_date = _date; st->build_date = _date;
MakeBuoy(tile, st->index); MakeBuoy(tile, st->index, GetWaterClass(tile));
UpdateStationVirtCoordDirty(st); UpdateStationVirtCoordDirty(st);
UpdateStationAcceptance(st, false); UpdateStationAcceptance(st, false);
@ -1917,7 +1919,7 @@ static CommandCost RemoveBuoy(Station *st, uint32 flags)
/* We have to set the water tile's state to the same state as before the /* We have to set the water tile's state to the same state as before the
* buoy was placed. Otherwise one could plant a buoy on a canal edge, * buoy was placed. Otherwise one could plant a buoy on a canal edge,
* remove it and flood the land (if the canal edge is at level 0) */ * remove it and flood the land (if the canal edge is at level 0) */
MakeWaterOrCanalDependingOnOwner(tile, GetTileOwner(tile)); MakeWaterKeepingClass(tile, GetTileOwner(tile));
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
UpdateStationVirtCoordDirty(st); UpdateStationVirtCoordDirty(st);
@ -1951,7 +1953,7 @@ CommandCost CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
direction = ReverseDiagDir(direction); direction = ReverseDiagDir(direction);
/* Docks cannot be placed on rapids */ /* Docks cannot be placed on rapids */
if (IsRiverTile(tile)) return_cmd_error(STR_304B_SITE_UNSUITABLE); if (IsWaterTile(tile)) return_cmd_error(STR_304B_SITE_UNSUITABLE);
if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR; if (!(flags & DC_NO_TOWN_RATING) && !CheckIfAuthorityAllows(tile)) return CMD_ERROR;
@ -1968,6 +1970,9 @@ CommandCost CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
if (MayHaveBridgeAbove(tile_cur) && IsBridgeAbove(tile_cur)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST); if (MayHaveBridgeAbove(tile_cur) && IsBridgeAbove(tile_cur)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
/* Get the water class of the water tile before it is cleared.*/
WaterClass wc = GetWaterClass(tile_cur);
cost = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR); cost = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(cost)) return CMD_ERROR; if (CmdFailed(cost)) return CMD_ERROR;
@ -2025,7 +2030,7 @@ CommandCost CmdBuildDock(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
st->rect.BeforeAddRect(tile, _dock_w_chk[direction], _dock_h_chk[direction], StationRect::ADD_TRY); st->rect.BeforeAddRect(tile, _dock_w_chk[direction], _dock_h_chk[direction], StationRect::ADD_TRY);
MakeDock(tile, st->owner, st->index, direction); MakeDock(tile, st->owner, st->index, direction, wc);
UpdateStationVirtCoordDirty(st); UpdateStationVirtCoordDirty(st);
UpdateStationAcceptance(st, false); UpdateStationAcceptance(st, false);
@ -2050,7 +2055,7 @@ static CommandCost RemoveDock(Station *st, uint32 flags)
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
DoClearSquare(tile1); DoClearSquare(tile1);
MakeWaterOrCanalDependingOnSurroundings(tile2, st->owner); MakeWaterKeepingClass(tile2, st->owner);
st->rect.AfterRemoveTile(st, tile1); st->rect.AfterRemoveTile(st, tile1);
st->rect.AfterRemoveTile(st, tile2); st->rect.AfterRemoveTile(st, tile2);
@ -2155,7 +2160,14 @@ static void DrawTile_Station(TileInfo *ti)
DrawTramCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y); DrawTramCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y);
} }
if (IsCanalBuoyTile(ti->tile)) DrawCanalWater(ti->tile); if (IsBuoy(ti->tile)) {
/* Draw appropriate water edges */
switch (GetWaterClass(ti->tile)) {
case WATER_CLASS_SEA: break;
case WATER_CLASS_CANAL: DrawCanalWater(ti->tile, false); break;
case WATER_CLASS_RIVER: DrawRiverWater(ti, false); break;
}
}
const DrawTileSeqStruct *dtss; const DrawTileSeqStruct *dtss;
foreach_draw_tile_seq(dtss, t->seq) { foreach_draw_tile_seq(dtss, t->seq) {

View File

@ -7,6 +7,7 @@
#include "rail_map.h" #include "rail_map.h"
#include "road_map.h" #include "road_map.h"
#include "water_map.h"
#include "station.h" #include "station.h"
#include "rail.h" #include "rail.h"
@ -155,16 +156,6 @@ static inline bool IsBuoyTile(TileIndex t)
return IsTileType(t, MP_STATION) && IsBuoy(t); return IsTileType(t, MP_STATION) && IsBuoy(t);
} }
static inline bool IsCanalBuoyTile(TileIndex t)
{
return IsBuoyTile(t) && !IsTileOwner(t, OWNER_WATER);
}
static inline bool IsSeaBuoyTile(TileIndex t)
{
return IsBuoyTile(t) && IsTileOwner(t, OWNER_WATER);
}
static inline bool IsHangarTile(TileIndex t) static inline bool IsHangarTile(TileIndex t)
{ {
return IsTileType(t, MP_STATION) && IsHangar(t); return IsTileType(t, MP_STATION) && IsHangar(t);
@ -287,18 +278,20 @@ static inline void MakeAirport(TileIndex t, Owner o, StationID sid, byte section
MakeStation(t, o, sid, STATION_AIRPORT, section); MakeStation(t, o, sid, STATION_AIRPORT, section);
} }
static inline void MakeBuoy(TileIndex t, StationID sid) static inline void MakeBuoy(TileIndex t, StationID sid, WaterClass wc)
{ {
/* Make the owner of the buoy tile the same as the current owner of the /* Make the owner of the buoy tile the same as the current owner of the
* water tile. In this way, we can reset the owner of the water to its * water tile. In this way, we can reset the owner of the water to its
* original state when the buoy gets removed. */ * original state when the buoy gets removed. */
MakeStation(t, GetTileOwner(t), sid, STATION_BUOY, 0); MakeStation(t, GetTileOwner(t), sid, STATION_BUOY, 0);
SetWaterClass(t, wc);
} }
static inline void MakeDock(TileIndex t, Owner o, StationID sid, DiagDirection d) static inline void MakeDock(TileIndex t, Owner o, StationID sid, DiagDirection d, WaterClass wc)
{ {
MakeStation(t, o, sid, STATION_DOCK, d); MakeStation(t, o, sid, STATION_DOCK, d);
MakeStation(t + TileOffsByDiagDir(d), o, sid, STATION_DOCK, GFX_DOCK_BASE_WATER_PART + DiagDirToAxis(d)); MakeStation(t + TileOffsByDiagDir(d), o, sid, STATION_DOCK, GFX_DOCK_BASE_WATER_PART + DiagDirToAxis(d));
SetWaterClass(t + TileOffsByDiagDir(d), wc);
} }
static inline void MakeOilrig(TileIndex t, StationID sid) static inline void MakeOilrig(TileIndex t, StationID sid)

View File

@ -248,7 +248,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p
/* retrieve landscape height and ensure it's on land */ /* retrieve landscape height and ensure it's on land */
tile_start = TileXY(x, y); tile_start = TileXY(x, y);
tile_end = TileXY(sx, sy); tile_end = TileXY(sx, sy);
if (IsWaterTile(tile_start) || IsRiverTile(tile_start) || IsWaterTile(tile_end) || IsRiverTile(tile_end)) { if (IsWaterTile(tile_start) || IsWaterTile(tile_end)) {
return_cmd_error(STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH); return_cmd_error(STR_02A0_ENDS_OF_BRIDGE_MUST_BOTH);
} }
@ -373,7 +373,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, uint32 flags, uint32 p1, uint32 p
switch (GetTileType(tile)) { switch (GetTileType(tile)) {
case MP_WATER: case MP_WATER:
if (!EnsureNoVehicleOnGround(tile)) return_cmd_error(STR_980E_SHIP_IN_THE_WAY); if (!EnsureNoVehicleOnGround(tile)) return_cmd_error(STR_980E_SHIP_IN_THE_WAY);
if (!IsWater(tile) && !IsCoast(tile) && !IsRiver(tile)) goto not_valid_below; if (!IsWater(tile) && !IsCoast(tile)) goto not_valid_below;
break; break;
case MP_RAILWAY: case MP_RAILWAY:
@ -468,7 +468,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32
direction = GetInclinedSlopeDirection(start_tileh); direction = GetInclinedSlopeDirection(start_tileh);
if (direction == INVALID_DIAGDIR) return_cmd_error(STR_500B_SITE_UNSUITABLE_FOR_TUNNEL); if (direction == INVALID_DIAGDIR) return_cmd_error(STR_500B_SITE_UNSUITABLE_FOR_TUNNEL);
if (IsRiverTile(start_tile)) return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER); if (IsWaterTile(start_tile)) return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
ret = DoCommand(start_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); ret = DoCommand(start_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return ret; if (CmdFailed(ret)) return ret;
@ -522,7 +522,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, uint32 flags, uint32 p1, uint32
/* if the command fails from here on we want the end tile to be highlighted */ /* if the command fails from here on we want the end tile to be highlighted */
_build_tunnel_endtile = end_tile; _build_tunnel_endtile = end_tile;
if (IsRiverTile(end_tile)) return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER); if (IsWaterTile(end_tile)) return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
/* slope of end tile must be complementary to the slope of the start tile */ /* slope of end tile must be complementary to the slope of the start tile */
if (end_tileh != ComplementSlope(start_tileh)) { if (end_tileh != ComplementSlope(start_tileh)) {

View File

@ -11,10 +11,11 @@ bool FloodHalftile(TileIndex t);
void ConvertGroundTilesIntoWaterTiles(); void ConvertGroundTilesIntoWaterTiles();
void DrawShipDepotSprite(int x, int y, int image); void DrawShipDepotSprite(int x, int y, int image);
void DrawCanalWater(TileIndex tile); void DrawCanalWater(TileIndex tile, bool draw_base);
void DrawRiverWater(const struct TileInfo *ti, bool draw_base);
void DrawShoreTile(Slope tileh); void DrawShoreTile(Slope tileh);
void MakeWaterOrCanalDependingOnOwner(TileIndex tile, Owner o); void MakeWaterKeepingClass(TileIndex tile, Owner o);
void MakeWaterOrCanalDependingOnSurroundings(TileIndex t, Owner o); void SetWaterClassDependingOnSurroundings(TileIndex t);
#endif /* WATER_H */ #endif /* WATER_H */

View File

@ -101,21 +101,16 @@ static void MarkCanalsAndRiversAroundDirty(TileIndex tile)
* @param t the tile to change. * @param t the tile to change.
* @param o the owner of the new tile. * @param o the owner of the new tile.
*/ */
void MakeWaterOrCanalDependingOnSurroundings(TileIndex t, Owner o) void SetWaterClassDependingOnSurroundings(TileIndex t)
{ {
assert(GetTileSlope(t, NULL) == SLOPE_FLAT); assert(GetTileSlope(t, NULL) == SLOPE_FLAT);
/* Mark tile dirty in all cases */ /* Mark tile dirty in all cases */
MarkTileDirtyByTile(t); MarkTileDirtyByTile(t);
/* Non-sealevel -> canal */
if (TileHeight(t) != 0) {
MakeCanal(t, o, Random());
return;
}
bool has_water = false; bool has_water = false;
bool has_canal = false; bool has_canal = false;
bool has_river = false;
for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) { for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
TileIndex neighbour = TileAddByDiagDir(t, dir); TileIndex neighbour = TileAddByDiagDir(t, dir);
@ -123,6 +118,7 @@ void MakeWaterOrCanalDependingOnSurroundings(TileIndex t, Owner o)
case MP_WATER: case MP_WATER:
has_water |= IsSea(neighbour) || IsCoast(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) == OWNER_WATER); has_water |= IsSea(neighbour) || IsCoast(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) == OWNER_WATER);
has_canal |= IsCanal(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) != OWNER_WATER); has_canal |= IsCanal(neighbour) || (IsShipDepot(neighbour) && GetShipDepotWaterOwner(neighbour) != OWNER_WATER);
has_river |= IsRiver(neighbour);
break; break;
case MP_RAILWAY: case MP_RAILWAY:
@ -138,10 +134,13 @@ void MakeWaterOrCanalDependingOnSurroundings(TileIndex t, Owner o)
default: break; 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 { } 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)); 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); 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 (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 o1 = GetTileOwner(tile);
Owner o2 = GetTileOwner(tile2); Owner o2 = GetTileOwner(tile2);
ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); 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) { if (flags & DC_EXEC) {
depot->town_index = ClosestTownFromTile(tile, (uint)-1)->index; depot->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
MakeShipDepot(tile, _current_player, DEPOT_NORTH, axis, o1); MakeShipDepot(tile, _current_player, DEPOT_NORTH, axis, wc1, o1);
MakeShipDepot(tile2, _current_player, DEPOT_SOUTH, axis, o2); MakeShipDepot(tile2, _current_player, DEPOT_SOUTH, axis, wc2, o2);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile2); MarkTileDirtyByTile(tile2);
d_auto_delete.Detach(); 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); return CommandCost(EXPENSES_CONSTRUCTION, _price.build_ship_depot);
} }
void MakeWaterOrCanalDependingOnOwner(TileIndex tile, Owner o) void MakeWaterKeepingClass(TileIndex tile, Owner o)
{ {
if (o == OWNER_WATER) { assert(IsTileType(tile, MP_WATER) || (IsTileType(tile, MP_STATION) && (IsBuoy(tile) || IsDock(tile))));
MakeWater(tile);
} else { switch (GetWaterClass(tile)) {
MakeCanal(tile, o, Random()); 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 */ /* Kill the depot, which is registered at the northernmost tile. Use that one */
delete GetDepotByTile(tile2 < tile ? tile2 : tile); delete GetDepotByTile(tile2 < tile ? tile2 : tile);
MakeWaterOrCanalDependingOnOwner(tile, GetShipDepotWaterOwner(tile)); MakeWaterKeepingClass(tile, GetShipDepotWaterOwner(tile));
MakeWaterOrCanalDependingOnOwner(tile2, GetShipDepotWaterOwner(tile2)); MakeWaterKeepingClass(tile2, GetShipDepotWaterOwner(tile2));
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile2); MarkTileDirtyByTile(tile2);
} }
@ -237,6 +246,8 @@ static CommandCost DoBuildShiplift(TileIndex tile, DiagDirection dir, uint32 fla
delta = TileOffsByDiagDir(dir); delta = TileOffsByDiagDir(dir);
/* lower tile */ /* lower tile */
WaterClass wc_lower = IsWaterTile(tile - delta) ? GetWaterClass(tile - delta) : WATER_CLASS_CANAL;
ret = DoCommand(tile - delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR); ret = DoCommand(tile - delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return CMD_ERROR; if (CmdFailed(ret)) return CMD_ERROR;
if (GetTileSlope(tile - delta, NULL) != SLOPE_FLAT) { if (GetTileSlope(tile - delta, NULL) != SLOPE_FLAT) {
@ -244,6 +255,8 @@ static CommandCost DoBuildShiplift(TileIndex tile, DiagDirection dir, uint32 fla
} }
/* upper tile */ /* upper tile */
WaterClass wc_upper = IsWaterTile(tile + delta) ? GetWaterClass(tile + delta) : WATER_CLASS_CANAL;
ret = DoCommand(tile + delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR); ret = DoCommand(tile + delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (CmdFailed(ret)) return CMD_ERROR; if (CmdFailed(ret)) return CMD_ERROR;
if (GetTileSlope(tile + delta, NULL) != SLOPE_FLAT) { if (GetTileSlope(tile + delta, NULL) != SLOPE_FLAT) {
@ -257,7 +270,7 @@ static CommandCost DoBuildShiplift(TileIndex tile, DiagDirection dir, uint32 fla
} }
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
MakeLock(tile, _current_player, dir); MakeLock(tile, _current_player, dir, wc_lower, wc_upper);
MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile - delta); MarkTileDirtyByTile(tile - delta);
MarkTileDirtyByTile(tile + delta); MarkTileDirtyByTile(tile + delta);
@ -280,8 +293,10 @@ static CommandCost RemoveShiplift(TileIndex tile, uint32 flags)
if (flags & DC_EXEC) { if (flags & DC_EXEC) {
DoClearSquare(tile); DoClearSquare(tile);
MakeWaterOrCanalDependingOnSurroundings(tile + delta, _current_player); MakeWaterKeepingClass(tile + delta, GetTileOwner(tile));
MakeWaterOrCanalDependingOnSurroundings(tile - delta, _current_player); MakeWaterKeepingClass(tile - delta, GetTileOwner(tile));
MarkTileDirtyByTile(tile - delta);
MarkTileDirtyByTile(tile + delta);
MarkCanalsAndRiversAroundDirty(tile - delta); MarkCanalsAndRiversAroundDirty(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); if (dir == INVALID_DIAGDIR) return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
/* Disallow building of locks on river rapids */ /* 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); return DoBuildShiplift(tile, dir, flags);
} }
@ -379,7 +394,6 @@ static CommandCost ClearTile_Water(TileIndex tile, byte flags)
{ {
switch (GetWaterTileType(tile)) { switch (GetWaterTileType(tile)) {
case WATER_TILE_CLEAR: case WATER_TILE_CLEAR:
case WATER_TILE_RIVER:
if (flags & DC_NO_WATER) return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER); if (flags & DC_NO_WATER) return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
/* Make sure it's not an edge tile. */ /* Make sure it's not an edge tile. */
@ -472,7 +486,7 @@ static bool IsWateredTile(TileIndex tile, Direction from)
} }
return false; 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; case MP_INDUSTRY: return (GetIndustrySpec(GetIndustryType(tile))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0;
default: return false; default: return false;
} }
@ -518,9 +532,17 @@ static void DrawWaterEdges(SpriteID base, TileIndex tile)
} }
} }
/** draw a canal styled water tile with dikes around */ /** Draw a plain sea water tile with no edges */
void DrawCanalWater(TileIndex tile) void DrawSeaWater(TileIndex tile)
{ {
DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE);
}
/** draw a canal styled water tile with dikes around */
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 */ /* Test for custom graphics, else use the default */
SpriteID dikes_base = GetCanalSprite(CF_DIKES, tile); SpriteID dikes_base = GetCanalSprite(CF_DIKES, tile);
if (dikes_base == 0) dikes_base = SPR_CANAL_DIKES_BASE; 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 image = SPR_FLAT_WATER_TILE;
SpriteID edges_base = GetCanalSprite(CF_RIVER_EDGE, ti->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. */ /* Draw river edges if available. */
if (edges_base > 48) DrawWaterEdges(edges_base, ti->tile); if (edges_base > 48) DrawWaterEdges(edges_base, ti->tile);
@ -619,8 +641,11 @@ static void DrawTile_Water(TileInfo *ti)
{ {
switch (GetWaterTileType(ti->tile)) { switch (GetWaterTileType(ti->tile)) {
case WATER_TILE_CLEAR: case WATER_TILE_CLEAR:
DrawGroundSprite(SPR_FLAT_WATER_TILE, PAL_NONE); switch (GetWaterClass(ti->tile)) {
if (IsCanal(ti->tile)) DrawCanalWater(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); DrawBridgeMiddle(ti);
break; break;
@ -637,11 +662,6 @@ static void DrawTile_Water(TileInfo *ti)
case WATER_TILE_DEPOT: case WATER_TILE_DEPOT:
DrawWaterStuff(ti, _shipdepot_display_seq[GetSection(ti->tile)], PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile)), 0); DrawWaterStuff(ti, _shipdepot_display_seq[GetSection(ti->tile)], PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile)), 0);
break; 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)) { switch (GetWaterTileType(tile)) {
case WATER_TILE_CLEAR: case WATER_TILE_CLEAR:
case WATER_TILE_RIVER:
if (!IsCanal(tile)) { if (!IsCanal(tile)) {
td->str = STR_3804_WATER; td->str = STR_3804_WATER;
} else { } else {
@ -842,7 +861,7 @@ static FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
Slope tileh = GetTileSlope(tile, NULL); Slope tileh = GetTileSlope(tile, NULL);
return (IsSlopeWithOneCornerRaised(tileh) ? FLOOD_ACTIVE : FLOOD_DRYUP); return (IsSlopeWithOneCornerRaised(tileh) ? FLOOD_ACTIVE : FLOOD_DRYUP);
} else { } 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: case MP_RAILWAY:
@ -855,7 +874,7 @@ static FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
return (GetTreeGround(tile) == TREE_GROUND_SHORE ? FLOOD_DRYUP : FLOOD_NONE); return (GetTreeGround(tile) == TREE_GROUND_SHORE ? FLOOD_DRYUP : FLOOD_NONE);
case MP_STATION: 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; if (IsOilRig(tile) || IsDock(tile)) return FLOOD_PASSIVE;
return FLOOD_NONE; return FLOOD_NONE;
@ -1073,11 +1092,10 @@ static uint32 GetTileTrackStatus_Water(TileIndex tile, TransportType mode, uint
if (mode != TRANSPORT_WATER) return 0; if (mode != TRANSPORT_WATER) return 0;
switch (GetWaterTileType(tile)) { 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_COAST: ts = (TrackBits)coast_tracks[GetTileSlope(tile, NULL) & 0xF]; break;
case WATER_TILE_LOCK: ts = AxisToTrackBits(DiagDirToAxis(GetLockDirection(tile))); break; case WATER_TILE_LOCK: ts = AxisToTrackBits(DiagDirToAxis(GetLockDirection(tile))); break;
case WATER_TILE_DEPOT: ts = AxisToTrackBits(GetShipDepotAxis(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; default: return 0;
} }
if (TileX(tile) == 0) { if (TileX(tile) == 0) {

View File

@ -10,7 +10,12 @@ enum WaterTileType {
WATER_TILE_COAST, WATER_TILE_COAST,
WATER_TILE_LOCK, WATER_TILE_LOCK,
WATER_TILE_DEPOT, WATER_TILE_DEPOT,
WATER_TILE_RIVER, };
enum WaterClass {
WATER_CLASS_SEA,
WATER_CLASS_CANAL,
WATER_CLASS_RIVER,
}; };
enum DepotPart { enum DepotPart {
@ -32,13 +37,24 @@ static inline WaterTileType GetWaterTileType(TileIndex t)
if (_m[t].m5 == 0) return WATER_TILE_CLEAR; if (_m[t].m5 == 0) return WATER_TILE_CLEAR;
if (_m[t].m5 == 1) return WATER_TILE_COAST; if (_m[t].m5 == 1) return WATER_TILE_COAST;
if (_m[t].m5 == 2) return WATER_TILE_RIVER;
if (IsInsideMM(_m[t].m5, LOCK_MIDDLE, LOCK_END)) return WATER_TILE_LOCK; if (IsInsideMM(_m[t].m5, LOCK_MIDDLE, LOCK_END)) return WATER_TILE_LOCK;
assert(IsInsideMM(_m[t].m5, DEPOT_NORTH, DEPOT_END)); assert(IsInsideMM(_m[t].m5, DEPOT_NORTH, DEPOT_END));
return WATER_TILE_DEPOT; return WATER_TILE_DEPOT;
} }
static inline WaterClass GetWaterClass(TileIndex t)
{
assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION));
return (WaterClass)GB(_m[t].m3, 0, 2);
}
static inline void SetWaterClass(TileIndex t, WaterClass wc)
{
assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION));
SB(_m[t].m3, 0, 2, wc);
}
/** IsWater return true if any type of clear water like ocean, river, canal */ /** IsWater return true if any type of clear water like ocean, river, canal */
static inline bool IsWater(TileIndex t) static inline bool IsWater(TileIndex t)
{ {
@ -47,24 +63,17 @@ static inline bool IsWater(TileIndex t)
static inline bool IsSea(TileIndex t) static inline bool IsSea(TileIndex t)
{ {
if (GetWaterTileType(t) != WATER_TILE_CLEAR) return false; return IsWater(t) && GetWaterClass(t) == WATER_CLASS_SEA;
if (!IsTileOwner(t, OWNER_WATER)) return false; // 'Human' built water = canal, not sea
return true;
}
static inline bool IsCoast(TileIndex t)
{
return GetWaterTileType(t) == WATER_TILE_COAST;
} }
static inline bool IsCanal(TileIndex t) static inline bool IsCanal(TileIndex t)
{ {
return GetWaterTileType(t) == WATER_TILE_CLEAR && GetTileOwner(t) != OWNER_WATER; return IsWater(t) && GetWaterClass(t) == WATER_CLASS_CANAL;
} }
static inline bool IsRiver(TileIndex t) static inline bool IsRiver(TileIndex t)
{ {
return GetWaterTileType(t) == WATER_TILE_RIVER; return IsWater(t) && GetWaterClass(t) == WATER_CLASS_RIVER;
} }
static inline bool IsWaterTile(TileIndex t) static inline bool IsWaterTile(TileIndex t)
@ -72,9 +81,9 @@ static inline bool IsWaterTile(TileIndex t)
return IsTileType(t, MP_WATER) && IsWater(t); return IsTileType(t, MP_WATER) && IsWater(t);
} }
static inline bool IsRiverTile(TileIndex t) static inline bool IsCoast(TileIndex t)
{ {
return IsTileType(t, MP_WATER) && IsRiver(t); return GetWaterTileType(t) == WATER_TILE_COAST;
} }
static inline TileIndex GetOtherShipDepotTile(TileIndex t) static inline TileIndex GetOtherShipDepotTile(TileIndex t)
@ -124,7 +133,7 @@ static inline void MakeWater(TileIndex t)
SetTileType(t, MP_WATER); SetTileType(t, MP_WATER);
SetTileOwner(t, OWNER_WATER); SetTileOwner(t, OWNER_WATER);
_m[t].m2 = 0; _m[t].m2 = 0;
_m[t].m3 = 0; _m[t].m3 = WATER_CLASS_SEA;
_m[t].m4 = 0; _m[t].m4 = 0;
_m[t].m5 = 0; _m[t].m5 = 0;
} }
@ -144,9 +153,9 @@ static inline void MakeRiver(TileIndex t, uint8 random_bits)
SetTileType(t, MP_WATER); SetTileType(t, MP_WATER);
SetTileOwner(t, OWNER_WATER); SetTileOwner(t, OWNER_WATER);
_m[t].m2 = 0; _m[t].m2 = 0;
_m[t].m3 = 0; _m[t].m3 = WATER_CLASS_RIVER;
_m[t].m4 = random_bits; _m[t].m4 = random_bits;
_m[t].m5 = 2; _m[t].m5 = 0;
} }
static inline void MakeCanal(TileIndex t, Owner o, uint8 random_bits) static inline void MakeCanal(TileIndex t, Owner o, uint8 random_bits)
@ -155,38 +164,38 @@ static inline void MakeCanal(TileIndex t, Owner o, uint8 random_bits)
SetTileType(t, MP_WATER); SetTileType(t, MP_WATER);
SetTileOwner(t, o); SetTileOwner(t, o);
_m[t].m2 = 0; _m[t].m2 = 0;
_m[t].m3 = 0; _m[t].m3 = WATER_CLASS_CANAL;
_m[t].m4 = random_bits; _m[t].m4 = random_bits;
_m[t].m5 = 0; _m[t].m5 = 0;
} }
static inline void MakeShipDepot(TileIndex t, Owner o, DepotPart base, Axis a, Owner original_owner) static inline void MakeShipDepot(TileIndex t, Owner o, DepotPart base, Axis a, WaterClass original_water_class, Owner original_owner)
{ {
SetTileType(t, MP_WATER); SetTileType(t, MP_WATER);
SetTileOwner(t, o); SetTileOwner(t, o);
_m[t].m2 = 0; _m[t].m2 = 0;
_m[t].m3 = 0; _m[t].m3 = original_water_class;
_m[t].m4 = original_owner; _m[t].m4 = original_owner;
_m[t].m5 = base + a * 2; _m[t].m5 = base + a * 2;
} }
static inline void MakeLockTile(TileIndex t, Owner o, byte section) static inline void MakeLockTile(TileIndex t, Owner o, byte section, WaterClass original_water_class)
{ {
SetTileType(t, MP_WATER); SetTileType(t, MP_WATER);
SetTileOwner(t, o); SetTileOwner(t, o);
_m[t].m2 = 0; _m[t].m2 = 0;
_m[t].m3 = 0; _m[t].m3 = original_water_class;
_m[t].m4 = 0; _m[t].m4 = 0;
_m[t].m5 = section; _m[t].m5 = section;
} }
static inline void MakeLock(TileIndex t, Owner o, DiagDirection d) static inline void MakeLock(TileIndex t, Owner o, DiagDirection d, WaterClass wc_lower, WaterClass wc_upper)
{ {
TileIndexDiff delta = TileOffsByDiagDir(d); TileIndexDiff delta = TileOffsByDiagDir(d);
MakeLockTile(t, o, LOCK_MIDDLE + d); MakeLockTile(t, o, LOCK_MIDDLE + d, WATER_CLASS_CANAL);
MakeLockTile(t - delta, o, LOCK_LOWER + d); MakeLockTile(t - delta, o, LOCK_LOWER + d, wc_lower);
MakeLockTile(t + delta, o, LOCK_UPPER + d); MakeLockTile(t + delta, o, LOCK_UPPER + d, wc_upper);
} }
#endif /* WATER_MAP_H */ #endif /* WATER_MAP_H */