From ba52fbeb91076280206f0d38553877880cc7568c Mon Sep 17 00:00:00 2001
From: Jonathan G Rennison
Date: Sun, 12 Jun 2022 09:00:31 +0100
Subject: [PATCH] Signals: Add variable for restriction info, add bit for
reserve through
---
docs/newgrf-additions-nml.html | 31 +++++++++++++++++++++++++++++++
docs/newgrf-additions.html | 26 ++++++++++++++++++++++++++
src/newgrf_extension.cpp | 6 ++++--
src/newgrf_extension.h | 2 ++
src/newgrf_newsignals.cpp | 19 +++++++++++++++++--
src/newgrf_newsignals.h | 11 ++++++++---
src/newgrf_railtype.cpp | 23 ++++++++++++++---------
src/newgrf_railtype.h | 11 +++++++----
src/rail_cmd.cpp | 10 ++++++----
src/tracerestrict.cpp | 24 ++++++++++++++++++++++++
src/tunnelbridge_cmd.cpp | 10 ++++++----
11 files changed, 145 insertions(+), 28 deletions(-)
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 @@
+
+ Variables in the table below which are not supported by the version of OpenTTD being used return a value of 0.
+
+ Variable | Value range | Comment |
+ signal_restriction_info | bitmask(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
+
+ |
+
+
Property | Value range | Comment |
@@ -400,6 +416,21 @@ item (FEAT_GLOBALVARS) {
+
+
+ Variable | Value range | Comment |
+ signal_restriction_info | bitmask(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
+
+ Signal routing restriction information (mappable variable: railtype_signal_restriction_info)
+ This applies to Action 2/3 - Railtype custom signal sprites.
+
+ Bit | Value | Meaning |
+ 0 | 1 | This signal has a routing restriction program attached |
+ 1 | 2 | Reserve 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
+
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
+
+ Signal routing restriction information (mappable variable: signals_signal_restriction_info)
+ This applies to Action 2/3 Signals (Feature 0E) custom signal sprites.
+
+ Bit | Value | Meaning |
+ 0 | 1 | This signal has a routing restriction program attached |
+ 1 | 2 | Reserve 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
+
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) {