From bdd73a19a19936f785451c0268e636471a73a6e1 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sun, 19 Jun 2022 04:15:27 +0100 Subject: [PATCH] Add signal style flag for unconditional reserve through Add map bits for unconditional reserve through Adjust signal aspect/state handling --- docs/landscape.html | 2 ++ docs/landscape_grid.html | 2 +- docs/newgrf-additions-nml.html | 5 +++ docs/newgrf-additions.html | 7 ++++ src/newgrf.cpp | 9 ++++++ src/newgrf_extension.cpp | 1 + src/newgrf_extension.h | 1 + src/newgrf_newsignals.cpp | 16 ++++++---- src/newgrf_newsignals.h | 3 +- src/newgrf_railtype.cpp | 2 +- src/pbs.cpp | 2 +- src/rail_cmd.cpp | 4 +++ src/rail_map.h | 19 +++++++++++ src/saveload/afterload.cpp | 4 +++ src/saveload/extended_ver_sl.cpp | 2 +- src/signal.cpp | 55 ++++++++++++++++++++++++++++++++ src/signal_func.h | 4 +++ src/tracerestrict.cpp | 21 ++++++++++-- 18 files changed, 144 insertions(+), 15 deletions(-) diff --git a/docs/landscape.html b/docs/landscape.html index ea3d1fac33..fe8f37e70f 100644 --- a/docs/landscape.html +++ b/docs/landscape.html @@ -510,6 +510,8 @@
  • m4 bits 7..4: bit clear = signal 3..0 shows red
  • m6 bits 7..4: signal style for signal 0 and 1
  • m6 bits 3..0: signal style for signal 2 and 3
  • +
  • m7 bits 7: reserve through always set for signal 0 or 1
  • +
  • m7 bits 6: reserve through always set for signal 2 or 3
  • m7 bits 5..3: signal aspect for signal 0 or 1 (only valid if signal is present and not red, and multi-aspect signalling is in effect)
  • m7 bits 2..0: signal aspect for signal 2 or 3 (only valid if signal is present and not red, and multi-aspect signalling is in effect)
  • diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html index 8b7560e478..553a62b5af 100644 --- a/docs/landscape_grid.html +++ b/docs/landscape_grid.html @@ -114,7 +114,7 @@ the array so you can quickly see what is used and what is not. XXXX XXXX O1 XXXXXX PPPP PPPP - OO PPPPPP + PP PPPPPP depot diff --git a/docs/newgrf-additions-nml.html b/docs/newgrf-additions-nml.html index 3902597023..a4a220b5b8 100644 --- a/docs/newgrf-additions-nml.html +++ b/docs/newgrf-additions-nml.html @@ -466,6 +466,11 @@ item (FEAT_GLOBALVARS) { the signal aspect with respect to the signals either side (i.e. function like a banner repeater). + style_always_reserve_through0 or 1 + + Set whether reserve through is unconditionally enabled for the most recently defined style (defined using the define_style property). + + no_default_style0 or 1 When enabled, custom signal graphics from this GRF are only used for custom signal styles, not the default style diff --git a/docs/newgrf-additions.html b/docs/newgrf-additions.html index 7e1170ee47..d384b7bd3b 100644 --- a/docs/newgrf-additions.html +++ b/docs/newgrf-additions.html @@ -438,6 +438,13 @@ The Action 0 Id field is not used, the value is ignored.

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

    +

    Set custom signal style always reserve through mode (mappable property: signals_style_always_reserve_through)

    +

    This applies to the most recent custom signal style defined using the signals_define_style property.
    + When enabled, signals using this style have reserve through unconditionally enabled.

    +

    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. +

    +

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

    Set whether custom signal sprites should not be used for the default signal style (mappable property: signals_no_default_style)

    This applies to Action 2/3 Signals (Feature 0E) custom signal sprites for this GRF.
    When enabled, this GRF is not used for the default signal style, it is only used for custom signal styles defined with signals_define_style.

    diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 0a93687e0e..bfb0295efe 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -4234,6 +4234,15 @@ static ChangeInfoResult SignalsChangeInfo(uint id, int numinfo, int prop, const break; } + case A0RPI_SIGNALS_STYLE_ALWAYS_RESERVE_THROUGH: { + if (MappedPropertyLengthMismatch(buf, 1, mapping_entry)) break; + uint8 value = buf->ReadByte(); + if (_cur.grffile->current_new_signal_style != nullptr) { + SB(_cur.grffile->current_new_signal_style->style_flags, NSSF_ALWAYS_RESERVE_THROUGH, 1, (value != 0 ? 1 : 0)); + } + break; + } + default: ret = HandleAction0PropertyDefault(buf, prop); break; diff --git a/src/newgrf_extension.cpp b/src/newgrf_extension.cpp index 18e8dc2ac6..f0b456c919 100644 --- a/src/newgrf_extension.cpp +++ b/src/newgrf_extension.cpp @@ -95,6 +95,7 @@ extern const GRFPropertyMapDefinition _grf_action0_remappable_properties[] = { GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_DEFINE_STYLE, "signals_define_style"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_NAME, "signals_style_name"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_NO_ASPECT_INCREASE, "signals_style_no_aspect_increase"), + GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_ALWAYS_RESERVE_THROUGH, "signals_style_always_reserve_through"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_USE_LAND_GROUND, "object_use_land_ground"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_EDGE_FOUNDATION_MODE, "object_edge_foundation_mode"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_FLOOD_RESISTANT, "object_flood_resistant"), diff --git a/src/newgrf_extension.h b/src/newgrf_extension.h index b0d9632e61..5c79392d53 100644 --- a/src/newgrf_extension.h +++ b/src/newgrf_extension.h @@ -39,6 +39,7 @@ enum Action0RemapPropertyIds { A0RPI_SIGNALS_DEFINE_STYLE, A0RPI_SIGNALS_STYLE_NAME, A0RPI_SIGNALS_STYLE_NO_ASPECT_INCREASE, + A0RPI_SIGNALS_STYLE_ALWAYS_RESERVE_THROUGH, A0RPI_OBJECT_USE_LAND_GROUND, A0RPI_OBJECT_EDGE_FOUNDATION_MODE, A0RPI_OBJECT_FLOOD_RESISTANT, diff --git a/src/newgrf_newsignals.cpp b/src/newgrf_newsignals.cpp index 1b9bd4775b..dd37a112c5 100644 --- a/src/newgrf_newsignals.cpp +++ b/src/newgrf_newsignals.cpp @@ -46,7 +46,7 @@ static uint8 MapSignalStyle(uint8 style) switch (variable) { case 0x40: return GetTerrainType(this->tile, this->context); case A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO: - return GetNewSignalsRestrictedSignalsInfo(this->prog, this->tile); + return GetNewSignalsRestrictedSignalsInfo(this->prog, this->tile, this->signal_style); case A2VRI_SIGNALS_SIGNAL_CONTEXT: return GetNewSignalsSignalContext(this->signal_context, this->tile); case A2VRI_SIGNALS_SIGNAL_STYLE: return MapSignalStyle(this->signal_style); @@ -86,13 +86,15 @@ NewSignalsResolverObject::NewSignalsResolverObject(const GRFFile *grffile, TileI this->root_spritegroup = grffile != nullptr ? grffile->new_signals_group : nullptr; } -uint GetNewSignalsRestrictedSignalsInfo(const TraceRestrictProgram *prog, TileIndex tile) +uint GetNewSignalsRestrictedSignalsInfo(const TraceRestrictProgram *prog, TileIndex tile, uint8 signal_style) { - if (prog == nullptr) return 0; - - uint result = 1; - if ((prog->actions_used_flags & TRPAUF_RESERVE_THROUGH_ALWAYS) && !IsTileType(tile, MP_TUNNELBRIDGE)) result |= 2; - if ((prog->actions_used_flags & TRPAUF_REVERSE) && !IsTileType(tile, MP_TUNNELBRIDGE)) result |= 4; + uint result = 0; + if (signal_style != 0 && HasBit(_always_reserve_through_style_mask, signal_style)) result |= 2; + if (prog != nullptr) { + result |= 1; + if ((prog->actions_used_flags & TRPAUF_RESERVE_THROUGH_ALWAYS) && !IsTileType(tile, MP_TUNNELBRIDGE)) result |= 2; + if ((prog->actions_used_flags & TRPAUF_REVERSE) && !IsTileType(tile, MP_TUNNELBRIDGE)) result |= 4; + } return result; } diff --git a/src/newgrf_newsignals.h b/src/newgrf_newsignals.h index 14776e908b..992624c094 100644 --- a/src/newgrf_newsignals.h +++ b/src/newgrf_newsignals.h @@ -26,6 +26,7 @@ enum { enum NewSignalStyleFlags { NSSF_NO_ASPECT_INC = 0, + NSSF_ALWAYS_RESERVE_THROUGH = 1, }; struct NewSignalStyle { @@ -82,7 +83,7 @@ struct NewSignalsResolverObject : public ResolverObject { GrfSpecFeature GetFeature() const override; }; -uint GetNewSignalsRestrictedSignalsInfo(const TraceRestrictProgram *prog, TileIndex tile); +uint GetNewSignalsRestrictedSignalsInfo(const TraceRestrictProgram *prog, TileIndex tile, uint8 signal_style); inline uint GetNewSignalsSignalContext(CustomSignalSpriteContext signal_context, TileIndex tile) { diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 4e9775d6e6..8547918cee 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -55,7 +55,7 @@ return t != nullptr ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE; } case A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO: - return GetNewSignalsRestrictedSignalsInfo(this->prog, this->tile); + return GetNewSignalsRestrictedSignalsInfo(this->prog, this->tile, 0); case A2VRI_RAILTYPE_SIGNAL_CONTEXT: return GetNewSignalsSignalContext(this->signal_context, this->tile); } diff --git a/src/pbs.cpp b/src/pbs.cpp index b6e65828e3..29e87d1b8b 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -1259,10 +1259,10 @@ bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bo /* PBS signal on next trackdir? Conditionally safe position. */ if (HasPbsSignalOnTrackdir(ft.m_new_tile, td)) { if (GetSignalType(ft.m_new_tile, TrackdirToTrack(td)) == SIGTYPE_NO_ENTRY) return include_line_end; + if (GetSignalAlwaysReserveThrough(ft.m_new_tile, TrackdirToTrack(td))) return false; if (IsRestrictedSignal(ft.m_new_tile)) { const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(ft.m_new_tile, TrackdirToTrack(td)); if (prog && prog->actions_used_flags & TRPAUF_RESERVE_THROUGH) { - if (prog->actions_used_flags & TRPAUF_RESERVE_THROUGH_ALWAYS) return false; TraceRestrictProgramResult out; prog->Execute(v, TraceRestrictProgramInput(ft.m_new_tile, td, &VehiclePosTraceRestrictPreviousSignalCallback, nullptr), out); if (out.flags & TRPRF_RESERVE_THROUGH) { diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index e892339aa2..c82be6877d 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.cpp @@ -1720,6 +1720,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, SetSignalType(tile, track, sigtype); SetSignalVariant(tile, track, sigvar); SetSignalStyle(tile, track, signal_style); + UpdateSignalReserveThroughBit(tile, track, false); } /* Subtract old signal infrastructure count. */ @@ -1755,6 +1756,8 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, } if (sigtype == SIGTYPE_NO_ENTRY) CycleSignalSide(tile, track); + + UpdateSignalReserveThroughBit(tile, track, false); } } else if (ctrl_pressed) { @@ -1794,6 +1797,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, FreeSignalProgram(SignalReference(tile, track)); SetSignalType(tile, track, sigtype); SetSignalStyle(tile, track, signal_style); + UpdateSignalReserveThroughBit(tile, track, false); } /* Add new signal infrastructure count. */ diff --git a/src/rail_map.h b/src/rail_map.h index b298f8f1bc..97db9f6f33 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -397,6 +397,11 @@ static inline void SetSignalAspect(TileIndex t, Track track, uint8 aspect) SB(_me[t].m7, pos, 3, aspect); } +static inline bool NonZeroSignalStylePossiblyOnTile(TileIndex t) +{ + return _me[t].m6 != 0; +} + static inline uint8 GetSignalStyle(TileIndex t, Track track) { assert_tile(GetRailTileType(t) == RAIL_TILE_SIGNALS, t); @@ -411,6 +416,20 @@ static inline void SetSignalStyle(TileIndex t, Track track, uint8 style) SB(_me[t].m6, pos, 4, style); } +static inline bool GetSignalAlwaysReserveThrough(TileIndex t, Track track) +{ + assert_tile(GetRailTileType(t) == RAIL_TILE_SIGNALS, t); + byte pos = (track == TRACK_LOWER || track == TRACK_RIGHT) ? 7 : 6; + return HasBit(_me[t].m7, pos); +} + +static inline void SetSignalAlwaysReserveThrough(TileIndex t, Track track, bool reserve_through) +{ + assert_tile(GetRailTileType(t) == RAIL_TILE_SIGNALS, t); + byte pos = (track == TRACK_LOWER || track == TRACK_RIGHT) ? 7 : 6; + SB(_me[t].m7, pos, 1, reserve_through ? 1 : 0); +} + /** * Set the states of the signals (Along/AgainstTrackDir) * @param tile the tile to set the states for diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 1a2ca35cb9..20d6dba6a6 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -4078,6 +4078,10 @@ bool AfterLoadGame() } } + if (SlXvIsFeatureMissing(XSLFI_REALISTIC_TRAIN_BRAKING, 8)) { + _aspect_cfg_hash = 0; + } + InitializeRoadGUI(); /* This needs to be done after conversion. */ diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index fa77378927..b08fe809a8 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -151,7 +151,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_ANIMATED_TILE_EXTRA, XSCF_NULL, 1, 1, "animated_tile_extra", nullptr, nullptr, nullptr }, { XSLFI_NEWGRF_INFO_EXTRA, XSCF_NULL, 1, 1, "newgrf_info_extra", nullptr, nullptr, nullptr }, { XSLFI_INDUSTRY_CARGO_ADJ, XSCF_IGNORABLE_UNKNOWN, 1, 1, "industry_cargo_adj", nullptr, nullptr, nullptr }, - { XSLFI_REALISTIC_TRAIN_BRAKING,XSCF_NULL, 7, 7, "realistic_train_braking", nullptr, nullptr, "VLKA" }, + { XSLFI_REALISTIC_TRAIN_BRAKING,XSCF_NULL, 8, 8, "realistic_train_braking", nullptr, nullptr, "VLKA" }, { XSLFI_INFLATION_FIXED_DATES, XSCF_IGNORABLE_ALL, 1, 1, "inflation_fixed_dates", nullptr, nullptr, nullptr }, { XSLFI_WATER_FLOODING, XSCF_NULL, 2, 2, "water_flooding", nullptr, nullptr, nullptr }, { XSLFI_MORE_HOUSES, XSCF_NULL, 2, 2, "more_houses", nullptr, nullptr, nullptr }, diff --git a/src/signal.cpp b/src/signal.cpp index 1db24fd75e..1a38add2e9 100644 --- a/src/signal.cpp +++ b/src/signal.cpp @@ -31,6 +31,7 @@ uint8 _extra_aspects = 0; uint64 _aspect_cfg_hash = 0; uint16 _non_aspect_inc_style_mask = 0; +uint16 _always_reserve_through_style_mask = 0; uint16 _no_tunnel_bridge_style_mask = 0; bool _signal_sprite_oversized = false; @@ -382,6 +383,10 @@ static SigInfo ExploreSegment(Owner owner) if (_extra_aspects > 0) { info.out_signal_tile = tile; info.out_signal_trackdir = trackdir; + if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && GetSignalAlwaysReserveThrough(tile, track) && + GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_RED) { + info.flags |= SF_PBS; + } } /* if it is a presignal EXIT in OUR direction, count it */ @@ -856,6 +861,10 @@ static void UpdateSignalsAroundSegment(SigInfo info) // Progsig dependencies MarkDependencidesForUpdate(SignalReference(tile, track)); + } else if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC && GetSignalAlwaysReserveThrough(tile, track)) { + /* for reserve through signals, add block to the global set */ + DiagDirection exitdir = TrackdirToExitdir(ReverseTrackdir(trackdir)); + _globset.Add(tile, exitdir); // do not check for full global set, first update all signals } SetSignalStateByTrackdir(tile, trackdir, newstate); refresh = true; @@ -1503,6 +1512,7 @@ static bool DetermineExtraAspectsVariable() _non_aspect_inc_style_mask = 0; _no_tunnel_bridge_style_mask = 0; + _always_reserve_through_style_mask = 0; if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) { for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { @@ -1517,6 +1527,10 @@ static bool DetermineExtraAspectsVariable() SetBit(_non_aspect_inc_style_mask, i + 1); SetBit(_no_tunnel_bridge_style_mask, i + 1); } + if (HasBit(_new_signal_styles[i].style_flags, NSSF_ALWAYS_RESERVE_THROUGH)) { + SetBit(_always_reserve_through_style_mask, i + 1); + SetBit(_no_tunnel_bridge_style_mask, i + 1); + } } } @@ -1525,6 +1539,7 @@ static bool DetermineExtraAspectsVariable() SimpleChecksum64 checksum; checksum.Update(SimpleHash32(_extra_aspects)); checksum.Update(SimpleHash32(_non_aspect_inc_style_mask)); + checksum.Update(SimpleHash32(_always_reserve_through_style_mask)); if (checksum.state != _aspect_cfg_hash) { _aspect_cfg_hash = checksum.state; @@ -1539,7 +1554,9 @@ void UpdateExtraAspectsVariable() bool changed = DetermineExtraAspectsVariable(); if (changed) { + UpdateAllSignalReserveThroughBits(); if (_extra_aspects > 0) UpdateAllSignalAspects(); + UpdateAllBlockSignals(); MarkWholeScreenDirty(); } } @@ -1548,3 +1565,41 @@ void InitialiseExtraAspectsVariable() { DetermineExtraAspectsVariable(); } + +void UpdateSignalReserveThroughBit(TileIndex tile, Track track, bool update_signal) +{ + bool reserve_through = false; + if (NonZeroSignalStylePossiblyOnTile(tile) && _always_reserve_through_style_mask != 0 && + HasBit(_always_reserve_through_style_mask, GetSignalStyle(tile, track))) { + reserve_through = true; + } else { + if (IsRestrictedSignal(tile)) { + const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(tile, track); + if (prog && prog->actions_used_flags & TRPAUF_RESERVE_THROUGH_ALWAYS) reserve_through = true; + } + } + + if (reserve_through != GetSignalAlwaysReserveThrough(tile, track)) { + SetSignalAlwaysReserveThrough(tile, track, reserve_through); + if (update_signal && _settings_game.vehicle.train_braking_model == TBM_REALISTIC) { + AddTrackToSignalBuffer(tile, track, GetTileOwner(tile)); + UpdateSignalsInBuffer(); + } + } +} + +void UpdateAllSignalReserveThroughBits() +{ + TileIndex tile = 0; + do { + if (IsTileType(tile, MP_RAILWAY) && HasSignals(tile)) { + TrackBits bits = GetTrackBits(tile); + do { + Track track = RemoveFirstTrack(&bits); + if (HasSignalOnTrack(tile, track)) { + UpdateSignalReserveThroughBit(tile, track, false); + } + } while (bits != TRACK_BIT_NONE); + } + } while (++tile != MapSize()); +} diff --git a/src/signal_func.h b/src/signal_func.h index 0021179654..9e3ea80972 100644 --- a/src/signal_func.h +++ b/src/signal_func.h @@ -22,6 +22,7 @@ extern uint8 _extra_aspects; extern uint64 _aspect_cfg_hash; extern uint16 _non_aspect_inc_style_mask; +extern uint16 _always_reserve_through_style_mask; extern uint16 _no_tunnel_bridge_style_mask; extern bool _signal_sprite_oversized; @@ -192,4 +193,7 @@ inline uint8 GetForwardAspectFollowingTrackAndIncrement(TileIndex tile, Trackdir return std::min(GetForwardAspectFollowingTrack(tile, trackdir) + 1, _extra_aspects + 1); } +void UpdateSignalReserveThroughBit(TileIndex tile, Track track, bool update_signal); +void UpdateAllSignalReserveThroughBits(); + #endif /* SIGNAL_FUNC_H */ diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index 1c992e9ae7..cc29da52df 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -1313,6 +1313,8 @@ bool TraceRestrictRemoveProgramMapping(TraceRestrictRefId ref) // Found TraceRestrictProgram *prog = _tracerestrictprogram_pool.Get(iter->second.program_id); + bool update_reserve_through = (prog->actions_used_flags & TRPAUF_RESERVE_THROUGH_ALWAYS); + // check to see if another mapping needs to be removed as well // do this before decrementing the refcount bool remove_other_mapping = prog->refcount == 2 && prog->items.empty(); @@ -1329,14 +1331,25 @@ bool TraceRestrictRemoveProgramMapping(TraceRestrictRefId ref) if (remove_other_mapping) { TraceRestrictRemoveProgramMapping(const_cast(prog)->GetRefIdsPtr()[0]); } + + if (update_reserve_through) UpdateSignalReserveThroughBit(tile, track, true); return true; } else { return false; } } -void TraceRestrictCheckRefreshSignals(const TraceRestrictProgram *prog, TileIndex tile, size_t old_size, TraceRestrictProgramActionsUsedFlags old_actions_used_flags) +void TraceRestrictCheckRefreshSignals(const TraceRestrictProgram *prog, size_t old_size, TraceRestrictProgramActionsUsedFlags old_actions_used_flags) { + if (((old_actions_used_flags ^ prog->actions_used_flags) & TRPAUF_RESERVE_THROUGH_ALWAYS)) { + const TraceRestrictRefId *data = prog->GetRefIdsPtr(); + for (uint i = 0; i < prog->refcount; i++) { + TileIndex tile = GetTraceRestrictRefIdTileIndex(data[i]); + Track track = GetTraceRestrictRefIdTrack(data[i]); + if (IsTileType(tile, MP_RAILWAY)) UpdateSignalReserveThroughBit(tile, track, true); + } + } + if (_network_dedicated) return; if (!((old_actions_used_flags ^ prog->actions_used_flags) & (TRPAUF_RESERVE_THROUGH_ALWAYS | TRPAUF_REVERSE))) return; @@ -1740,7 +1753,7 @@ CommandCost CmdProgramSignalTraceRestrict(TileIndex tile, DoCommandFlag flags, u // so delete it, as it's redundant TraceRestrictRemoveProgramMapping(MakeTraceRestrictRefId(tile, track)); } else { - TraceRestrictCheckRefreshSignals(prog, tile, old_size, old_actions_used_flags); + TraceRestrictCheckRefreshSignals(prog, old_size, old_actions_used_flags); } // update windows @@ -1821,6 +1834,8 @@ CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag } prog->items = source_prog->items; // copy prog->Validate(); + + TraceRestrictCheckRefreshSignals(prog, 0, static_cast(0)); } break; } @@ -1841,7 +1856,7 @@ CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag 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); + TraceRestrictCheckRefreshSignals(prog, old_size, old_actions_used_flags); } break; }