diff --git a/docs/newgrf-additions-nml.html b/docs/newgrf-additions-nml.html index 2f0bbb0088..665b601cd3 100644 --- a/docs/newgrf-additions-nml.html +++ b/docs/newgrf-additions-nml.html @@ -103,6 +103,22 @@ +

Railtypes variables

+

Variables in the table below which are not supported by the version of OpenTTD being used return a value of 0.

+ + + + + +
VariableValue rangeComment
signal_restriction_infobitmask(SIGNAL_RESTRICTION_INFO_XXX, ...) + Information about the restricted signal status of the signal being drawn: +
+
RESTRICTED
+
The signal is restricted (has a routing restriction program attached)
+
RESERVE_THROUGH_ALWAYS
+
The attached routing restriction program unconditionally sets reserve through
+
+

Roadtype properties

@@ -400,6 +416,21 @@ item (FEAT_GLOBALVARS) {
PropertyValue rangeComment
+
+ + + + + +
VariableValue rangeComment
signal_restriction_infobitmask(SIGNAL_RESTRICTION_INFO_XXX, ...) + Information about the restricted signal status of the signal being drawn: +
+
RESTRICTED
+
The signal is restricted (has a routing restriction program attached)
+
RESERVE_THROUGH_ALWAYS
+
The attached routing restriction program unconditionally sets reserve through
+
+

Custom signal sprites example:

diff --git a/docs/newgrf-additions.html b/docs/newgrf-additions.html
index 40a8ea78dd..39c883e460 100644
--- a/docs/newgrf-additions.html
+++ b/docs/newgrf-additions.html
@@ -241,6 +241,7 @@
 	This flag should only be set if the Action 2/3 actually returns a different sprite when bit 24 of variable 18 is set.
The property length is 1 byte. 0 is disabled (default). 1 is enabled.

+

See also: railtype_signal_restriction_info variable

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

Enable recolouring for custom signal sprites (mappable property: railtype_enable_signal_recolour)

This applies to Action 2/3 - Railtype custom signal sprites.
@@ -358,6 +359,7 @@ The property length is 1 byte. 0 is disabled (default). 1 is enabled.
The Action 0 Id field is not used, the value is ignored.

+

See also: signals_signal_restriction_info variable

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

Enable recolouring for custom signal sprites (mappable property: signals_enable_signal_recolour)

This applies to Action 2/3 Signals (Feature 0E) custom signal sprites for this GRF.
@@ -547,6 +549,18 @@

Track type in purchase list (42)

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


+

Variational Action 2 - Railtypes

+

Signal routing restriction information (mappable variable: railtype_signal_restriction_info)

+

This applies to Action 2/3 - Railtype custom signal sprites.
+ + + + +
BitValueMeaning
01This signal has a routing restriction program attached
12Reserve through is unconditionally set in the routing restriction program
+

+

See also: railtype_enable_restricted_signals property

+

This is indicated by the feature name: action0_railtype_restricted_signals, version 2

+

Variational Action 2 - Objects

Tile slope after foundation applied (mappable variable: object_foundation_tile_slope)

This has the same format as bits 8-12 of object variable 41.

@@ -557,6 +571,18 @@ This is useful for xoring with bits 8-12 of variable 41, because if this variable is unavailable then the result is still the underlying tile slope.

This is indicated by the feature name: action0_object_edge_foundation_mode, version 2


+

Variational Action 2 - Signals (Feature 0E)

+

Signal routing restriction information (mappable variable: signals_signal_restriction_info)

+

This applies to Action 2/3 Signals (Feature 0E) custom signal sprites.
+ + + + +
BitValueMeaning
01This signal has a routing restriction program attached
12Reserve through is unconditionally set in the routing restriction program
+

+

See also: signals_enable_restricted_signals property

+

This is indicated by the feature name: action0_signals_restricted_signals, version 2

+

Action 3 - Signals (Feature 0E)

Note that Action 3 feature 0E is not supported (does nothing) in standard OpenTTD.

diff --git a/src/newgrf_extension.cpp b/src/newgrf_extension.cpp index c301506def..7608da281f 100644 --- a/src/newgrf_extension.cpp +++ b/src/newgrf_extension.cpp @@ -34,7 +34,7 @@ extern const GRFFeatureInfo _grf_feature_list[] = { GRFFeatureInfo("action5_road_waypoints", 1), GRFFeatureInfo("action0_railtype_programmable_signals", 1), GRFFeatureInfo("action0_railtype_no_entry_signals", 1), - GRFFeatureInfo("action0_railtype_restricted_signals", 1), + GRFFeatureInfo("action0_railtype_restricted_signals", 2), GRFFeatureInfo("action0_railtype_disable_realistic_braking", 1), GRFFeatureInfo("action0_railtype_recolour", 1), GRFFeatureInfo("action0_railtype_extra_aspects", 1), @@ -43,7 +43,7 @@ extern const GRFFeatureInfo _grf_feature_list[] = { GRFFeatureInfo("action0_global_default_object_generate_amount", 1), GRFFeatureInfo("action0_signals_programmable_signals", 1), GRFFeatureInfo("action0_signals_no_entry_signals", 1), - GRFFeatureInfo("action0_signals_restricted_signals", 1), + GRFFeatureInfo("action0_signals_restricted_signals", 2), GRFFeatureInfo("action0_signals_recolour", 1), GRFFeatureInfo("action0_signals_extra_aspects", 1), GRFFeatureInfo("action3_signals_custom_signal_sprites", 1), @@ -126,6 +126,8 @@ extern const GRFVariableMapDefinition _grf_action2_remappable_variables[] = { GRFVariableMapDefinition(GSF_ROADSTOPS, 0x67, "roadstop_land_info_nearby_tiles"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x68, "roadstop_road_stop_info_nearby_tiles"), GRFVariableMapDefinition(GSF_ROADSTOPS, 0x6A, "roadstop_road_stop_grfid_nearby_tiles"), + GRFVariableMapDefinition(GSF_RAILTYPES, A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO, "railtype_signal_restriction_info"), + GRFVariableMapDefinition(GSF_SIGNALS, A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO, "signals_signal_restriction_info"), GRFVariableMapDefinition(), }; diff --git a/src/newgrf_extension.h b/src/newgrf_extension.h index 6698fce4c2..2b282b3e83 100644 --- a/src/newgrf_extension.h +++ b/src/newgrf_extension.h @@ -61,6 +61,8 @@ enum Action2VariableRemapIds { A2VRI_OBJECT_FOUNDATION_SLOPE = 0x100, A2VRI_OBJECT_FOUNDATION_SLOPE_CHANGE, A2VRI_VEHICLE_CURRENT_SPEED_SCALED, + A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO, + A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO, }; /** Action14 feature definition */ diff --git a/src/newgrf_newsignals.cpp b/src/newgrf_newsignals.cpp index 1e2ec79d71..5532bc4c21 100644 --- a/src/newgrf_newsignals.cpp +++ b/src/newgrf_newsignals.cpp @@ -10,7 +10,9 @@ #include "stdafx.h" #include "debug.h" #include "newgrf_newsignals.h" +#include "newgrf_extension.h" #include "map_func.h" +#include "tracerestrict.h" #include "safeguards.h" @@ -27,11 +29,14 @@ std::vector _new_signals_grfs; if (this->tile == INVALID_TILE) { switch (variable) { case 0x40: return 0; + case A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO: return 0; } } switch (variable) { case 0x40: return GetTerrainType(this->tile, this->context); + case A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO: + return GetNewSignalsRestrictedSignalsInfo(this->prog, this->tile); } DEBUG(grf, 1, "Unhandled new signals tile variable 0x%X", variable); @@ -59,9 +64,19 @@ GrfSpecFeature NewSignalsResolverObject::GetFeature() const * @param context Are we resolving sprites for the upper halftile, or on a bridge? * @param param1 Extra parameter (first parameter of the callback, except railtypes do not have callbacks). * @param param2 Extra parameter (second parameter of the callback, except railtypes do not have callbacks). + * @param prog Routing restriction program. */ -NewSignalsResolverObject::NewSignalsResolverObject(const GRFFile *grffile, TileIndex tile, TileContext context, uint32 param1, uint32 param2) - : ResolverObject(grffile, CBID_NO_CALLBACK, param1, param2), newsignals_scope(*this, tile, context) +NewSignalsResolverObject::NewSignalsResolverObject(const GRFFile *grffile, TileIndex tile, TileContext context, uint32 param1, uint32 param2, const TraceRestrictProgram *prog) + : ResolverObject(grffile, CBID_NO_CALLBACK, param1, param2), newsignals_scope(*this, tile, context, prog) { this->root_spritegroup = grffile != nullptr ? grffile->new_signals_group : nullptr; } + +uint GetNewSignalsRestrictedSignalsInfo(const TraceRestrictProgram *prog, TileIndex tile) +{ + if (prog == nullptr) return 0; + + uint result = 1; + if ((prog->actions_used_flags & TRPAUF_RESERVE_THROUGH_ALWAYS) && !IsTileType(tile, MP_TUNNELBRIDGE)) result |= 2; + return result; +} diff --git a/src/newgrf_newsignals.h b/src/newgrf_newsignals.h index 85a1e20d9c..94807a38aa 100644 --- a/src/newgrf_newsignals.h +++ b/src/newgrf_newsignals.h @@ -15,10 +15,13 @@ extern std::vector _new_signals_grfs; +struct TraceRestrictProgram; + /** Resolver for the new signals scope. */ struct NewSignalsScopeResolver : public ScopeResolver { TileIndex tile; ///< Tracktile. For track on a bridge this is the southern bridgehead. TileContext context; ///< Are we resolving sprites for the upper halftile, or on a bridge? + const TraceRestrictProgram *prog; /** * Constructor of the railtype scope resolvers. @@ -26,8 +29,8 @@ struct NewSignalsScopeResolver : public ScopeResolver { * @param tile %Tile containing the track. For track on a bridge this is the southern bridgehead. * @param context Are we resolving sprites for the upper halftile, or on a bridge? */ - NewSignalsScopeResolver(ResolverObject &ro, TileIndex tile, TileContext context) - : ScopeResolver(ro), tile(tile), context(context) + NewSignalsScopeResolver(ResolverObject &ro, TileIndex tile, TileContext context, const TraceRestrictProgram *prog) + : ScopeResolver(ro), tile(tile), context(context), prog(prog) { } @@ -39,7 +42,7 @@ struct NewSignalsScopeResolver : public ScopeResolver { struct NewSignalsResolverObject : public ResolverObject { NewSignalsScopeResolver newsignals_scope; ///< Resolver for the new signals scope. - NewSignalsResolverObject(const GRFFile *grffile, TileIndex tile, TileContext context, uint32 param1 = 0, uint32 param2 = 0); + NewSignalsResolverObject(const GRFFile *grffile, TileIndex tile, TileContext context, uint32 param1 = 0, uint32 param2 = 0, const TraceRestrictProgram *prog = nullptr); ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { @@ -54,4 +57,6 @@ struct NewSignalsResolverObject : public ResolverObject { GrfSpecFeature GetFeature() const override; }; +uint GetNewSignalsRestrictedSignalsInfo(const TraceRestrictProgram *prog, TileIndex tile); + #endif /* NEWGRF_RAILTYPE_H */ diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 7173a49f66..3c37a3a37e 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -11,6 +11,7 @@ #include "debug.h" #include "newgrf_railtype.h" #include "newgrf_newsignals.h" +#include "newgrf_extension.h" #include "date_func.h" #include "depot_base.h" #include "town.h" @@ -32,6 +33,7 @@ case 0x42: return 0; case 0x43: return _date; case 0x44: return HZB_TOWN_EDGE; + case A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO: return 0; } } @@ -51,6 +53,8 @@ } return t != nullptr ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE; } + case A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO: + return GetNewSignalsRestrictedSignalsInfo(this->prog, this->tile); } DEBUG(grf, 1, "Unhandled rail type tile variable 0x%X", variable); @@ -77,9 +81,10 @@ uint32 RailTypeResolverObject::GetDebugID() const * @param rtsg Railpart of interest * @param param1 Extra parameter (first parameter of the callback, except railtypes do not have callbacks). * @param param2 Extra parameter (second parameter of the callback, except railtypes do not have callbacks). + * @param prog Routing restriction program. */ -RailTypeResolverObject::RailTypeResolverObject(const RailtypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32 param1, uint32 param2) - : ResolverObject(rti != nullptr ? rti->grffile[rtsg] : nullptr, CBID_NO_CALLBACK, param1, param2), railtype_scope(*this, rti, tile, context) +RailTypeResolverObject::RailTypeResolverObject(const RailtypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32 param1, uint32 param2, const TraceRestrictProgram *prog) + : ResolverObject(rti != nullptr ? rti->grffile[rtsg] : nullptr, CBID_NO_CALLBACK, param1, param2), railtype_scope(*this, rti, tile, context, prog) { this->root_spritegroup = rti != nullptr ? rti->group[rtsg] : nullptr; } @@ -116,7 +121,7 @@ inline uint8 RemapAspect(uint8 aspect, uint8 extra_aspects) return aspect + 1; } -static PalSpriteID GetRailTypeCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, uint8 aspect, bool gui, bool restricted) +static PalSpriteID GetRailTypeCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, uint8 aspect, bool gui, const TraceRestrictProgram *prog) { if (rti->group[RTSG_SIGNALS] == nullptr) return { 0, PAL_NONE }; if (type == SIGTYPE_PROG && !HasBit(rti->ctrl_flags, RTCF_PROGSIG)) return { 0, PAL_NONE }; @@ -124,8 +129,8 @@ static PalSpriteID GetRailTypeCustomSignalSprite(const RailtypeInfo *rti, TileIn uint32 param1 = gui ? 0x10 : 0x00; uint32 param2 = (type << 16) | (var << 8) | RemapAspect(aspect, rti->signal_extra_aspects); - if (restricted && HasBit(rti->ctrl_flags, RTCF_RESTRICTEDSIG)) SetBit(param2, 24); - RailTypeResolverObject object(rti, tile, TCX_NORMAL, RTSG_SIGNALS, param1, param2); + if ((prog != nullptr) && HasBit(rti->ctrl_flags, RTCF_RESTRICTEDSIG)) SetBit(param2, 24); + RailTypeResolverObject object(rti, tile, TCX_NORMAL, RTSG_SIGNALS, param1, param2, prog); const SpriteGroup *group = object.Resolve(); if (group == nullptr || group->GetNumResults() == 0) return { 0, PAL_NONE }; @@ -144,11 +149,11 @@ static PalSpriteID GetRailTypeCustomSignalSprite(const RailtypeInfo *rti, TileIn * @param gui Is the sprite being used on the map or in the GUI? * @return The sprite to draw. */ -CustomSignalSpriteResult GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, uint8 aspect, bool gui, bool restricted) +CustomSignalSpriteResult GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, uint8 aspect, bool gui, const TraceRestrictProgram *prog) { if (_settings_client.gui.show_all_signal_default) return { { 0, PAL_NONE }, false }; - PalSpriteID spr = GetRailTypeCustomSignalSprite(rti, tile, type, var, aspect, gui, restricted); + PalSpriteID spr = GetRailTypeCustomSignalSprite(rti, tile, type, var, aspect, gui, prog); if (spr.sprite != 0) return { spr, HasBit(rti->ctrl_flags, RTCF_RESTRICTEDSIG) }; for (const GRFFile *grf : _new_signals_grfs) { @@ -157,8 +162,8 @@ CustomSignalSpriteResult GetCustomSignalSprite(const RailtypeInfo *rti, TileInde uint32 param1 = gui ? 0x10 : 0x00; uint32 param2 = (type << 16) | (var << 8) | RemapAspect(aspect, grf->new_signal_extra_aspects); - if (restricted && HasBit(grf->new_signal_ctrl_flags, NSCF_RESTRICTEDSIG)) SetBit(param2, 24); - NewSignalsResolverObject object(grf, tile, TCX_NORMAL, param1, param2); + if ((prog != nullptr) && HasBit(grf->new_signal_ctrl_flags, NSCF_RESTRICTEDSIG)) SetBit(param2, 24); + NewSignalsResolverObject object(grf, tile, TCX_NORMAL, param1, param2, prog); const SpriteGroup *group = object.Resolve(); if (group != nullptr && group->GetNumResults() != 0) { diff --git a/src/newgrf_railtype.h b/src/newgrf_railtype.h index 39818790c7..470c27355e 100644 --- a/src/newgrf_railtype.h +++ b/src/newgrf_railtype.h @@ -14,11 +14,14 @@ #include "newgrf_commons.h" #include "newgrf_spritegroup.h" +struct TraceRestrictProgram; + /** Resolver for the railtype scope. */ struct RailTypeScopeResolver : public ScopeResolver { TileIndex tile; ///< Tracktile. For track on a bridge this is the southern bridgehead. TileContext context; ///< Are we resolving sprites for the upper halftile, or on a bridge? const RailtypeInfo *rti; + const TraceRestrictProgram *prog; /** * Constructor of the railtype scope resolvers. @@ -26,8 +29,8 @@ struct RailTypeScopeResolver : public ScopeResolver { * @param tile %Tile containing the track. For track on a bridge this is the southern bridgehead. * @param context Are we resolving sprites for the upper halftile, or on a bridge? */ - RailTypeScopeResolver(ResolverObject &ro, const RailtypeInfo *rti, TileIndex tile, TileContext context) - : ScopeResolver(ro), tile(tile), context(context), rti(rti) + RailTypeScopeResolver(ResolverObject &ro, const RailtypeInfo *rti, TileIndex tile, TileContext context, const TraceRestrictProgram *prog) + : ScopeResolver(ro), tile(tile), context(context), rti(rti), prog(prog) { } @@ -39,7 +42,7 @@ struct RailTypeScopeResolver : public ScopeResolver { struct RailTypeResolverObject : public ResolverObject { RailTypeScopeResolver railtype_scope; ///< Resolver for the railtype scope. - RailTypeResolverObject(const RailtypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32 param1 = 0, uint32 param2 = 0); + RailTypeResolverObject(const RailtypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32 param1 = 0, uint32 param2 = 0, const TraceRestrictProgram *prog = nullptr); ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { @@ -59,7 +62,7 @@ struct CustomSignalSpriteResult { }; SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context = TCX_NORMAL, uint *num_results = nullptr); -CustomSignalSpriteResult GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, uint8 aspect, bool gui = false, bool restricted = false); +CustomSignalSpriteResult GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, uint8 aspect, bool gui = false, const TraceRestrictProgram *prog = nullptr); RailType GetRailTypeTranslation(uint8 railtype, const GRFFile *grffile); uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile); diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 1db2c14e06..8cc6ed422c 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -2721,8 +2721,10 @@ static void GetSignalXY(TileIndex tile, uint pos, uint &x, uint &y) } void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, SignalState condition, SignalOffsets image, uint pos, SignalType type, - SignalVariant variant, bool show_restricted, bool exit_signal = false) + SignalVariant variant, const TraceRestrictProgram *prog, bool exit_signal = false) { + bool show_restricted = (prog != nullptr); + if (type == SIGTYPE_NO_ENTRY) pos ^= 1; uint x, y; @@ -2742,7 +2744,7 @@ void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, Sign aspect = 0; } - const CustomSignalSpriteResult result = GetCustomSignalSprite(rti, tile, type, variant, aspect, false, show_restricted); + const CustomSignalSpriteResult result = GetCustomSignalSprite(rti, tile, type, variant, aspect, false, prog); SpriteID sprite = result.sprite.sprite; PaletteID pal = PAL_NONE; bool is_custom_sprite = (sprite != 0); @@ -2822,8 +2824,8 @@ static void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track trac SignalType type = GetSignalType(tile, track); SignalVariant variant = GetSignalVariant(tile, track); - bool show_restricted = IsRestrictedSignal(tile) && (GetExistingTraceRestrictProgram(tile, track) != nullptr); - DrawSingleSignal(tile, rti, track, condition, image, pos, type, variant, show_restricted); + const TraceRestrictProgram *prog = IsRestrictedSignal(tile) ? GetExistingTraceRestrictProgram(tile, track) : nullptr; + DrawSingleSignal(tile, rti, track, condition, image, pos, type, variant, prog); } template diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index a0b8a04857..6654fe222c 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -1323,6 +1323,20 @@ bool TraceRestrictRemoveProgramMapping(TraceRestrictRefId ref) } } +void TraceRestrictCheckRefreshSignals(const TraceRestrictProgram *prog, TileIndex tile, size_t old_size, TraceRestrictProgramActionsUsedFlags old_actions_used_flags) +{ + if (_network_dedicated) return; + + if (!((old_actions_used_flags ^ prog->actions_used_flags) & TRPAUF_RESERVE_THROUGH_ALWAYS)) return; + + if (old_size == 0 && prog->refcount == 1) return; // Program is new, no need to refresh again + + const TraceRestrictRefId *data = prog->GetRefIdsPtr(); + for (uint i = 0; i < prog->refcount; i++) { + MarkTileDirtyByTile(GetTraceRestrictRefIdTileIndex(data[i]), VMDF_NOT_MAP_MODE); + } +} + /** * Gets the signal program for the tile ref @p ref * An empty program will be constructed if none exists, and @p create_new is true, unless the pool is full @@ -1687,6 +1701,9 @@ CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, u if (flags & DC_EXEC) { assert(prog); + size_t old_size = prog->items.size(); + TraceRestrictProgramActionsUsedFlags old_actions_used_flags = prog->actions_used_flags; + // move in modified program prog->items.swap(items); prog->actions_used_flags = actions_used_flags; @@ -1695,6 +1712,8 @@ CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, u // program is empty, and this tile is the only reference to it // so delete it, as it's redundant TraceRestrictRemoveProgramMapping(MakeTraceRestrictRefId(tile, track)); + } else { + TraceRestrictCheckRefreshSignals(prog, tile, old_size, old_actions_used_flags); } // update windows @@ -1788,9 +1807,14 @@ CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag return CMD_ERROR; } + size_t old_size = prog->items.size(); + TraceRestrictProgramActionsUsedFlags old_actions_used_flags = prog->actions_used_flags; + prog->items.reserve(prog->items.size() + source_prog->items.size()); // this is in case prog == source_prog prog->items.insert(prog->items.end(), source_prog->items.begin(), source_prog->items.end()); // append prog->Validate(); + + TraceRestrictCheckRefreshSignals(prog, tile, old_size, old_actions_used_flags); } break; } diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 413e4e9cb7..16b4de7b2b 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -1758,7 +1758,8 @@ static void DrawTunnelBridgeRampSingleSignal(const TileInfo *ti, bool is_green, } } bool show_restricted = IsTunnelBridgeRestrictedSignal(ti->tile); - const CustomSignalSpriteResult result = GetCustomSignalSprite(rti, ti->tile, type, variant, aspect, false, show_restricted); + const TraceRestrictProgram *prog = show_restricted ? GetExistingTraceRestrictProgram(ti->tile, FindFirstTrack(GetAcrossTunnelBridgeTrackBits(ti->tile))) : nullptr; + const CustomSignalSpriteResult result = GetCustomSignalSprite(rti, ti->tile, type, variant, aspect, false, prog); PalSpriteID sprite = result.sprite; bool is_custom_sprite = (sprite.sprite != 0); @@ -2142,7 +2143,7 @@ static void DrawTile_TunnelBridge(TileInfo *ti, DrawTileProcParams params) if (IsTunnelBridgeWithSignalSimulation(ti->tile)) { extern void DrawSingleSignal(TileIndex tile, const RailtypeInfo *rti, Track track, SignalState condition, - SignalOffsets image, uint pos, SignalType type, SignalVariant variant, bool show_restricted, bool exit_signal = false); + SignalOffsets image, uint pos, SignalType type, SignalVariant variant, const TraceRestrictProgram *prog, bool exit_signal = false); DiagDirection dir = GetTunnelBridgeDirection(ti->tile); SignalVariant variant = IsTunnelBridgeSemaphore(ti->tile) ? SIG_SEMAPHORE : SIG_ELECTRIC; @@ -2154,15 +2155,16 @@ static void DrawTile_TunnelBridge(TileInfo *ti, DrawTileProcParams params) position ^= 1; image = (SignalOffsets)(image ^ 1); } + const TraceRestrictProgram *prog = IsTunnelBridgeRestrictedSignal(ti->tile) ? GetExistingTraceRestrictProgram(ti->tile, t) : nullptr; if (IsTunnelBridgeSignalSimulationEntrance(ti->tile)) { - DrawSingleSignal(ti->tile, rti, t, GetTunnelBridgeEntranceSignalState(ti->tile), image, position, SIGTYPE_NORMAL, variant, IsTunnelBridgeRestrictedSignal(ti->tile), false); + DrawSingleSignal(ti->tile, rti, t, GetTunnelBridgeEntranceSignalState(ti->tile), image, position, SIGTYPE_NORMAL, variant, prog, false); } if (IsTunnelBridgeSignalSimulationExit(ti->tile)) { SignalType type = SIGTYPE_NORMAL; if (IsTunnelBridgePBS(ti->tile)) { type = IsTunnelBridgeSignalSimulationEntrance(ti->tile) ? SIGTYPE_PBS : SIGTYPE_PBS_ONEWAY; } - DrawSingleSignal(ti->tile, rti, t, GetTunnelBridgeExitSignalState(ti->tile), (SignalOffsets)(image ^ 1), position ^ 1, type, variant, IsTunnelBridgeRestrictedSignal(ti->tile), true); + DrawSingleSignal(ti->tile, rti, t, GetTunnelBridgeExitSignalState(ti->tile), (SignalOffsets)(image ^ 1), position ^ 1, type, variant, prog, true); } }; switch (t) {