summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/landscape.html1
-rw-r--r--docs/landscape_grid.html2
-rw-r--r--src/industry_cmd.cpp25
-rw-r--r--src/industry_map.h16
-rw-r--r--src/newgrf_industrytiles.cpp11
-rw-r--r--src/openttd.cpp20
-rw-r--r--src/saveload.cpp2
-rw-r--r--src/station_cmd.cpp6
-rw-r--r--src/station_map.h3
-rw-r--r--src/water.h2
-rw-r--r--src/water_cmd.cpp45
-rw-r--r--src/water_map.h13
12 files changed, 110 insertions, 36 deletions
diff --git a/docs/landscape.html b/docs/landscape.html
index 9493f35a2..9a92ba9c0 100644
--- a/docs/landscape.html
+++ b/docs/landscape.html
@@ -1035,6 +1035,7 @@
<ul>
<li>m1 bit 7: clear = under construction
<ul>
+ <li>m1 bits 6..5 : Water class (sea, canal, river or land)
<li>m1 bits 3..2: construction counter, for buildings under construction incremented on every periodic tile processing</li>
<li>m1 bits 1..0: stage of construction (<tt>3</tt> = completed), incremented when the construction counter wraps around<br>
the meaning is different for some animated tiles which are never under construction (types <tt>01</tt>, <tt>1E</tt>..<tt>20</tt>, <tt>30</tt>, <tt>58</tt>; see above)</li>
diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html
index f47b7f43a..291447f30 100644
--- a/docs/landscape_grid.html
+++ b/docs/landscape_grid.html
@@ -293,7 +293,7 @@ the array so you can quickly see what is used and what is not.
<td>8</td>
<td class="caption">industry</td>
<td class="bits">XXXX XXXX</td>
- <td class="bits">X<span class="free">OOO</span> <span class="abuse">
+ <td class="bits">XXX<span class="free">O</span> <span class="abuse">
XXXX</span></td>
<td class="bits">XXXX XXXX XXXX XXXX</td>
<td class="bits">XXXX XXXX</td>
diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp
index 88d85486e..3d6f4bbd9 100644
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -147,7 +147,8 @@ Industry::~Industry()
BEGIN_TILE_LOOP(tile_cur, this->width, this->height, this->xy);
if (IsTileType(tile_cur, MP_INDUSTRY)) {
if (GetIndustryIndex(tile_cur) == this->index) {
- DoClearSquare(tile_cur);
+ /* MakeWaterKeepingClass() can also handle 'land' */
+ MakeWaterKeepingClass(tile_cur, OWNER_NONE);
}
} else if (IsTileType(tile_cur, MP_STATION) && IsOilRig(tile_cur)) {
DeleteOilRig(tile_cur);
@@ -300,7 +301,13 @@ static void DrawTile_Industry(TileInfo *ti)
/* DrawFoundation() modifes ti->z and ti->tileh */
if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED);
- DrawGroundSprite(image, pal);
+ /* If the ground sprite is the default flat water sprite, draw also canal/river borders.
+ * Do not do this if the tile's WaterClass is 'land'. */
+ if (image == SPR_FLAT_WATER_TILE && IsIndustryTileOnWater(ti->tile)) {
+ DrawWaterClassGround(ti);
+ } else {
+ DrawGroundSprite(image, pal);
+ }
/* If industries are transparent and invisible, do not draw the upper part */
if (IsInvisibilitySet(TO_INDUSTRIES)) return;
@@ -724,6 +731,8 @@ static void TileLoop_Industry(TileIndex tile)
IndustryGfx newgfx;
IndustryGfx gfx;
+ if (IsIndustryTileOnWater(tile)) TileLoop_Water(tile);
+
TriggerIndustryTile(tile, INDTILE_TRIGGER_TILE_LOOP);
if (!IsIndustryCompleted(tile)) {
@@ -748,14 +757,6 @@ static void TileLoop_Industry(TileIndex tile)
gfx = GetIndustryGfx(tile);
switch (gfx) {
- case GFX_OILRIG_1: // coast line at oilrigs
- case GFX_OILRIG_2:
- case GFX_OILRIG_3:
- case GFX_OILRIG_4:
- case GFX_OILRIG_5:
- TileLoop_Water(tile);
- break;
-
case GFX_COAL_MINE_TOWER_NOT_ANIMATED:
case GFX_COPPER_MINE_TOWER_NOT_ANIMATED:
case GFX_GOLD_MINE_TOWER_NOT_ANIMATED:
@@ -1548,9 +1549,11 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, int type, const Ind
size = it->ti.y;
if (size > i->height)i->height = size;
+ WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID);
+
DoCommand(cur_tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
- MakeIndustry(cur_tile, i->index, it->gfx, Random());
+ MakeIndustry(cur_tile, i->index, it->gfx, Random(), wc);
if (_generating_world) {
SetIndustryConstructionCounter(cur_tile, 3);
diff --git a/src/industry_map.h b/src/industry_map.h
index 77cab8920..04be3513a 100644
--- a/src/industry_map.h
+++ b/src/industry_map.h
@@ -7,7 +7,7 @@
#include "industry.h"
#include "tile_map.h"
-
+#include "water_map.h"
/**
@@ -155,13 +155,24 @@ static inline void SetIndustryGfx(TileIndex t, IndustryGfx gfx)
}
/**
+ * Tests if the industry tile was built on water.
+ * @param t the industry tile
+ * @return true iff on water
+ */
+static inline bool IsIndustryTileOnWater(TileIndex t)
+{
+ assert(IsTileType(t, MP_INDUSTRY));
+ return (GetWaterClass(t) != WATER_CLASS_INVALID);
+}
+
+/**
* Make the given tile an industry tile
* @param t the tile to make an industry tile
* @param index the industry this tile belongs to
* @param gfx the graphics to use for the tile
* @param random the random value
*/
-static inline void MakeIndustry(TileIndex t, IndustryID index, IndustryGfx gfx, uint8 random)
+static inline void MakeIndustry(TileIndex t, IndustryID index, IndustryGfx gfx, uint8 random, WaterClass wc)
{
SetTileType(t, MP_INDUSTRY);
_m[t].m1 = 0;
@@ -170,6 +181,7 @@ static inline void MakeIndustry(TileIndex t, IndustryID index, IndustryGfx gfx,
_m[t].m4 = 0;
SetIndustryGfx(t, gfx);
_me[t].m7 = random;
+ SetWaterClass(t, wc);
}
/**
diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp
index 7f0aa2b8b..63c7cbf34 100644
--- a/src/newgrf_industrytiles.cpp
+++ b/src/newgrf_industrytiles.cpp
@@ -25,6 +25,7 @@
#include "town.h"
#include "command_func.h"
#include "animated_tile_func.h"
+#include "water.h"
#include "table/sprites.h"
#include "table/strings.h"
@@ -185,7 +186,15 @@ void IndustryDrawTileLayout(const TileInfo *ti, const SpriteGroup *group, byte r
if (IS_CUSTOM_SPRITE(image)) image += stage;
- if (GB(image, 0, SPRITE_WIDTH) != 0) DrawGroundSprite(image, pal);
+ if (GB(image, 0, SPRITE_WIDTH) != 0) {
+ /* If the ground sprite is the default flat water sprite, draw also canal/river borders
+ * Do not do this if the tile's WaterClass is 'land'. */
+ if (image == SPR_FLAT_WATER_TILE && IsIndustryTileOnWater(ti->tile)) {
+ DrawWaterClassGround(ti);
+ } else {
+ DrawGroundSprite(image, pal);
+ }
+ }
foreach_draw_tile_seq(dtss, dts->seq) {
if (GB(dtss->image.sprite, 0, SPRITE_WIDTH) == 0) continue;
diff --git a/src/openttd.cpp b/src/openttd.cpp
index 31bfeb33d..29c230c8e 100644
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -2340,8 +2340,8 @@ bool AfterLoadGame()
for (TileIndex t = 0; t < map_size; t++) {
if (GetTileSlope(t, NULL) != SLOPE_FLAT) continue;
- if (IsTileType(t, MP_WATER) && IsLock(t)) SetWaterClassDependingOnSurroundings(t);
- if (IsTileType(t, MP_STATION) && (IsDock(t) || IsBuoy(t))) SetWaterClassDependingOnSurroundings(t);
+ if (IsTileType(t, MP_WATER) && IsLock(t)) SetWaterClassDependingOnSurroundings(t, false);
+ if (IsTileType(t, MP_STATION) && (IsDock(t) || IsBuoy(t))) SetWaterClassDependingOnSurroundings(t, false);
}
}
@@ -2438,6 +2438,22 @@ bool AfterLoadGame()
}
}
+ if (CheckSavegameVersion(99)) {
+ /* Set newly introduced WaterClass of industry tiles */
+ for (TileIndex t = 0; t < map_size; t++) {
+ if (IsTileType(t, MP_STATION) && IsOilRig(t)) {
+ SetWaterClassDependingOnSurroundings(t, true);
+ }
+ if (IsTileType(t, MP_INDUSTRY)) {
+ if ((GetIndustrySpec(GetIndustryType(t))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0) {
+ SetWaterClassDependingOnSurroundings(t, true);
+ } else {
+ SetWaterClass(t, WATER_CLASS_INVALID);
+ }
+ }
+ }
+ }
+
GamelogPrintDebug(1);
return InitializeWindowsAndCaches();
diff --git a/src/saveload.cpp b/src/saveload.cpp
index dd0824582..640ebcc7f 100644
--- a/src/saveload.cpp
+++ b/src/saveload.cpp
@@ -36,7 +36,7 @@
#include "table/strings.h"
-extern const uint16 SAVEGAME_VERSION = 98;
+extern const uint16 SAVEGAME_VERSION = 99;
SavegameType _savegame_type; ///< type of savegame we are loading
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 0fc0a14df..67afd5a1d 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -2932,7 +2932,8 @@ void BuildOilRig(TileIndex tile)
st->string_id = GenerateStationName(st, tile, STATIONNAMING_OILRIG);
- MakeOilrig(tile, st->index);
+ assert(IsTileType(tile, MP_INDUSTRY));
+ MakeOilrig(tile, st->index, GetWaterClass(tile));
st->owner = OWNER_NONE;
st->airport_flags = 0;
@@ -2967,7 +2968,8 @@ void DeleteOilRig(TileIndex tile)
{
Station *st = GetStationByTile(tile);
- MakeWater(tile);
+ MakeWaterKeepingClass(tile, OWNER_NONE);
+ MarkTileDirtyByTile(tile);
st->dock_tile = 0;
st->airport_tile = 0;
diff --git a/src/station_map.h b/src/station_map.h
index 0ec6797dc..7422a32e5 100644
--- a/src/station_map.h
+++ b/src/station_map.h
@@ -313,9 +313,10 @@ static inline void MakeDock(TileIndex t, Owner o, StationID sid, DiagDirection d
SetWaterClass(t + TileOffsByDiagDir(d), wc);
}
-static inline void MakeOilrig(TileIndex t, StationID sid)
+static inline void MakeOilrig(TileIndex t, StationID sid, WaterClass wc)
{
MakeStation(t, OWNER_NONE, sid, STATION_OILRIG, 0);
+ SetWaterClass(t, wc);
}
#endif /* STATION_MAP_H */
diff --git a/src/water.h b/src/water.h
index 2ed54856b..e54d2e1ea 100644
--- a/src/water.h
+++ b/src/water.h
@@ -15,6 +15,6 @@ void DrawWaterClassGround(const struct TileInfo *ti);
void DrawShoreTile(Slope tileh);
void MakeWaterKeepingClass(TileIndex tile, Owner o);
-void SetWaterClassDependingOnSurroundings(TileIndex t);
+void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_water_class);
#endif /* WATER_H */
diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp
index b72b0a9cf..dd90530ed 100644
--- a/src/water_cmd.cpp
+++ b/src/water_cmd.cpp
@@ -109,10 +109,20 @@ static void MarkCanalsAndRiversAroundDirty(TileIndex tile)
* whether the tile used to be canal or 'normal' water.
* @param t the tile to change.
* @param o the owner of the new tile.
+ * @param include_invalid_water_class Also consider WATER_CLASS_INVALID, i.e. industry tiles on land
*/
-void SetWaterClassDependingOnSurroundings(TileIndex t)
+void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_water_class)
{
- assert(GetTileSlope(t, NULL) == SLOPE_FLAT);
+ /* If the slope is not flat, we always assume 'land' (if allowed). Also for one-corner-raised-shores.
+ * Note: Wrt. autosloping under industry tiles this is the most fool-proof behaviour. */
+ if (GetTileSlope(t, NULL) != SLOPE_FLAT) {
+ if (include_invalid_water_class) {
+ SetWaterClass(t, WATER_CLASS_INVALID);
+ return;
+ } else {
+ NOT_REACHED();
+ }
+ }
/* Mark tile dirty in all cases */
MarkTileDirtyByTile(t);
@@ -158,6 +168,11 @@ void SetWaterClassDependingOnSurroundings(TileIndex t)
}
}
+ if (!has_water && !has_canal && !has_river && include_invalid_water_class) {
+ SetWaterClass(t, WATER_CLASS_INVALID);
+ return;
+ }
+
if (has_river && !has_canal) {
SetWaterClass(t, WATER_CLASS_RIVER);
} else if (has_canal || !has_water) {
@@ -219,12 +234,21 @@ CommandCost CmdBuildShipDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2
void MakeWaterKeepingClass(TileIndex tile, Owner o)
{
- assert(IsTileType(tile, MP_WATER) || (IsTileType(tile, MP_STATION) && (IsBuoy(tile) || IsDock(tile))));
+ assert(IsTileType(tile, MP_WATER) || (IsTileType(tile, MP_STATION) && (IsBuoy(tile) || IsDock(tile) || IsOilRig(tile))) || IsTileType(tile, MP_INDUSTRY));
+
+ WaterClass wc = GetWaterClass(tile);
+
+ /* Autoslope might turn an originally canal or river tile into land */
+ uint z;
+ if (GetTileSlope(tile, &z) != SLOPE_FLAT) wc = WATER_CLASS_INVALID;
- switch (GetWaterClass(tile)) {
+ if (wc == WATER_CLASS_SEA && z > 0) wc = WATER_CLASS_CANAL;
+
+ switch (wc) {
case WATER_CLASS_SEA: MakeWater(tile); break;
case WATER_CLASS_CANAL: MakeCanal(tile, o, Random()); break;
case WATER_CLASS_RIVER: MakeRiver(tile, Random()); break;
+ default: DoClearSquare(tile); break;
}
}
@@ -512,7 +536,7 @@ static bool IsWateredTile(TileIndex tile, Direction from)
return false;
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 IsIndustryTileOnWater(tile);
case MP_TUNNELBRIDGE: return GetTunnelBridgeTransportType(tile) == TRANSPORT_WATER && ReverseDiagDir(GetTunnelBridgeDirection(tile)) == DirToDiagDir(from);
default: return false;
}
@@ -671,6 +695,7 @@ void DrawWaterClassGround(const TileInfo *ti) {
case WATER_CLASS_SEA: DrawSeaWater(ti->tile); break;
case WATER_CLASS_CANAL: DrawCanalWater(ti->tile); break;
case WATER_CLASS_RIVER: DrawRiverWater(ti); break;
+ default: NOT_REACHED();
}
}
@@ -882,9 +907,9 @@ static void FloodVehicle(Vehicle *v)
*/
static FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
{
- /* FLOOD_ACTIVE: 'single-corner-raised'-coast, sea, sea-shipdepots, sea-buoys, sea-docks (water part), rail with flooded halftile
+ /* FLOOD_ACTIVE: 'single-corner-raised'-coast, sea, sea-shipdepots, sea-buoys, sea-docks (water part), rail with flooded halftile, sea-water-industries, sea-oilrigs
* FLOOD_DRYUP: coast with more than one corner raised, coast with rail-track, coast with trees
- * FLOOD_PASSIVE: oilrig, water-industries
+ * FLOOD_PASSIVE: (not used)
* FLOOD_NONE: canals, rivers, everything else
*/
switch (GetTileType(tile)) {
@@ -906,13 +931,13 @@ static FloodingBehaviour GetFloodingBehaviour(TileIndex tile)
return (GetTreeGround(tile) == TREE_GROUND_SHORE ? FLOOD_DRYUP : FLOOD_NONE);
case MP_STATION:
- if (IsBuoy(tile) || (IsDock(tile) && GetTileSlope(tile, NULL) == SLOPE_FLAT)) {
+ if (IsBuoy(tile) || (IsDock(tile) && GetTileSlope(tile, NULL) == SLOPE_FLAT) || IsOilRig(tile)) {
return (GetWaterClass(tile) == WATER_CLASS_SEA ? FLOOD_ACTIVE : FLOOD_NONE);
}
- return (IsOilRig(tile) ? FLOOD_PASSIVE : FLOOD_NONE);
+ return FLOOD_NONE;
case MP_INDUSTRY:
- return ((GetIndustrySpec(GetIndustryType(tile))->behaviour & INDUSTRYBEH_BUILT_ONWATER) != 0 ? FLOOD_PASSIVE : FLOOD_NONE);
+ return ((IsIndustryTileOnWater(tile) && GetWaterClass(tile) == WATER_CLASS_SEA) ? FLOOD_ACTIVE : FLOOD_NONE);
default:
return FLOOD_NONE;
diff --git a/src/water_map.h b/src/water_map.h
index 94e805342..a0faab036 100644
--- a/src/water_map.h
+++ b/src/water_map.h
@@ -16,6 +16,7 @@ enum WaterClass {
WATER_CLASS_SEA,
WATER_CLASS_CANAL,
WATER_CLASS_RIVER,
+ WATER_CLASS_INVALID, ///< Used for industry tiles on land (also for oilrig if newgrf says so)
};
enum DepotPart {
@@ -45,14 +46,18 @@ static inline WaterTileType GetWaterTileType(TileIndex t)
static inline WaterClass GetWaterClass(TileIndex t)
{
- assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION));
- return (WaterClass)GB(_m[t].m3, 0, 2);
+ assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY));
+ return (WaterClass)(IsTileType(t, MP_INDUSTRY) ? GB(_m[t].m1, 5, 2) : 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);
+ assert(IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY));
+ if (IsTileType(t, MP_INDUSTRY)) {
+ SB(_m[t].m1, 5, 2, wc);
+ } else {
+ SB(_m[t].m3, 0, 2, wc);
+ }
}
/** IsWater return true if any type of clear water like ocean, river, canal */