diff --git a/docs/newgrf-additions.html b/docs/newgrf-additions.html
index 03fc540e29..ed142badda 100644
--- a/docs/newgrf-additions.html
+++ b/docs/newgrf-additions.html
@@ -201,18 +201,38 @@
This property allows building bridges over stations.
- The bridge height property defines minimum clearances required for a bridge for each of the 8 station layouts (or 0 to not allow any bridge). Values are given in height level units (1 level == 8px).
- Each height value is 1 byte, the total property length is 8 bytes.
+ The bridge height property defines minimum clearances required for a bridge for each of the station layouts (or 0 to not allow any bridge). Values are given in height level units (1 level == 8px).
+
+
+ Fixed length of 8 values:
+ Each height value is 1 byte, the number of values (one for each station layout) is 8, the total property length is 8 bytes.
This is indicated by the feature name: action0_station_prop1B, version 1
+
+ Variable length:
+ Each height value is 1 byte, the number of values (one for each station layout) is variable, the total property length is variable.
+ The mappable property must be used, not variable 1B. The number of values is determined from the length.
+
+ This is indicated by the feature name: action0_station_min_bridge_height, version 1
+
Disallowed bridge pillars (mappable property: station_disallowed_bridge_pillars)
This property describes which bridge pillars are not allowed on the station tile.
- It consists of 8 pillar flags, for each of the 8 station layouts.
- Each set of flags is 1 byte, the total property length is 8 bytes.
+ It consists of N pillar flags, for each of the N station layouts.
+ Each set of flags is 1 byte.
Each set of flags has the format described in the bridge_pillar_flags property section, below.
+
+ Fixed length of 8 values:
+ Each set of flags is 1 byte, the number of values (one for each station layout) is 8, the total property length is 8 bytes.
+
This is indicated by the feature name: action0_station_disallowed_bridge_pillars, version 1
+ Variable length:
+ Each set of flags is 1 byte, the number of values (one for each station layout) is variable, the total property length is variable.
+ The number of values is determined from the length.
+
+ This is indicated by the feature name: action0_station_disallowed_bridge_pillars, version 2
+
The 8 station layouts are described below.
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 2b6f1ad255..92c271fb72 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -2148,23 +2148,33 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, cons
break;
}
- case A0RPI_STATION_MIN_BRIDGE_HEIGHT:
- if (MappedPropertyLengthMismatch(buf, 8, mapping_entry)) break;
- [[fallthrough]];
+ case A0RPI_STATION_MIN_BRIDGE_HEIGHT: {
+ SetBit(statspec->internal_flags, SSIF_BRIDGE_HEIGHTS_SET);
+ size_t length = buf->ReadExtendedByte();
+ if (statspec->bridge_above_flags.size() < length) statspec->bridge_above_flags.resize(length);
+ for (size_t i = 0; i < length; i++) {
+ statspec->bridge_above_flags[i].height = buf->ReadByte();
+ }
+ break;
+ }
+
case 0x1B: // Minimum height for a bridge above
SetBit(statspec->internal_flags, SSIF_BRIDGE_HEIGHTS_SET);
+ if (statspec->bridge_above_flags.size() < 8) statspec->bridge_above_flags.resize(8);
for (uint i = 0; i < 8; i++) {
- statspec->bridge_height[i] = buf->ReadByte();
+ statspec->bridge_above_flags[i].height = buf->ReadByte();
}
break;
- case A0RPI_STATION_DISALLOWED_BRIDGE_PILLARS:
- if (MappedPropertyLengthMismatch(buf, 8, mapping_entry)) break;
+ case A0RPI_STATION_DISALLOWED_BRIDGE_PILLARS: {
SetBit(statspec->internal_flags, SSIF_BRIDGE_DISALLOWED_PILLARS_SET);
- for (uint i = 0; i < 8; i++) {
- statspec->bridge_disallowed_pillars[i] = buf->ReadByte();
+ size_t length = buf->ReadExtendedByte();
+ if (statspec->bridge_above_flags.size() < length) statspec->bridge_above_flags.resize(length);
+ for (size_t i = 0; i < length; i++) {
+ statspec->bridge_above_flags[i].disallowed_pillars = buf->ReadByte();
}
break;
+ }
case 0x1C: // Station Name
AddStringForMapping(buf->ReadWord(), &statspec->name);
diff --git a/src/newgrf_extension.cpp b/src/newgrf_extension.cpp
index d3970f1ddf..6d7a9e067b 100644
--- a/src/newgrf_extension.cpp
+++ b/src/newgrf_extension.cpp
@@ -22,7 +22,8 @@ extern const GRFFeatureInfo _grf_feature_list[] = {
GRFFeatureInfo("feature_id_mapping", 2),
GRFFeatureInfo("action5_type_id_mapping", 2),
GRFFeatureInfo("action0_station_prop1B", 1),
- GRFFeatureInfo("action0_station_disallowed_bridge_pillars", 1),
+ GRFFeatureInfo("action0_station_min_bridge_height", 1),
+ GRFFeatureInfo("action0_station_disallowed_bridge_pillars", 2),
GRFFeatureInfo("varaction2_station_var42", 1),
GRFFeatureInfo("varaction2_station_station_nearby_info_v2", 1),
GRFFeatureInfo("more_bridge_types", 1),
diff --git a/src/newgrf_station.h b/src/newgrf_station.h
index 1be4c7e7cf..cf9ab76b61 100644
--- a/src/newgrf_station.h
+++ b/src/newgrf_station.h
@@ -177,8 +177,11 @@ struct StationSpec : NewGRFSpecBase {
uint8_t flags; ///< Bitmask of flags, bit 0: use different sprite set; bit 1: divide cargo about by station size
- uint8_t bridge_height[8]; ///< Minimum height for a bridge above, 0 for none
- uint8_t bridge_disallowed_pillars[8]; ///< Disallowed pillar flags for a bridge above
+ struct BridgeAboveFlags {
+ uint8_t height = UINT8_MAX; ///< Minimum height for a bridge above, 0 for none
+ uint8_t disallowed_pillars = 0; ///< Disallowed pillar flags for a bridge above
+ };
+ std::vector bridge_above_flags; ///< List of bridge above flags.
enum class TileFlags : uint8_t {
None = 0,
@@ -194,6 +197,12 @@ struct StationSpec : NewGRFSpecBase {
/** Custom platform layouts, keyed by platform and length combined. */
std::unordered_map> layouts;
+
+ BridgeAboveFlags GetBridgeAboveFlags(uint gfx) const
+ {
+ if (gfx < this->bridge_above_flags.size()) return this->bridge_above_flags[gfx];
+ return {};
+ }
};
DECLARE_ENUM_AS_BIT_SET(StationSpec::TileFlags);
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 660d3ad66e..3c76b4298f 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -924,15 +924,14 @@ CommandCost CheckBuildableTile(TileIndex tile, uint invalid_dirs, int &allowed_z
CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec *statspec, uint8_t layout, TileIndex northern_bridge_end, TileIndex southern_bridge_end, int bridge_height,
BridgeType bridge_type, TransportType bridge_transport_type)
{
- assert(layout < 8);
-
- if (statspec && HasBit(statspec->internal_flags, SSIF_BRIDGE_HEIGHTS_SET)) {
- if (statspec->bridge_height[layout] == 0) return CommandCost(INVALID_STRING_ID);
- if (GetTileMaxZ(tile) + statspec->bridge_height[layout] > bridge_height) {
+ if (statspec != nullptr && HasBit(statspec->internal_flags, SSIF_BRIDGE_HEIGHTS_SET)) {
+ int height_above = statspec->GetBridgeAboveFlags(layout).height;
+ if (height_above == 0) return CommandCost(INVALID_STRING_ID);
+ if (GetTileMaxZ(tile) + height_above > bridge_height) {
return CommandCost(STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION);
}
} else if (!statspec) {
- // default stations/waypoints
+ /* Default stations/waypoints */
const int height = layout < 4 ? 2 : 5;
if (GetTileMaxZ(tile) + height > bridge_height) return CommandCost(STR_ERROR_BRIDGE_TOO_LOW_FOR_STATION);
} else {
@@ -940,18 +939,22 @@ CommandCost IsRailStationBridgeAboveOk(TileIndex tile, const StationSpec *statsp
}
BridgePiecePillarFlags disallowed_pillar_flags;
- if (statspec && HasBit(statspec->internal_flags, SSIF_BRIDGE_DISALLOWED_PILLARS_SET)) {
- // pillar flags set by NewGRF
- disallowed_pillar_flags = (BridgePiecePillarFlags) statspec->bridge_disallowed_pillars[layout];
+ if (statspec != nullptr && HasBit(statspec->internal_flags, SSIF_BRIDGE_DISALLOWED_PILLARS_SET)) {
+ /* Pillar flags set by NewGRF */
+ disallowed_pillar_flags = (BridgePiecePillarFlags) statspec->GetBridgeAboveFlags(layout).disallowed_pillars;
} else if (!statspec) {
- // default stations/waypoints
- static const uint8_t st_flags[8] = { 0x50, 0xA0, 0x50, 0xA0, 0x50 | 0x26, 0xA0 | 0x1C, 0x50 | 0x89, 0xA0 | 0x43 };
- disallowed_pillar_flags = (BridgePiecePillarFlags) st_flags[layout];
+ /* Default stations/waypoints */
+ if (layout < 8) {
+ static const uint8_t st_flags[8] = { 0x50, 0xA0, 0x50, 0xA0, 0x50 | 0x26, 0xA0 | 0x1C, 0x50 | 0x89, 0xA0 | 0x43 };
+ disallowed_pillar_flags = (BridgePiecePillarFlags) st_flags[layout];
+ } else {
+ disallowed_pillar_flags = (BridgePiecePillarFlags) 0;
+ }
} else if ((GetStationTileFlags(layout, statspec) & StationSpec::TileFlags::Blocked) == StationSpec::TileFlags::Blocked) {
- // non-track station tiles
+ /* Non-track station tiles */
disallowed_pillar_flags = (BridgePiecePillarFlags) 0;
} else {
- // tracked station tiles
+ /* Tracked station tiles */
const Axis axis = HasBit(layout, 0) ? AXIS_Y : AXIS_X;
disallowed_pillar_flags = (BridgePiecePillarFlags) (axis == AXIS_X ? 0x50 : 0xA0);
}