diff --git a/docs/landscape.html b/docs/landscape.html
--- a/docs/landscape.html
+++ b/docs/landscape.html
@@ -989,8 +989,11 @@
+
m6 bit 7: rail station / waypoint may have catenary pylons
+ m6 bit 6: rail station / waypoint may have catenary wires
m6 bits 5..3: the station type (rail, airport, truck, bus, oilrig, dock, buoy, waypoint)
m6 bit 2: pbs reservation state for railway stations/waypoints
+ m6 bit 0: rail station / waypoint is blocked
m7 bits 4..0: owner of road (road stops)
m7: animation frame (railway stations/waypoints, airports)
diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html
--- a/docs/landscape_grid.html
+++ b/docs/landscape_grid.html
@@ -188,7 +188,7 @@ the array so you can quickly see what is
XXXX OOOO |
XXXX XXXX |
XXXX XXXX |
- OOXXX XOO |
+ XXXXX XOX |
XXXX XXXX |
OOOO OOOO OOXX XXXX |
diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp
--- a/src/newgrf_station.cpp
+++ b/src/newgrf_station.cpp
@@ -840,46 +840,6 @@ const StationSpec *GetStationSpec(TileIn
return specindex < st->speclist.size() ? st->speclist[specindex].spec : nullptr;
}
-
-/**
- * Check whether a rail station tile is NOT traversable.
- * @param tile %Tile to test.
- * @return Station tile is blocked.
- * @note This could be cached (during build) in the map array to save on all the dereferencing.
- */
-bool IsStationTileBlocked(TileIndex tile)
-{
- const StationSpec *statspec = GetStationSpec(tile);
-
- return statspec != nullptr && HasBit(statspec->blocked, GetStationGfx(tile));
-}
-
-/**
- * Check if a rail station tile shall have pylons when electrified.
- * @param tile %Tile to test.
- * @return Tile shall have pylons.
- * @note This could be cached (during build) in the map array to save on all the dereferencing.
- */
-bool CanStationTileHavePylons(TileIndex tile)
-{
- const StationSpec *statspec = GetStationSpec(tile);
- uint gfx = GetStationGfx(tile);
- /* Default stations do not draw pylons under roofs (gfx >= 4) */
- return statspec != nullptr ? HasBit(statspec->pylons, gfx) : gfx < 4;
-}
-
-/**
- * Check if a rail station tile shall have wires when electrified.
- * @param tile %Tile to test.
- * @return Tile shall have wires.
- * @note This could be cached (during build) in the map array to save on all the dereferencing.
- */
-bool CanStationTileHaveWires(TileIndex tile)
-{
- const StationSpec *statspec = GetStationSpec(tile);
- return statspec == nullptr || !HasBit(statspec->wires, GetStationGfx(tile));
-}
-
/** Wrapper for animation control, see GetStationCallback. */
uint16_t GetAnimStationCallback(CallbackID callback, uint32_t param1, uint32_t param2, const StationSpec *statspec, BaseStation *st, TileIndex tile, int)
{
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -47,6 +47,7 @@
#include "../subsidy_base.h"
#include "../subsidy_func.h"
#include "../newgrf.h"
+#include "../newgrf_station.h"
#include "../engine_func.h"
#include "../rail_gui.h"
#include "../core/backup_type.hpp"
@@ -2856,6 +2857,26 @@ bool AfterLoadGame()
_settings_game.script.settings_profile = IsInsideMM(_old_diff_level, SP_BEGIN, SP_END) ? _old_diff_level : (uint)SP_MEDIUM;
}
+ {
+ /* Station blocked, wires and pylon flags need to be stored in the map. This is effectively cached data, so no
+ * version check is necessary. This is done here as the SLV_182 check below needs the blocked status. */
+ for (auto t : Map::Iterate()) {
+ if (HasStationTileRail(t)) {
+ StationGfx gfx = GetStationGfx(t);
+ const StationSpec *statspec = GetStationSpec(t);
+
+ bool blocked = statspec != nullptr && HasBit(statspec->blocked, gfx);
+ /* Default stations do not draw pylons under roofs (gfx >= 4) */
+ bool pylons = statspec != nullptr ? HasBit(statspec->pylons, gfx) : gfx < 4;
+ bool wires = statspec == nullptr || !HasBit(statspec->wires, gfx);
+
+ SetStationTileBlocked(t, blocked);
+ SetStationTileHavePylons(t, pylons);
+ SetStationTileHaveWires(t, wires);
+ }
+ }
+ }
+
if (IsSavegameVersionBefore(SLV_182)) {
/* Aircraft acceleration variable was bonkers */
for (Aircraft *v : Aircraft::Iterate()) {
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -1466,7 +1466,18 @@ CommandCost CmdBuildRailStation(DoComman
SetStationTileRandomBits(tile, GB(Random(), 0, 4));
SetAnimationFrame(tile, 0);
- if (!IsStationTileBlocked(tile)) c->infrastructure.rail[rt]++;
+ /* Should be the same as layout but axis component could be wrong... */
+ StationGfx gfx = GetStationGfx(tile);
+ bool blocked = statspec != nullptr && HasBit(statspec->blocked, gfx);
+ /* Default stations do not draw pylons under roofs (gfx >= 4) */
+ bool pylons = statspec != nullptr ? HasBit(statspec->pylons, gfx) : gfx < 4;
+ bool wires = statspec == nullptr || !HasBit(statspec->wires, gfx);
+
+ SetStationTileBlocked(tile, blocked);
+ SetStationTileHavePylons(tile, pylons);
+ SetStationTileHaveWires(tile, wires);
+
+ if (!blocked) c->infrastructure.rail[rt]++;
c->infrastructure.station++;
if (statspec != nullptr) {
diff --git a/src/station_func.h b/src/station_func.h
--- a/src/station_func.h
+++ b/src/station_func.h
@@ -43,12 +43,6 @@ void UpdateStationDockingTiles(Station *
void RemoveDockingTile(TileIndex t);
void ClearDockingTilesCheckingNeighbours(TileIndex tile);
-/* Check if a rail station tile is traversable. */
-bool IsStationTileBlocked(TileIndex tile);
-
-bool CanStationTileHavePylons(TileIndex tile);
-bool CanStationTileHaveWires(TileIndex tile);
-
void UpdateAirportsNoise();
bool SplitGroundSpriteForOverlay(const TileInfo *ti, SpriteID *ground, RailTrackOffset *overlay_offset);
diff --git a/src/station_map.h b/src/station_map.h
--- a/src/station_map.h
+++ b/src/station_map.h
@@ -330,6 +330,78 @@ static inline bool IsHangarTile(Tile t)
}
/**
+ * Is tile \a t a blocked tile?
+ * @pre HasStationRail(t)
+ * @param t Tile to check
+ * @return \c true if the tile is blocked
+ */
+static inline bool IsStationTileBlocked(Tile t)
+{
+ assert(HasStationRail(t));
+ return HasBit(t.m6(), 0);
+}
+
+/**
+ * Set the blocked state of the rail station
+ * @pre HasStationRail(t)
+ * @param t the station tile
+ * @param b the blocked state
+ */
+static inline void SetStationTileBlocked(Tile t, bool b)
+{
+ assert(HasStationRail(t));
+ SB(t.m6(), 0, 1, b ? 1 : 0);
+}
+
+/**
+ * Can tile \a t have catenary wires?
+ * @pre HasStationRail(t)
+ * @param t Tile to check
+ * @return \c true if the tile can have catenary wires
+ */
+static inline bool CanStationTileHaveWires(Tile t)
+{
+ assert(HasStationRail(t));
+ return HasBit(t.m6(), 6);
+}
+
+/**
+ * Set the catenary wires state of the rail station
+ * @pre HasStationRail(t)
+ * @param t the station tile
+ * @param b the catenary wires state
+ */
+static inline void SetStationTileHaveWires(Tile t, bool b)
+{
+ assert(HasStationRail(t));
+ SB(t.m6(), 6, 1, b ? 1 : 0);
+}
+
+/**
+ * Can tile \a t have catenary pylons?
+ * @pre HasStationRail(t)
+ * @param t Tile to check
+ * @return \c true if the tile can have catenary pylons
+ */
+static inline bool CanStationTileHavePylons(Tile t)
+{
+ assert(HasStationRail(t));
+ return HasBit(t.m6(), 7);
+}
+
+/**
+ * Set the catenary pylon state of the rail station
+ * @pre HasStationRail(t)
+ * @param t the station tile
+ * @param b the catenary pylons state
+ */
+static inline void SetStationTileHavePylons(Tile t, bool b)
+{
+ assert(HasStationRail(t));
+ SB(t.m6(), 7, 1, b ? 1 : 0);
+}
+
+/**
* Get the rail direction of a rail station.
* @param t Tile to query
* @pre HasStationRail(t)
@@ -379,10 +451,10 @@ static inline TrackBits GetRailStationTr
static inline bool IsCompatibleTrainStationTile(Tile test_tile, Tile station_tile)
{
assert(IsRailStationTile(station_tile));
- return IsRailStationTile(test_tile) && IsCompatibleRail(GetRailType(test_tile), GetRailType(station_tile)) &&
+ return IsRailStationTile(test_tile) && !IsStationTileBlocked(test_tile) &&
+ IsCompatibleRail(GetRailType(test_tile), GetRailType(station_tile)) &&
GetRailStationAxis(test_tile) == GetRailStationAxis(station_tile) &&
- GetStationIndex(test_tile) == GetStationIndex(station_tile) &&
- !IsStationTileBlocked(test_tile);
+ GetStationIndex(test_tile) == GetStationIndex(station_tile);
}
/**
diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp
--- a/src/waypoint_cmd.cpp
+++ b/src/waypoint_cmd.cpp
@@ -277,6 +277,18 @@ CommandCost CmdBuildRailWaypoint(DoComma
HasStationReservation(tile);
MakeRailWaypoint(tile, wp->owner, wp->index, axis, layout_ptr[i], GetRailType(tile));
SetCustomStationSpecIndex(tile, map_spec_index);
+
+ /* Should be the same as layout but axis component could be wrong... */
+ StationGfx gfx = GetStationGfx(tile);
+ bool blocked = spec != nullptr && HasBit(spec->blocked, gfx);
+ /* Default stations do not draw pylons under roofs (gfx >= 4) */
+ bool pylons = spec != nullptr ? HasBit(spec->pylons, gfx) : gfx < 4;
+ bool wires = spec == nullptr || !HasBit(spec->wires, gfx);
+
+ SetStationTileBlocked(tile, blocked);
+ SetStationTileHavePylons(tile, pylons);
+ SetStationTileHaveWires(tile, wires);
+
SetRailStationReservation(tile, reserved);
MarkTileDirtyByTile(tile);