mirror of https://github.com/OpenTTD/OpenTTD
(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
parent
7cf2c83462
commit
1d891a8b15
|
@ -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> </td>
|
<td nowrap valign=top><tt>00</tt> </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> </td>
|
|
||||||
<td align=left>river</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td nowrap valign=top><tt>10</tt>..<tt>1B</tt> </td>
|
<td nowrap valign=top><tt>10</tt>..<tt>1B</tt> </td>
|
||||||
<td align=left>canal locks
|
<td align=left>canal locks
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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!
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue