Index: docs/landscape.html
===================================================================
--- docs/landscape.html (revision 27221)
+++ docs/landscape.html (working copy)
@@ -855,6 +855,7 @@
|
+ - m1 bit 7: set if a river was originally present under water based station tiles when current water class is canal (dock, buoy, oilrig)
- m1 bits 6..5: water class for buoys, water part of docks and for airport tiles
- m1 bits 4..0: owner of the station
- m2: index into the array of stations
@@ -991,6 +992,7 @@
|
+ - m1 bit 7: set if a river was originally present at the tile when current water class is canal (canal, ship depot, lock)
- m1 bits 6..5 : Water class (sea, canal or river)
- m1 bits 4..0: owner (for sea, rivers, and coasts normally 11)
- m2: Depot index (for depots only)
@@ -1111,9 +1113,10 @@
|
- - m1 bit 7: clear = under construction
+
- m1 bit 7: set if a river was originally present at the tile when current water class is canal (oilrig)
+
- m1 bits 6..5 : Water class (sea, canal, river or land)
+
- m1 bit 4: clear = under construction
- - m1 bits 6..5 : Water class (sea, canal, river or land)
- m1 bits 3..2: construction counter, for buildings under construction incremented on every periodic tile processing
- m1 bits 1..0: stage of construction (3 = completed), incremented when the construction counter wraps around
the meaning is different for some animated tiles which are never under construction (types 01, 1E..20, 30, 58; see above)
@@ -1594,6 +1597,7 @@
|
+ - m1 bit 7: set if a river was originally present at the tile when current water class is canal
- m1 bits 6..5 : Water class (sea, canal, river or land)
- m1 bits 4..0: owner of the object (for lighthouses and transmitters normally 10)
- m2: index into the array of objects, bits 0 to 15 (upper bits in m5)
Index: docs/landscape_grid.html
===================================================================
--- docs/landscape_grid.html (revision 27221)
+++ docs/landscape_grid.html (working copy)
@@ -207,6 +207,7 @@
rail waypoint |
-inherit- |
-inherit- |
+ OXXX XXXX |
-inherit- |
-inherit- |
-inherit- |
@@ -213,14 +214,13 @@
-inherit- |
-inherit- |
-inherit- |
- -inherit- |
road stop |
-inherit- |
-inherit- |
+ OXXX XXXX |
-inherit- |
- -inherit- |
XXXX OOOO |
OOOO OOOO |
~~~~ ~XXX |
@@ -231,8 +231,8 @@
dock |
-inherit- |
-inherit- |
+ XXXX XXXX |
-inherit- |
- -inherit- |
OOOO OOOO |
OOOO OOOO |
~~~~ ~XXX |
@@ -243,8 +243,8 @@
airport |
-inherit- |
-inherit- |
+ OXXX XXXX |
-inherit- |
- -inherit- |
XXXX OOOO |
OOOO OOOO |
XXXX XXXX |
@@ -255,8 +255,8 @@
buoy |
-inherit- |
-inherit- |
+ XXXX XXXX |
-inherit- |
- -inherit- |
OOOO OOOO |
OOOO OOOO |
~~~~ ~~~~ |
@@ -267,8 +267,8 @@
oilrig |
-inherit- |
-inherit- |
+ XXXX XXXX |
-inherit- |
- -inherit- |
OOOO OOOO |
OOOO OOOO |
~~~~ ~~~~ |
@@ -276,7 +276,7 @@
OOOO OOOO |
- 6 |
+ 6 |
sea, shore |
XXXX XXXX |
XXXX XXXX |
@@ -284,31 +284,55 @@
OOOO OOOO OOOO OOOO |
OOOO OOOO |
OOOO OOOO |
+ X~~X ~~~X |
+ OOOO OOOO |
+ OOOO OOOO |
+
+
+ lock |
+ XXXX XXXX |
+ XXXX XXXX |
+ XXXX XXXX |
+ OOOO OOOO OOOO OOOO |
+ OOOO OOOO |
+ OOOO OOOO |
X~~X XXXX |
OOOO OOOO |
OOOO OOOO |
- canal, river |
+ canal |
-inherit- |
-inherit- |
- -inherit- |
+ XXXX XXXX |
OOOO OOOO OOOO OOOO |
OOOO OOOO |
XXXX XXXX |
+ X~~X ~~~X |
+ OOOO OOOO |
+ OOOO OOOO |
+
+
+ river |
-inherit- |
+ -inherit- |
+ OXXX XXXX |
+ OOOO OOOO OOOO OOOO |
OOOO OOOO |
+ XXXX XXXX |
+ X~~X ~~~X |
OOOO OOOO |
+ OOOO OOOO |
shipdepot |
-inherit- |
-inherit- |
- -inherit- |
+ XXXX XXXX |
XXXX XXXX XXXX XXXX |
OOOO OOOO |
OOOO OOOO |
- -inherit- |
+ X~~X ~~XX |
OOOO OOOO |
OOOO OOOO |
@@ -317,7 +341,7 @@
industry |
XXXX XXXX |
XXXX XXXX |
- XXXO XXXX |
+ XXXX XXXX |
XXXX XXXX XXXX XXXX |
XXXX XXXX |
XXXX XXXX |
@@ -355,7 +379,7 @@
objects |
XXXX XXXX |
XXXX XXXX |
- OXXX XXXX |
+ XXXX XXXX |
XXXX XXXX XXXX XXXX |
XXXX XXXX |
OOOO OOOO |
Index: src/industry_cmd.cpp
===================================================================
--- src/industry_cmd.cpp (revision 27221)
+++ src/industry_cmd.cpp (working copy)
@@ -1755,10 +1755,12 @@
i->location.Add(cur_tile);
WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID);
+ bool river = HasTileCanalOnRiver(cur_tile);
DoCommand(cur_tile, 0, 0, DC_EXEC | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR);
MakeIndustry(cur_tile, i->index, it->gfx, Random(), wc);
+ if (river) SetCanalOnRiver(cur_tile);
if (_generating_world) {
SetIndustryConstructionCounter(cur_tile, 3);
Index: src/industry_map.h
===================================================================
--- src/industry_map.h (revision 27221)
+++ src/industry_map.h (working copy)
@@ -77,7 +77,7 @@
static inline bool IsIndustryCompleted(TileIndex t)
{
assert(IsTileType(t, MP_INDUSTRY));
- return HasBit(_m[t].m1, 7);
+ return HasBit(_m[t].m1, 4);
}
IndustryType GetIndustryType(TileIndex tile);
@@ -90,7 +90,7 @@
static inline void SetIndustryCompleted(TileIndex tile)
{
assert(IsTileType(tile, MP_INDUSTRY));
- SB(_m[tile].m1, 7, 1, 1);
+ SB(_m[tile].m1, 4, 1, 1);
}
/**
@@ -189,8 +189,7 @@
static inline void ResetIndustryConstructionStage(TileIndex tile)
{
assert(IsTileType(tile, MP_INDUSTRY));
- SB(_m[tile].m1, 0, 4, 0);
- SB(_m[tile].m1, 7, 1, 0);
+ SB(_m[tile].m1, 0, 5, 0);
}
/**
Index: src/lang/english.txt
===================================================================
--- src/lang/english.txt (revision 27221)
+++ src/lang/english.txt (working copy)
@@ -4324,6 +4324,7 @@
STR_ERROR_CAN_T_BUILD_ON_RIVER :{WHITE}... can't build on river
STR_ERROR_MUST_DEMOLISH_CANAL_FIRST :{WHITE}Must demolish canal first
STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE :{WHITE}Can't build aqueduct here...
+STR_ERROR_MUST_CLEAR_RIVER_FIRST :{WHITE}Must clear river first
# Tree related errors
STR_ERROR_TREE_ALREADY_HERE :{WHITE}... tree already here
Index: src/saveload/afterload.cpp
===================================================================
--- src/saveload/afterload.cpp (revision 27221)
+++ src/saveload/afterload.cpp (working copy)
@@ -2985,6 +2985,18 @@
ResetSignalHandlers();
AfterLoadLinkGraphs();
+
+ if (IsSavegameVersionBefore(195)) {
+ for (TileIndex t = 0; t < map_size; t++) {
+ if (IsTileType(t, MP_INDUSTRY) && HasBit(_m[t].m1, 7)) {
+ SetIndustryCompleted(t);
+ SB(_m[t].m1, 7, 1, 0);
+ }
+ if (IsTileType(t, MP_STATION) && IsOilRig(t) && HasBit(_m[t].m1, 7)) {
+ SB(_m[t].m1, 7, 1, 0);
+ }
+ }
+ }
return true;
}
Index: src/saveload/saveload.cpp
===================================================================
--- src/saveload/saveload.cpp (revision 27221)
+++ src/saveload/saveload.cpp (working copy)
@@ -262,8 +262,9 @@
* 192 26700
* 193 26802
* 194 26881 1.5.x
+ * 195 27221 Canal on River v7
*/
-extern const uint16 SAVEGAME_VERSION = 194; ///< Current savegame version of OpenTTD.
+extern const uint16 SAVEGAME_VERSION = 195; ///< Current savegame version of OpenTTD.
SavegameType _savegame_type; ///< type of savegame we are loading
Index: src/station_cmd.cpp
===================================================================
--- src/station_cmd.cpp (revision 27221)
+++ src/station_cmd.cpp (working copy)
@@ -2511,6 +2511,7 @@
/* Get the water class of the water tile before it is cleared.*/
WaterClass wc = GetWaterClass(tile_cur);
+ bool canal_on_river = HasTileCanalOnRiver(tile_cur);
ret = DoCommand(tile_cur, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (ret.Failed()) return ret;
@@ -2551,6 +2552,7 @@
DirtyCompanyInfrastructureWindows(st->owner);
MakeDock(tile, st->owner, st->index, direction, wc);
+ if (canal_on_river) SetCanalOnRiver(tile + TileOffsByDiagDir(direction));
st->UpdateVirtCoord();
UpdateStationAcceptance(st, false);
Index: src/water_cmd.cpp
===================================================================
--- src/water_cmd.cpp (revision 27221)
+++ src/water_cmd.cpp (working copy)
@@ -120,6 +120,9 @@
WaterClass wc1 = GetWaterClass(tile);
WaterClass wc2 = GetWaterClass(tile2);
+ bool river1 = HasTileCanalOnRiver(tile);
+ bool river2 = HasTileCanalOnRiver(tile2);
+
CommandCost cost = CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_DEPOT_SHIP]);
bool add_cost = !IsWaterTile(tile);
@@ -148,6 +151,8 @@
MakeShipDepot(tile, _current_company, depot->index, DEPOT_PART_NORTH, axis, wc1);
MakeShipDepot(tile2, _current_company, depot->index, DEPOT_PART_SOUTH, axis, wc2);
+ if (river1) SetCanalOnRiver(tile);
+ if (river2) SetCanalOnRiver(tile2);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile2);
MakeDefaultName(depot);
@@ -194,14 +199,26 @@
}
/* Zero map array and terminate animation */
+ bool river = HasTileCanalOnRiver(tile);
DoClearSquare(tile);
/* Maybe change to water */
switch (wc) {
- case WATER_CLASS_SEA: MakeSea(tile); break;
- case WATER_CLASS_CANAL: MakeCanal(tile, o, Random()); break;
- case WATER_CLASS_RIVER: MakeRiver(tile, Random()); break;
- default: break;
+ case WATER_CLASS_SEA:
+ MakeSea(tile);
+ break;
+
+ case WATER_CLASS_CANAL:
+ MakeCanal(tile, o, Random());
+ if (river) SetCanalOnRiver(tile);
+ break;
+
+ case WATER_CLASS_RIVER:
+ MakeRiver(tile, Random());
+ break;
+
+ default:
+ break;
}
MarkTileDirtyByTile(tile);
@@ -264,6 +281,7 @@
/* lower tile */
WaterClass wc_lower = IsWaterTile(tile - delta) ? GetWaterClass(tile - delta) : WATER_CLASS_CANAL;
+ bool river_lower = HasTileCanalOnRiver(tile - delta);
if (!IsWaterTile(tile - delta)) {
ret = DoCommand(tile - delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
@@ -277,6 +295,7 @@
/* upper tile */
WaterClass wc_upper = IsWaterTile(tile + delta) ? GetWaterClass(tile + delta) : WATER_CLASS_CANAL;
+ bool river_upper = HasTileCanalOnRiver(tile + delta);
if (!IsWaterTile(tile + delta)) {
ret = DoCommand(tile + delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
@@ -291,7 +310,7 @@
if (IsBridgeAbove(tile) || IsBridgeAbove(tile - delta) || IsBridgeAbove(tile + delta)) {
return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
}
-
+
if (flags & DC_EXEC) {
/* Update company infrastructure counts. */
Company *c = Company::GetIfValid(_current_company);
@@ -305,6 +324,8 @@
}
MakeLock(tile, _current_company, dir, wc_lower, wc_upper, wc_middle);
+ if (river_lower) SetCanalOnRiver(tile - delta);
+ if (river_upper) SetCanalOnRiver(tile + delta);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile - delta);
MarkTileDirtyByTile(tile + delta);
@@ -419,6 +440,7 @@
if (IsTileType(tile, MP_WATER) && (!IsTileOwner(tile, OWNER_WATER) || wc == WATER_CLASS_SEA)) continue;
bool water = IsWaterTile(tile);
+ bool river = HasTileWaterClass(tile) && GetWaterClass(tile) == WATER_CLASS_RIVER;
ret = DoCommand(tile, 0, 0, flags | DC_FORCE_CLEAR_TILE, CMD_LANDSCAPE_CLEAR);
if (ret.Failed()) return ret;
@@ -443,6 +465,7 @@
default:
MakeCanal(tile, _current_company, Random());
+ if (river) SetCanalOnRiver(tile);
if (Company::IsValidID(_current_company)) {
Company::Get(_current_company)->infrastructure.water++;
DirtyCompanyInfrastructureWindows(_current_company);
@@ -465,6 +488,7 @@
static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags)
{
+ bool river = HasTileCanalOnRiver(tile);
switch (GetWaterTileType(tile)) {
case WATER_TILE_CLEAR: {
if (flags & DC_NO_WATER) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
@@ -492,6 +516,7 @@
DirtyCompanyInfrastructureWindows(owner);
}
DoClearSquare(tile);
+ if (river) MakeRiver(tile, Random());
MarkCanalsAndRiversAroundDirty(tile);
}
@@ -1311,8 +1336,11 @@
static CommandCost TerraformTile_Water(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new)
{
- /* Canals can't be terraformed */
- if (IsWaterTile(tile) && IsCanal(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_CANAL_FIRST);
+ /* Canals and rivers can't be terraformed */
+ if (IsWaterTile(tile)) {
+ if (IsCanal(tile)) return_cmd_error(STR_ERROR_MUST_DEMOLISH_CANAL_FIRST);
+ if (IsRiver(tile)) return_cmd_error(STR_ERROR_MUST_CLEAR_RIVER_FIRST);
+ }
return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
}
Index: src/water_map.h
===================================================================
--- src/water_map.h (revision 27221)
+++ src/water_map.h (working copy)
@@ -16,25 +16,26 @@
#include "tile_map.h"
/**
- * Bit field layout of m5 for water tiles.
+ * Bit field layout for water tiles.
*/
enum WaterTileTypeBitLayout {
- WBL_TYPE_BEGIN = 4, ///< Start of the 'type' bitfield.
- WBL_TYPE_COUNT = 4, ///< Length of the 'type' bitfield.
+ WBL_TYPE_BEGIN = 4, ///< First bit for the structure kind, in m5 bitfield.
+ WBL_TYPE_COUNT = 4, ///< Number of bits, for the structure kind, in m5 bitfield.
- WBL_TYPE_NORMAL = 0x0, ///< Clear water or coast ('type' bitfield).
- WBL_TYPE_LOCK = 0x1, ///< Lock ('type' bitfield).
- WBL_TYPE_DEPOT = 0x8, ///< Depot ('type' bitfield).
+ WBL_TYPE_NORMAL = 0x0, ///< Clear water or coast, in m5 (structure kind bitfield).
+ WBL_TYPE_LOCK = 0x1, ///< Lock, in m5 (structure kind bitfield).
+ WBL_TYPE_DEPOT = 0x8, ///< Depot, in m5 (structure kind bitfield).
- WBL_COAST_FLAG = 0, ///< Flag for coast.
+ WBL_COAST_FLAG = 0, ///< Flag for coast, in m5.
+ WBL_RIVER_FLAG = 7, ///< Flag for canal on river, in m1.
- WBL_LOCK_ORIENT_BEGIN = 0, ///< Start of lock orientiation bitfield.
- WBL_LOCK_ORIENT_COUNT = 2, ///< Length of lock orientiation bitfield.
- WBL_LOCK_PART_BEGIN = 2, ///< Start of lock part bitfield.
- WBL_LOCK_PART_COUNT = 2, ///< Length of lock part bitfield.
+ WBL_LOCK_ORIENT_BEGIN = 0, ///< Start of lock orientiation, in m5 bitfield.
+ WBL_LOCK_ORIENT_COUNT = 2, ///< Length of lock orientiation, in m5 bitfield.
+ WBL_LOCK_PART_BEGIN = 2, ///< Start of lock part, in m5 bitfield.
+ WBL_LOCK_PART_COUNT = 2, ///< Length of lock part, in m5 bitfield.
- WBL_DEPOT_PART = 0, ///< Depot part flag.
- WBL_DEPOT_AXIS = 1, ///< Depot axis flag.
+ WBL_DEPOT_PART = 0, ///< Depot part flag, in m5.
+ WBL_DEPOT_AXIS = 1, ///< Depot axis flag, in m5.
};
/** Available water tile types. */
@@ -55,6 +56,12 @@
/** Helper information for extract tool. */
template <> struct EnumPropsT : MakeEnumPropsT {};
+/** Bases of a canal (for #WATER_CLASS_CANAL class of water). */
+enum CanalBase {
+ WCC_WITHOUT_RIVER = 0, ///< Without a river under it
+ WCC_WITH_RIVER = 1, ///< With a river under it
+};
+
/** Sections of the water depot. */
enum DepotPart {
DEPOT_PART_NORTH = 0, ///< Northern part of a depot.
@@ -122,6 +129,40 @@
}
/**
+ * Get the base of the canal at a tile.
+ * @param t Water tile to query.
+ * @pre GetWaterClass(t) == WATER_CLASS_CANAL
+ * @return Base of the canal at the tile.
+ */
+static inline CanalBase GetCanalBase(TileIndex t)
+{
+ assert(GetWaterClass(t) == WATER_CLASS_CANAL);
+ return (CanalBase)HasBit(_m[t].m1, WBL_RIVER_FLAG) ? WCC_WITH_RIVER : WCC_WITHOUT_RIVER;
+}
+
+/**
+ * Set the base of the canal to indicate there is a river under a tile.
+ * @param t Water tile of water class canal to query.
+ * @pre GetWaterClass(t) == WATER_CLASS_CANAL
+ */
+static inline void SetCanalOnRiver(TileIndex t)
+{
+ assert(GetWaterClass(t) == WATER_CLASS_CANAL);
+ SB(_m[t].m1, WBL_RIVER_FLAG, 1, WCC_WITH_RIVER);
+}
+
+/**
+ * Checks whether the canal at a tile has a river under it.
+ * @param t Water tile of water class canal to query.
+ * @pre GetWaterClass(t) == WATER_CLASS_CANAL
+ * @return true if the canal has a river under it.
+ */
+static inline bool HasTileCanalOnRiver(TileIndex t)
+{
+ return HasTileWaterClass(t) && GetWaterClass(t) == WATER_CLASS_CANAL && GetCanalBase(t) == WCC_WITH_RIVER;
+}
+
+/**
* Tests if the tile was built on water.
* @param t the tile to check
* @pre IsTileType(t, MP_WATER) || IsTileType(t, MP_STATION) || IsTileType(t, MP_INDUSTRY) || IsTileType(t, MP_OBJECT)
| | | |