diff --git a/docs/newgrf-additions-nml.html b/docs/newgrf-additions-nml.html index 7f9dc5cd6d..9818ff6ba9 100644 --- a/docs/newgrf-additions-nml.html +++ b/docs/newgrf-additions-nml.html @@ -216,6 +216,17 @@ If there is no bridge above, the value is 0xFF. + adjacent_crossingbitmask(RAILTYPE_ADJACENT_CROSSING_XXX, ...) + + Adjacent level crossing information: +
+
SOUTH
+
This level crossing tile is part of a continuous adjacent crossing with the tile to the south (SW or SE)
+
NORTH
+
This level crossing tile is part of a continuous adjacent crossing with the tile to the north (NW or NE)
+
+ +

Roadtype properties

diff --git a/docs/newgrf-additions.html b/docs/newgrf-additions.html index b888fd6a6f..a58adc28ef 100644 --- a/docs/newgrf-additions.html +++ b/docs/newgrf-additions.html @@ -872,6 +872,16 @@

This is indicated by the feature name: varaction2_railtype_signal_vertical_clearance, version 1

+

Adjacent level crossing information (mappable variable: railtype_adjacent_crossing)

+

+ + + + +
BitMeaning
0This level crossing tile is part of a continuous adjacent crossing with the tile to the south (SW or SE)
1This level crossing tile is part of a continuous adjacent crossing with the tile to the north (NW or NE)
+ The value is 0 for non level crossing tiles. +

+

This is indicated by the feature name: varaction2_railtype_adjacent_crossing, version 1


Variational Action 2 - Objects

Tile slope after foundation applied (mappable variable: object_foundation_tile_slope)

diff --git a/src/newgrf_extension.cpp b/src/newgrf_extension.cpp index f8d9ba72c9..6c19e29487 100644 --- a/src/newgrf_extension.cpp +++ b/src/newgrf_extension.cpp @@ -44,6 +44,7 @@ extern const GRFFeatureInfo _grf_feature_list[] = { GRFFeatureInfo("varaction2_railtype_signal_context", 1), GRFFeatureInfo("varaction2_railtype_signal_side", 1), GRFFeatureInfo("varaction2_railtype_signal_vertical_clearance", 1), + GRFFeatureInfo("varaction2_railtype_adjacent_crossing", 1), GRFFeatureInfo("action0_global_extra_station_names", 2), GRFFeatureInfo("action0_global_default_object_generate_amount", 1), GRFFeatureInfo("action0_global_allow_rocks_in_desert", 1), @@ -175,6 +176,7 @@ extern const GRFVariableMapDefinition _grf_action2_remappable_variables[] = { GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_CONTEXT, "railtype_signal_context"), GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_SIDE, "railtype_signal_side"), GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_VERTICAL_CLEARANCE, "railtype_signal_vertical_clearance"), + GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_ADJACENT_CROSSING, "railtype_adjacent_crossing"), GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO, "signals_signal_restriction_info"), GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_CONTEXT, "signals_signal_context"), GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_STYLE, "signals_signal_style"), diff --git a/src/newgrf_extension.h b/src/newgrf_extension.h index 939beadd44..98016e23bf 100644 --- a/src/newgrf_extension.h +++ b/src/newgrf_extension.h @@ -86,6 +86,7 @@ enum Action2VariableRemapIds { A2VRI_RAILTYPE_SIGNAL_CONTEXT, A2VRI_RAILTYPE_SIGNAL_SIDE, A2VRI_RAILTYPE_SIGNAL_VERTICAL_CLEARANCE, + A2VRI_RAILTYPE_ADJACENT_CROSSING, A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO, A2VRI_SIGNALS_SIGNAL_CONTEXT, A2VRI_SIGNALS_SIGNAL_STYLE, diff --git a/src/newgrf_optimiser.cpp b/src/newgrf_optimiser.cpp index e9cfb4c525..59a9bb591a 100644 --- a/src/newgrf_optimiser.cpp +++ b/src/newgrf_optimiser.cpp @@ -108,6 +108,7 @@ static bool IsExpensiveRailtypeVariable(uint16 variable) { switch (variable) { case A2VRI_RAILTYPE_SIGNAL_VERTICAL_CLEARANCE: + case A2VRI_RAILTYPE_ADJACENT_CROSSING: return true; default: diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index e31bc2b181..c319e97b59 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -17,6 +17,7 @@ #include "depot_base.h" #include "town.h" #include "signal_func.h" +#include "road.h" #include "safeguards.h" @@ -39,6 +40,7 @@ case A2VRI_RAILTYPE_SIGNAL_CONTEXT: return this->signal_context; case A2VRI_RAILTYPE_SIGNAL_SIDE: return GetNewSignalsSideVariable(); case A2VRI_RAILTYPE_SIGNAL_VERTICAL_CLEARANCE: return 0xFF; + case A2VRI_RAILTYPE_ADJACENT_CROSSING: return 0; } } @@ -66,6 +68,31 @@ return GetNewSignalsSideVariable(); case A2VRI_RAILTYPE_SIGNAL_VERTICAL_CLEARANCE: return GetNewSignalsVerticalClearanceInfo(this->tile, this->z); + case A2VRI_RAILTYPE_ADJACENT_CROSSING: { + if (!IsLevelCrossingTile(this->tile) || !_settings_game.vehicle.adjacent_crossings) return 0; + + auto is_usable_crossing = [&](TileIndex t) -> bool { + if (HasRoadTypeRoad(t) && !HasBit(_roadtypes_non_train_colliding, GetRoadTypeRoad(t))) return true; + if (HasRoadTypeTram(t) && !HasBit(_roadtypes_non_train_colliding, GetRoadTypeTram(t))) return true; + return false; + }; + if (!is_usable_crossing(this->tile)) return 0; + + const Axis axis = GetCrossingRoadAxis(this->tile); + const DiagDirection dir_s = AxisToDiagDir(axis); + const DiagDirection dir_n = ReverseDiagDir(dir_s); + + uint32 result = 0; + auto test_dir = [&](DiagDirection dir, uint bit) { + const TileIndex t = TileAddByDiagDir(this->tile, dir); + if (t < MapSize() && IsLevelCrossingTile(t) && GetCrossingRoadAxis(t) == axis && is_usable_crossing(t)) { + SetBit(result, bit); + } + }; + test_dir(dir_s, 0); + test_dir(dir_n, 1); + return result; + } } DEBUG(grf, 1, "Unhandled rail type tile variable 0x%X", variable); diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index c5ecce0782..b63b2dd21c 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -1599,6 +1599,7 @@ static const NIVariable _niv_railtypes[] = { NIV(0x42, "level crossing status"), NIV(0x43, "construction date"), NIV(0x44, "town zone"), + NIV(A2VRI_RAILTYPE_ADJACENT_CROSSING, "adjacent crossing"), NIV_END() };