From 6d6e64b1f0b0aa9df0e8c74725c93829e428eb20 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 14 Aug 2025 19:35:32 +0100 Subject: [PATCH] Add: [NewGRF] Bridge pillar exclusion information for stations and roadstops. NewGRF stations and roadstops can now specify bridge pillar and minimum height information for their tiles. --- src/bridge_type.h | 6 ++++++ src/newgrf/newgrf_act0_roadstops.cpp | 31 ++++++++++++++++++++++++++++ src/newgrf/newgrf_act0_stations.cpp | 18 ++++++++++++++++ src/newgrf_roadstop.h | 5 ++--- src/newgrf_station.h | 2 ++ 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/bridge_type.h b/src/bridge_type.h index a01ec835dc..82b42b51d1 100644 --- a/src/bridge_type.h +++ b/src/bridge_type.h @@ -55,4 +55,10 @@ static constexpr BridgePillarFlags BRIDGEPILLARFLAGS_ALL{ BridgePillarFlag::EdgeNE, BridgePillarFlag::EdgeSE, BridgePillarFlag::EdgeSW, BridgePillarFlag::EdgeNW, }; +/** Information about a tile structure that may have a bridge above. */ +struct BridgeableTileInfo { + uint8_t height = 0; ///< Minimum height for a bridge above. 0 means a bridge is not allowed. + BridgePillarFlags disallowed_pillars = BRIDGEPILLARFLAGS_ALL; ///< Disallowed pillar flags for a bridge above +}; + #endif /* BRIDGE_TYPE_H */ diff --git a/src/newgrf/newgrf_act0_roadstops.cpp b/src/newgrf/newgrf_act0_roadstops.cpp index 0fc897b565..f260b48289 100644 --- a/src/newgrf/newgrf_act0_roadstops.cpp +++ b/src/newgrf/newgrf_act0_roadstops.cpp @@ -49,6 +49,13 @@ static ChangeInfoResult IgnoreRoadStopProperty(uint prop, ByteReader &buf) buf.ReadDWord(); break; + case 0x13: + case 0x14: + buf.ReadWord(); + buf.ReadWord(); + buf.ReadWord(); + break; + case 0x16: // Badge list SkipBadgeList(buf); break; @@ -134,6 +141,30 @@ static ChangeInfoResult RoadStopChangeInfo(uint first, uint last, int prop, Byte rs->flags = static_cast(buf.ReadDWord()); // Future-proofing, size this as 4 bytes, but we only need two byte's worth of flags at present break; + case 0x13: { // Minimum bridge height for each of the roadstop's tile layouts. + uint16_t tiles = buf.ReadExtendedByte(); + for (uint j = 0; j != tiles; ++j) { + if (j < std::size(rs->bridgeable_info)) { + rs->bridgeable_info[j].height = buf.ReadByte(); + } else { + buf.ReadByte(); + } + } + break; + } + + case 0x14: { // Disallowed pillars for each of the roadstop's tile layouts. + uint16_t tiles = buf.ReadExtendedByte(); + for (uint j = 0; j != tiles; ++j) { + if (j < std::size(rs->bridgeable_info)) { + rs->bridgeable_info[j].disallowed_pillars = BridgePillarFlags{buf.ReadByte()}; + } else { + buf.ReadByte(); + } + } + break; + } + case 0x15: // Cost multipliers rs->build_cost_multiplier = buf.ReadByte(); rs->clear_cost_multiplier = buf.ReadByte(); diff --git a/src/newgrf/newgrf_act0_stations.cpp b/src/newgrf/newgrf_act0_stations.cpp index d5336665ea..b6e8f4c5d9 100644 --- a/src/newgrf/newgrf_act0_stations.cpp +++ b/src/newgrf/newgrf_act0_stations.cpp @@ -294,6 +294,24 @@ static ChangeInfoResult StationChangeInfo(uint first, uint last, int prop, ByteR statspec->badges = ReadBadgeList(buf, GSF_STATIONS); break; + case 0x20: { // Minimum bridge height (extended) + uint16_t tiles = buf.ReadExtendedByte(); + if (statspec->bridgeable_info.size() < tiles) statspec->bridgeable_info.resize(tiles); + for (int j = 0; j != tiles; ++j) { + statspec->bridgeable_info[j].height = buf.ReadByte(); + } + break; + } + + case 0x21: { // Disallowed bridge pillars + uint16_t tiles = buf.ReadExtendedByte(); + if (statspec->bridgeable_info.size() < tiles) statspec->bridgeable_info.resize(tiles); + for (int j = 0; j != tiles; ++j) { + statspec->bridgeable_info[j].disallowed_pillars = BridgePillarFlags{buf.ReadByte()}; + } + break; + } + default: ret = CIR_UNKNOWN; break; diff --git a/src/newgrf_roadstop.h b/src/newgrf_roadstop.h index 731772b2e9..3f826aac43 100644 --- a/src/newgrf_roadstop.h +++ b/src/newgrf_roadstop.h @@ -12,6 +12,7 @@ #ifndef NEWGRF_ROADSTATION_H #define NEWGRF_ROADSTATION_H +#include "bridge_type.h" #include "newgrf_animation_type.h" #include "newgrf_spritegroup.h" #include "newgrf_badge_type.h" @@ -138,12 +139,10 @@ struct RoadStopSpec : NewGRFSpecBase { AnimationInfo animation; - uint8_t bridge_height[6]; ///< Minimum height for a bridge above, 0 for none - uint8_t bridge_disallowed_pillars[6]; ///< Disallowed pillar flags for a bridge above - uint8_t build_cost_multiplier = 16; ///< Build cost multiplier per tile. uint8_t clear_cost_multiplier = 16; ///< Clear cost multiplier per tile. + std::array bridgeable_info{}; ///< Per tile layout bridge information. std::vector badges; /** diff --git a/src/newgrf_station.h b/src/newgrf_station.h index cf8e210c72..2537209fd8 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.h @@ -11,6 +11,7 @@ #define NEWGRF_STATION_H #include "core/enum_type.hpp" +#include "bridge_type.h" #include "newgrf_animation_type.h" #include "newgrf_badge_type.h" #include "newgrf_callbacks.h" @@ -169,6 +170,7 @@ struct StationSpec : NewGRFSpecBase { }; using TileFlags = EnumBitSet; std::vector tileflags; ///< List of tile flags. + std::vector bridgeable_info; ///< Per tile layout bridge information. AnimationInfo animation;