diff --git a/docs/newgrf-additions-nml.html b/docs/newgrf-additions-nml.html index 8853be091f..30587cd468 100644 --- a/docs/newgrf-additions-nml.html +++ b/docs/newgrf-additions-nml.html @@ -508,10 +508,21 @@ item (FEAT_GLOBALVARS) { Set the look-ahead extra aspects for the most recently defined style (defined using the define_style property).
This property only makes a difference when the "limit train lookahead to signal aspect" game setting is enabled.
This limits the signal aspect which the hypothetical train driver can "read" from the signal without affecting signal aspect propagation to other signals, or variable extra_callback_info2.
- Example values could include: 1 for traditional banner repeater signals, or 0 for shunt signals.
+ Example values could include: 1 for traditional banner repeater signals.
+ Shunt signals should use style_lookahead_single_signal_only instead.
The value is clamped to be less than or equal to the value set in the extra_aspects property. + style_lookahead_single_signal_only0 or 1 + + Set the look-ahead to single signal only mode for the most recently defined style (defined using the define_style property).
+ This property only makes a difference when the "limit train lookahead to signal aspect" game setting is enabled.
+ This is similar to style_lookahead_extra_aspects with a value of 0, except the lookahead always ends at the + next signal, even if that signal type sets style_no_aspect_increase.
+ If enabled, this property overrides style_lookahead_extra_aspects.
+ This can be used for shunt signals. + + style_opposite_side0 or 1 Set whether signals should be drawn on the opposite side of the track for the most recently defined style (defined using the define_style property). diff --git a/docs/newgrf-additions.html b/docs/newgrf-additions.html index 5ccd66cd32..f83c473d63 100644 --- a/docs/newgrf-additions.html +++ b/docs/newgrf-additions.html @@ -475,11 +475,23 @@

This applies to the most recent custom signal style defined using the signals_define_style property.
This property only makes a difference when the "limit train lookahead to signal aspect" game setting is enabled.
This limits the signal aspect which the hypothetical train driver can "read" from the signal without affecting signal aspect propagation to other signals, or variable 0x18.
- Example values could include: 1 for traditional banner repeater signals, or 0 for shunt signals.

+ Example values could include: 1 for traditional banner repeater signals.
+ Shunt signals should use signals_style_lookahead_single_signal_only instead.

The property length is 1 byte. The value is clamped to be less than or equal to the value set in the signals_extra_aspects property.
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 train look-ahead to single signal only mode (mappable property: signals_style_lookahead_single_signal_only)

+

This applies to the most recent custom signal style defined using the signals_define_style property.
+ This property only makes a difference when the "limit train lookahead to signal aspect" game setting is enabled.
+ This is similar to signals_style_lookahead_extra_aspects with a value of 0, except the lookahead always ends at the + next signal, even if that signal type sets signals_style_no_aspect_increase.
+ If enabled, this property overrides signals_style_lookahead_extra_aspects.
+ This can be used for shunt signals.

+

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 custom signal style signal drawn on opposite side (mappable property: signals_style_opposite_side)

This applies to the most recent custom signal style defined using the signals_define_style property.
When enabled, signals using this style are drawn on the opposite side of the track.

diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 799af476f8..a8bc7a5ddc 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -4253,6 +4253,15 @@ static ChangeInfoResult SignalsChangeInfo(uint id, int numinfo, int prop, const break; } + case A0RPI_SIGNALS_STYLE_LOOKAHEAD_SINGLE_SIGNAL_ONLY: { + 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_LOOKAHEAD_SINGLE_SIGNAL, 1, (value != 0 ? 1 : 0)); + } + break; + } + case A0RPI_SIGNALS_STYLE_SEMAPHORE_ENABLED: { if (MappedPropertyLengthMismatch(buf, 4, mapping_entry)) break; uint32 mask = buf->ReadDWord(); diff --git a/src/newgrf_extension.cpp b/src/newgrf_extension.cpp index 6733165d1a..f8e807f199 100644 --- a/src/newgrf_extension.cpp +++ b/src/newgrf_extension.cpp @@ -97,6 +97,7 @@ extern const GRFPropertyMapDefinition _grf_action0_remappable_properties[] = { 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_SIGNALS, A0RPI_SIGNALS_STYLE_LOOKAHEAD_EXTRA_ASPECTS, "signals_style_lookahead_extra_aspects"), + GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_LOOKAHEAD_SINGLE_SIGNAL_ONLY, "signals_style_lookahead_single_signal_only"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_SEMAPHORE_ENABLED, "signals_style_semaphore_enabled"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_ELECTRIC_ENABLED, "signals_style_electric_enabled"), GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_OPPOSITE_SIDE, "signals_style_opposite_side"), diff --git a/src/newgrf_extension.h b/src/newgrf_extension.h index f504352708..19448d4f17 100644 --- a/src/newgrf_extension.h +++ b/src/newgrf_extension.h @@ -41,6 +41,7 @@ enum Action0RemapPropertyIds { A0RPI_SIGNALS_STYLE_NO_ASPECT_INCREASE, A0RPI_SIGNALS_STYLE_ALWAYS_RESERVE_THROUGH, A0RPI_SIGNALS_STYLE_LOOKAHEAD_EXTRA_ASPECTS, + A0RPI_SIGNALS_STYLE_LOOKAHEAD_SINGLE_SIGNAL_ONLY, A0RPI_SIGNALS_STYLE_SEMAPHORE_ENABLED, A0RPI_SIGNALS_STYLE_ELECTRIC_ENABLED, A0RPI_SIGNALS_STYLE_OPPOSITE_SIDE, diff --git a/src/newgrf_newsignals.h b/src/newgrf_newsignals.h index 1329780672..d6c3915cd0 100644 --- a/src/newgrf_newsignals.h +++ b/src/newgrf_newsignals.h @@ -29,6 +29,7 @@ enum NewSignalStyleFlags { NSSF_ALWAYS_RESERVE_THROUGH = 1, NSSF_LOOKAHEAD_ASPECTS_SET = 2, NSSF_OPPOSITE_SIDE = 3, + NSSF_LOOKAHEAD_SINGLE_SIGNAL = 4, }; struct NewSignalStyle { diff --git a/src/pbs.cpp b/src/pbs.cpp index 98e67d6284..078ea30016 100644 --- a/src/pbs.cpp +++ b/src/pbs.cpp @@ -664,6 +664,9 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra if (HasBit(_non_aspect_inc_style_mask, signal_style)) { SetBit(signal_flags, TRSLAI_NO_ASPECT_INC); } + if (HasBit(_next_only_style_mask, signal_style)) { + SetBit(signal_flags, TRSLAI_NEXT_ONLY); + } lookahead->AddSignal(signal_speed, 0, z, signal_flags); lookahead->SetNextExtendPositionIfUnset(); } @@ -1000,8 +1003,10 @@ void SetTrainReservationLookaheadEnd(Train *v) int32 threshold = v->lookahead->current_position + 24; uint8 known_signals_ahead = 1; + bool allow_skip_no_aspect_inc = false; if (v->IsInDepot()) { known_signals_ahead = _extra_aspects + 1; + allow_skip_no_aspect_inc = true; } for (const TrainReservationLookAheadItem &item : v->lookahead->items) { if (item.end >= v->lookahead->reservation_end_position) break; @@ -1010,10 +1015,11 @@ void SetTrainReservationLookaheadEnd(Train *v) /* Signal is within visual range */ uint8 style = item.data_aux >> 8; uint8 max_aspect = (style == 0) ? _extra_aspects : _new_signal_styles[style - 1].lookahead_extra_aspects; - max_aspect += (HasBit(item.data_aux, TRSLAI_NO_ASPECT_INC) ? 1 : 2); + if (!HasBit(item.data_aux, TRSLAI_NEXT_ONLY)) allow_skip_no_aspect_inc = true; + max_aspect += ((HasBit(item.data_aux, TRSLAI_NO_ASPECT_INC) && allow_skip_no_aspect_inc) ? 1 : 2); if (max_aspect > known_signals_ahead) known_signals_ahead = max_aspect; } - if (!HasBit(item.data_aux, TRSLAI_NO_ASPECT_INC)) { + if (!HasBit(item.data_aux, TRSLAI_NO_ASPECT_INC) || !allow_skip_no_aspect_inc) { known_signals_ahead--; if (known_signals_ahead == 0) { if (item.start > v->lookahead->lookahead_end_position) v->lookahead->lookahead_end_position = item.start; diff --git a/src/pbs.h b/src/pbs.h index 52aaae1e2e..e933ef2f11 100644 --- a/src/pbs.h +++ b/src/pbs.h @@ -60,6 +60,7 @@ enum TrainReservationLookAheadItemType : byte { enum TrainReservationSignalLookAheadItemFlags { TRSLAI_NO_ASPECT_INC = 0, ///< This signal does not increase the signal aspect (e.g. banner repeater) + TRSLAI_NEXT_ONLY = 1, ///< This signal only permits lookahead up to the next physical signal, even if that has TRSLAI_NO_ASPECT_INC (e.g. shunt) }; struct TrainReservationLookAheadItem { diff --git a/src/signal.cpp b/src/signal.cpp index 04f33831e7..33f55b7797 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 _next_only_style_mask = 0; uint16 _always_reserve_through_style_mask = 0; uint16 _no_tunnel_bridge_style_mask = 0; uint16 _signal_opposite_side_style_mask = 0; @@ -1512,6 +1513,7 @@ static bool DetermineExtraAspectsVariable() uint8 new_extra_aspects = 0; _non_aspect_inc_style_mask = 0; + _next_only_style_mask = 0; _no_tunnel_bridge_style_mask = 0; _always_reserve_through_style_mask = 0; _signal_opposite_side_style_mask = 0; @@ -1533,7 +1535,10 @@ static bool DetermineExtraAspectsVariable() SetBit(_always_reserve_through_style_mask, i + 1); SetBit(_no_tunnel_bridge_style_mask, i + 1); } - if (HasBit(_new_signal_styles[i].style_flags, NSSF_LOOKAHEAD_ASPECTS_SET)) { + if (HasBit(_new_signal_styles[i].style_flags, NSSF_LOOKAHEAD_SINGLE_SIGNAL)) { + _new_signal_styles[i].lookahead_extra_aspects = 0; + SetBit(_next_only_style_mask, i + 1); + } else if (HasBit(_new_signal_styles[i].style_flags, NSSF_LOOKAHEAD_ASPECTS_SET)) { _new_signal_styles[i].lookahead_extra_aspects = std::min(_new_signal_styles[i].lookahead_extra_aspects, _new_signal_styles[i].grffile->new_signal_extra_aspects); } else { _new_signal_styles[i].lookahead_extra_aspects = _new_signal_styles[i].grffile->new_signal_extra_aspects; diff --git a/src/signal_func.h b/src/signal_func.h index 126fd4b506..5cb7e6846f 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 _next_only_style_mask; extern uint16 _always_reserve_through_style_mask; extern uint16 _no_tunnel_bridge_style_mask; extern uint16 _signal_opposite_side_style_mask; diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index e7c6ee3f80..6d95084aa9 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.h @@ -278,6 +278,7 @@ class NIHVehicle : public NIHelper { case TRLIT_SIGNAL: b += seprintf(b, lastof(buffer), "signal: target speed: %u, style: %u, flags:", item.data_id, item.data_aux >> 8); if (HasBit(item.data_aux, TRSLAI_NO_ASPECT_INC)) b += seprintf(b, lastof(buffer), "n"); + if (HasBit(item.data_aux, TRSLAI_NEXT_ONLY)) b += seprintf(b, lastof(buffer), "s"); if (_settings_game.vehicle.realistic_braking_aspect_limited == TRBALM_ON && l.lookahead_end_position == item.start) { b += seprintf(b, lastof(buffer), ", lookahead end"); print_braking_speed(item.start, 0, item.z_pos);