Add combined normal and shunt aspect signal style flag

pull/407/head
Jonathan G Rennison 2 years ago
parent a6e3467d58
commit 78ae295dfe

@ -516,13 +516,20 @@ item (FEAT_GLOBALVARS) {
<tr><td>style_lookahead_single_signal_only</td><td>0 or 1</td>
<td>
Set the look-ahead to single signal only mode for the most recently defined style (defined using the <span class="code">define_style</span> property).<br />
This property only makes a difference when the "limit train lookahead to signal aspect" game setting is enabled.<br />
This property only makes a difference when the "limit train lookahead to signal aspect" game setting is enabled, or when using a different signal
type which uses <span class="code">tyle_combined_normal_shunt</span>.<br />
This is similar to <span class="code">style_lookahead_extra_aspects</span> with a value of 0, except the lookahead always ends at the
next signal, even if that signal type sets <span class="code">style_no_aspect_increase</span>.<br />
If enabled, this property overrides <span class="code">style_lookahead_extra_aspects</span>.<br />
This can be used for shunt signals.
</td>
</tr>
<tr><td>style_combined_normal_shunt</td><td>0 or 1</td>
<td>
Enable functioning as a combined normal aspect and shunt signal for the most recently defined style (defined using the <span class="code">define_style</span> property).<br />
When enabled and displaying a shunt aspect, the signal state in the lowest byte of <span class="code">extra_callback_info2</span> will have the value: 0xFF.
</td>
</tr>
<tr><td>style_opposite_side</td><td>0 or 1</td>
<td>
Set whether signals should be drawn on the opposite side of the track for the most recently defined style (defined using the <span class="code">define_style</span> property).

@ -483,7 +483,8 @@
<p>This is indicated by the feature name: <font face="monospace">action0_signals_style</font>, version 1</p>
<h4 id="signals_style_lookahead_single_signal_only">Set custom signal style train look-ahead to single signal only mode (mappable property: signals_style_lookahead_single_signal_only)</h4>
<p>This applies to the most recent custom signal style defined using the <a href="#signals_define_style">signals_define_style</a> property.<br />
This property only makes a difference when the "limit train lookahead to signal aspect" game setting is enabled.<br />
This property only makes a difference when the "limit train lookahead to signal aspect" game setting is enabled, or when using a different signal
type which uses <a href="#signals_style_combined_normal_shunt">signals_style_combined_normal_shunt</a>.<br />
This is similar to <a href="#signals_style_lookahead_extra_aspects">signals_style_lookahead_extra_aspects</a> with a value of 0, except the lookahead always ends at the
next signal, even if that signal type sets <a href="#signals_style_no_aspect_increase">signals_style_no_aspect_increase</a>.<br />
If enabled, this property overrides <a href="#signals_style_lookahead_extra_aspects">signals_style_lookahead_extra_aspects</a>.<br />
@ -492,6 +493,13 @@
The Action 0 Id field is not used, the value is ignored.
</p>
<p>This is indicated by the feature name: <font face="monospace">action0_signals_style</font>, version 1</p>
<h4 id="signals_style_combined_normal_shunt">Set custom signal style combined normal aspect and shunt signal mode (mappable property: signals_style_combined_normal_shunt)</h4>
<p>This applies to the most recent custom signal style defined using the <a href="#signals_define_style">signals_define_style</a> property.<br />
When enabled and displaying a shunt aspect, the signal state in the lowest byte of variable 0x18 (SS: signal state) will have the value: 0xFF.</p>
<p>The property length is 1 byte. 0 is disabled (default). 1 is enabled.<br />
The Action 0 Id field is not used, the value is ignored.
</p>
<p>This is indicated by the feature name: <font face="monospace">action0_signals_style</font>, version 1</p>
<h4 id="signals_style_opposite_side">Set custom signal style signal drawn on opposite side (mappable property: signals_style_opposite_side)</h4>
<p>This applies to the most recent custom signal style defined using the <a href="#signals_define_style">signals_define_style</a> property.<br />
When enabled, signals using this style are drawn on the opposite side of the track.</p>

@ -356,7 +356,7 @@ void UpdateAllBlockSignals(Owner owner)
}
if (_extra_aspects > 0 && IsTunnelBridgeSignalSimulationEntrance(tile) && GetTunnelBridgeEntranceSignalState(tile) == SIGNAL_STATE_GREEN) {
SetTunnelBridgeEntranceSignalAspect(tile, 0);
UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile));
UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile), false);
}
}
} while (++tile != MapSize());

@ -4289,6 +4289,15 @@ static ChangeInfoResult SignalsChangeInfo(uint id, int numinfo, int prop, const
break;
}
case A0RPI_SIGNALS_STYLE_COMBINED_NORMAL_SHUNT: {
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_COMBINED_NORMAL_SHUNT, 1, (value != 0 ? 1 : 0));
}
break;
}
default:
ret = HandleAction0PropertyDefault(buf, prop);
break;

@ -101,6 +101,7 @@ extern const GRFPropertyMapDefinition _grf_action0_remappable_properties[] = {
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"),
GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_COMBINED_NORMAL_SHUNT, "signals_style_combined_normal_shunt"),
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"),

@ -45,6 +45,7 @@ enum Action0RemapPropertyIds {
A0RPI_SIGNALS_STYLE_SEMAPHORE_ENABLED,
A0RPI_SIGNALS_STYLE_ELECTRIC_ENABLED,
A0RPI_SIGNALS_STYLE_OPPOSITE_SIDE,
A0RPI_SIGNALS_STYLE_COMBINED_NORMAL_SHUNT,
A0RPI_OBJECT_USE_LAND_GROUND,
A0RPI_OBJECT_EDGE_FOUNDATION_MODE,
A0RPI_OBJECT_FLOOD_RESISTANT,

@ -33,6 +33,7 @@ enum NewSignalStyleFlags {
NSSF_LOOKAHEAD_ASPECTS_SET = 2,
NSSF_OPPOSITE_SIDE = 3,
NSSF_LOOKAHEAD_SINGLE_SIGNAL = 4,
NSSF_COMBINED_NORMAL_SHUNT = 5,
};
struct NewSignalStyle {

@ -15,6 +15,7 @@
#include "date_func.h"
#include "depot_base.h"
#include "town.h"
#include "signal_func.h"
#include "safeguards.h"
@ -117,10 +118,16 @@ SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSp
return group->GetResult();
}
inline uint8 RemapAspect(uint8 aspect, uint8 extra_aspects)
inline uint8 RemapAspect(uint8 aspect, uint8 extra_aspects, uint8 style)
{
if (likely(extra_aspects == 0 || _extra_aspects == 0)) return std::min<uint8>(aspect, 1);
if (aspect == 0) return 0;
if (style != 0 && HasBit(_signal_style_masks.combined_normal_shunt, style)) {
if (aspect == 1) {
return 0xFF;
}
aspect--;
}
if (aspect >= extra_aspects + 1) return 1;
return aspect + 1;
}
@ -132,7 +139,7 @@ static PalSpriteID GetRailTypeCustomSignalSprite(const RailtypeInfo *rti, TileIn
if (type == SIGTYPE_NO_ENTRY && !HasBit(rti->ctrl_flags, RTCF_NOENTRYSIG)) return { 0, PAL_NONE };
uint32 param1 = (context == CSSC_GUI) ? 0x10 : 0x00;
uint32 param2 = (type << 16) | (var << 8) | RemapAspect(aspect, rti->signal_extra_aspects);
uint32 param2 = (type << 16) | (var << 8) | RemapAspect(aspect, rti->signal_extra_aspects, 0);
if ((prog != nullptr) && HasBit(rti->ctrl_flags, RTCF_RESTRICTEDSIG)) SetBit(param2, 24);
RailTypeResolverObject object(rti, tile, TCX_NORMAL, RTSG_SIGNALS, param1, param2, context, prog);
@ -170,7 +177,7 @@ CustomSignalSpriteResult GetCustomSignalSprite(const RailtypeInfo *rti, TileInde
if (!HasBit(grf->new_signal_style_mask, style)) continue;
uint32 param1 = (context == CSSC_GUI) ? 0x10 : 0x00;
uint32 param2 = (type << 16) | (var << 8) | RemapAspect(aspect, grf->new_signal_extra_aspects);
uint32 param2 = (type << 16) | (var << 8) | RemapAspect(aspect, grf->new_signal_extra_aspects, style);
if ((prog != nullptr) && HasBit(grf->new_signal_ctrl_flags, NSCF_RESTRICTEDSIG)) SetBit(param2, 24);
NewSignalsResolverObject object(grf, tile, TCX_NORMAL, param1, param2, context, style, prog);

@ -88,7 +88,7 @@ bool TryReserveRailTrackdir(TileIndex tile, Trackdir td, bool trigger_stations)
MarkSingleSignalDirty(tile, td);
if (_extra_aspects > 0) {
SetSignalAspect(tile, TrackdirToTrack(td), 0);
UpdateAspectDeferred(tile, td);
UpdateAspectDeferred(tile, td, true);
}
}
return success;
@ -667,6 +667,10 @@ static PBSTileInfo FollowReservation(Owner o, RailTypes rts, TileIndex tile, Tra
if (HasBit(_signal_style_masks.next_only, signal_style)) {
SetBit(signal_flags, TRSLAI_NEXT_ONLY);
}
if (HasBit(_signal_style_masks.combined_normal_shunt, signal_style)) {
SetBit(signal_flags, TRSLAI_COMBINED);
UpdateLookaheadCombinedNormalShuntSignalDeferred(tile, trackdir, lookahead->RealEndPosition());
}
lookahead->AddSignal(signal_speed, 0, z, signal_flags);
lookahead->SetNextExtendPositionIfUnset();
}
@ -1011,6 +1015,18 @@ void SetTrainReservationLookaheadEnd(Train *v)
for (const TrainReservationLookAheadItem &item : v->lookahead->items) {
if (item.end >= v->lookahead->reservation_end_position) break;
if (item.type == TRLIT_SIGNAL) {
if (HasBit(item.data_aux, TRSLAI_COMBINED_SHUNT)) {
/* Combined normal/shunt in shunt mode */
allow_skip_no_aspect_inc = false;
if (item.start <= threshold) {
known_signals_ahead = 1;
continue;
} else {
if (item.start > v->lookahead->lookahead_end_position) v->lookahead->lookahead_end_position = item.start;
return;
}
}
if (item.start <= threshold) {
/* Signal is within visual range */
uint8 style = item.data_aux >> 8;
@ -1090,6 +1106,7 @@ void FillTrainReservationLookAhead(Train *v)
}
if (!(HasAcrossTunnelBridgeReservation(end) && GetTunnelBridgeExitSignalState(end) == SIGNAL_STATE_GREEN && raw_free_tiles == INT_MAX)) {
/* do not attempt to follow through a signalled tunnel/bridge if it is not empty or the far end is not reserved */
FlushDeferredDetermineCombineNormalShuntMode(v);
SetTrainReservationLookaheadEnd(v);
return;
}
@ -1097,6 +1114,7 @@ void FillTrainReservationLookAhead(Train *v)
}
if (IsRailDepotTile(tile) && !GetDepotReservationTrackBits(tile)) {
FlushDeferredDetermineCombineNormalShuntMode(v);
SetTrainReservationLookaheadEnd(v);
return;
}
@ -1131,6 +1149,7 @@ void FillTrainReservationLookAhead(Train *v)
v->lookahead->reservation_end_tile = res.tile;
v->lookahead->reservation_end_trackdir = res.trackdir;
FlushDeferredDetermineCombineNormalShuntMode(v);
SetTrainReservationLookaheadEnd(v);
}

@ -61,6 +61,8 @@ 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)
TRSLAI_COMBINED = 2, ///< This signal is a combined normal/shunt signal, special handling
TRSLAI_COMBINED_SHUNT = 3, ///< This signal is a combined normal/shunt signal, in shunt mode
};
struct TrainReservationLookAheadItem {

@ -1434,7 +1434,7 @@ static void SetupBridgeTunnelSignalSimulation(TileIndex entrance, TileIndex exit
SetTunnelBridgeSignalSimulationExit(exit);
if (_extra_aspects > 0) {
SetTunnelBridgeEntranceSignalAspect(entrance, 0);
UpdateAspectDeferred(entrance, GetTunnelBridgeEntranceTrackdir(entrance));
UpdateAspectDeferred(entrance, GetTunnelBridgeEntranceTrackdir(entrance), false);
}
}
@ -1583,7 +1583,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
SetTunnelBridgeSignalSimulationExit(t);
if (_extra_aspects > 0) {
SetTunnelBridgeEntranceSignalAspect(t, 0);
UpdateAspectDeferred(t, GetTunnelBridgeEntranceTrackdir(t));
UpdateAspectDeferred(t, GetTunnelBridgeEntranceTrackdir(t), false);
}
};

@ -25,6 +25,7 @@
#include "newgrf_newsignals.h"
#include "core/checksum_func.hpp"
#include "core/hash_func.hpp"
#include "pathfinder/follow_track.hpp"
#include "safeguards.h"
@ -367,7 +368,7 @@ static SigInfo ExploreSegment(Owner owner)
if (HasSignalOnTrackdir(tile, reversedir)) {
if (IsPbsSignalNonExtended(sig)) {
info.flags |= SF_PBS;
if (_extra_aspects > 0 && GetSignalStateByTrackdir(tile, reversedir) == SIGNAL_STATE_GREEN) {
if (_extra_aspects > 0 && GetSignalStateByTrackdir(tile, reversedir) == SIGNAL_STATE_GREEN && !IsRailSpecialSignalAspect(tile, track)) {
_tbpset.Add(tile, reversedir);
}
} else if (!_tbuset.Add(tile, reversedir)) {
@ -778,7 +779,7 @@ static void UpdateSignalsAroundSegment(SigInfo info)
/* don't change signal state if tile is reserved in realistic braking mode */
if ((_settings_game.vehicle.train_braking_model == TBM_REALISTIC && HasBit(GetRailReservationTrackBits(tile), track))) {
if (_extra_aspects > 0 && GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_GREEN) {
if (_extra_aspects > 0 && GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_GREEN && !IsRailSpecialSignalAspect(tile, track)) {
uint8 aspect = GetForwardAspectAndIncrement(info, tile, trackdir);
uint8 old_aspect = GetSignalAspect(tile, track);
if (aspect != old_aspect) {
@ -1263,7 +1264,14 @@ uint8 GetSignalAspectGeneric(TileIndex tile, Trackdir trackdir, bool check_non_i
void AdjustSignalAspectIfNonIncStyleIntl(TileIndex tile, Track track, uint8 &aspect)
{
if (IsTileType(tile, MP_RAILWAY) && HasBit(_signal_style_masks.non_aspect_inc, GetSignalStyle(tile, track))) aspect--;
if (IsTileType(tile, MP_RAILWAY)) {
uint8 style = GetSignalStyle(tile, track);
if (HasBit(_signal_style_masks.combined_normal_shunt, style)) {
aspect--;
if (aspect == 0) return;
}
if (HasBit(_signal_style_masks.non_aspect_inc, style)) aspect--;
}
}
static void RefreshBridgeOnExitAspectChange(TileIndex entrance, TileIndex exit)
@ -1282,6 +1290,11 @@ static void RefreshBridgeOnExitAspectChange(TileIndex entrance, TileIndex exit)
}
}
static inline bool IsRailCombinedNormalShuntSignalStyle(TileIndex tile, Track track)
{
return _signal_style_masks.combined_normal_shunt != 0 && HasBit(_signal_style_masks.combined_normal_shunt, GetSignalStyle(tile, track));
}
void PropagateAspectChange(TileIndex tile, Trackdir trackdir, uint8 aspect)
{
AdjustSignalAspectIfNonIncStyle(tile, TrackdirToTrack(trackdir), aspect);
@ -1330,7 +1343,14 @@ void PropagateAspectChange(TileIndex tile, Trackdir trackdir, uint8 aspect)
if (HasSignalOnTrackdir(tile, reversedir)) {
if (GetSignalStateByTrackdir(tile, reversedir) == SIGNAL_STATE_RED) return;
if (GetSignalAspect(tile, track) == aspect) return; // aspect already correct
bool combined_mode = IsRailCombinedNormalShuntSignalStyle(tile, track);
const uint8 current_aspect = GetSignalAspect(tile, track);
if (combined_mode && current_aspect == 1) {
/* Don't change special combined_normal_shunt aspect */
return;
}
if (combined_mode && aspect > 0) aspect = std::min<uint8>(aspect + 1, 7);
if (current_aspect == aspect) return; // aspect already correct
SetSignalAspect(tile, track, aspect);
MarkSingleSignalDirty(tile, reversedir);
AdjustSignalAspectIfNonIncStyle(tile, TrackdirToTrack(trackdir), aspect);
@ -1426,12 +1446,29 @@ void PropagateAspectChange(TileIndex tile, Trackdir trackdir, uint8 aspect)
}
static std::vector<std::pair<TileIndex, Trackdir>> _deferred_aspect_updates;
static std::vector<std::pair<TileIndex, Trackdir>> _deferred_determine_combined_normal_shunt_mode;
void UpdateAspectDeferred(TileIndex tile, Trackdir trackdir)
struct DeferredLookaheadCombinedNormalShuntModeItem {
TileIndex tile;
Trackdir trackdir;
int lookahead_position;
};
static std::vector<DeferredLookaheadCombinedNormalShuntModeItem> _deferred_lookahead_combined_normal_shunt_mode;
void UpdateAspectDeferred(TileIndex tile, Trackdir trackdir, bool check_combined_normal_aspect)
{
if (check_combined_normal_aspect && IsRailCombinedNormalShuntSignalStyle(tile, TrackdirToTrack(trackdir)) &&
_settings_game.vehicle.train_braking_model == TBM_REALISTIC) {
_deferred_determine_combined_normal_shunt_mode.push_back({ tile, trackdir });
}
_deferred_aspect_updates.push_back({ tile, trackdir });
}
void UpdateLookaheadCombinedNormalShuntSignalDeferred(TileIndex tile, Trackdir trackdir, int lookahead_position)
{
_deferred_lookahead_combined_normal_shunt_mode.push_back({ tile, trackdir, lookahead_position });
}
void FlushDeferredAspectUpdates()
{
/* Iterate in reverse order to reduce backtracking when updating the aspects of a new reservation */
@ -1441,7 +1478,7 @@ void FlushDeferredAspectUpdates()
switch (GetTileType(tile)) {
case MP_RAILWAY:
if (HasSignalOnTrackdir(tile, trackdir) && GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_GREEN && GetSignalAspect(tile, TrackdirToTrack(trackdir)) == 0) {
uint8 aspect = GetForwardAspectFollowingTrackAndIncrement(tile, trackdir);
uint8 aspect = GetForwardAspectFollowingTrackAndIncrement(tile, trackdir, IsRailCombinedNormalShuntSignalStyle(tile, TrackdirToTrack(trackdir)));
SetSignalAspect(tile, TrackdirToTrack(trackdir), aspect);
PropagateAspectChange(tile, trackdir, aspect);
}
@ -1469,6 +1506,68 @@ void FlushDeferredAspectUpdates()
_deferred_aspect_updates.clear();
}
void DetermineCombineNormalShuntModeWithLookahead(Train *v, TileIndex tile, Trackdir trackdir, int lookahead_position)
{
size_t count = v->lookahead->items.size();
for (size_t i = 0; i < count; i++) {
TrainReservationLookAheadItem &item = v->lookahead->items[i];
if (item.start == lookahead_position && item.type == TRLIT_SIGNAL && HasBit(item.data_aux, TRSLAI_COMBINED)) {
container_unordered_remove(_deferred_determine_combined_normal_shunt_mode, std::pair<TileIndex, Trackdir>({ tile, trackdir }));
for (size_t j = i + 1; j < count; j++) {
const TrainReservationLookAheadItem &ahead = v->lookahead->items[j];
if (ahead.type == TRLIT_SIGNAL) {
if (HasBit(item.data_aux, TRSLAI_COMBINED)) return;
if (!HasBit(item.data_aux, TRSLAI_NO_ASPECT_INC) && !HasBit(item.data_aux, TRSLAI_NEXT_ONLY)) return;
}
}
if (IsRailDepotTile(v->lookahead->reservation_end_tile) || IsTileType(v->lookahead->reservation_end_tile, MP_TUNNELBRIDGE)) return;
CFollowTrackRail ft(v);
if (ft.Follow(v->lookahead->reservation_end_tile, v->lookahead->reservation_end_trackdir)) {
if (KillFirstBit(ft.m_new_td_bits) != TRACKDIR_BIT_NONE) {
/* reached a junction tile, shouldn't be reached, just assume normal route */
return;
}
TileIndex new_tile = ft.m_new_tile;
Trackdir new_trackdir = FindFirstTrackdir(ft.m_new_td_bits);
if (!(IsTileType(new_tile, MP_RAILWAY) && HasSignalOnTrackdir(new_tile, new_trackdir) && !IsNoEntrySignal(new_tile, TrackdirToTrack(new_trackdir)) &&
HasBit(_signal_style_masks.next_only, GetSignalStyle(new_tile, TrackdirToTrack(new_trackdir))))) {
/* Didn't find a shunt signal at the end of the reservation */
return;
}
} else {
/* end of line */
return;
}
/* shunt mode */
SetSignalAspect(tile, TrackdirToTrack(trackdir), 1);
SetBit(item.data_aux, TRSLAI_COMBINED_SHUNT);
return;
}
}
}
void FlushDeferredDetermineCombineNormalShuntMode(Train *v)
{
for (const auto &iter : _deferred_lookahead_combined_normal_shunt_mode) {
DetermineCombineNormalShuntModeWithLookahead(v, iter.tile, iter.trackdir, iter.lookahead_position);
}
_deferred_lookahead_combined_normal_shunt_mode.clear();
for (const auto &iter : _deferred_determine_combined_normal_shunt_mode) {
TileIndex tile = iter.first;
Trackdir trackdir = iter.second;
/* Reservation with no associated lookahead, default to a shunt route */
SetSignalAspect(tile, TrackdirToTrack(trackdir), 1);
}
_deferred_determine_combined_normal_shunt_mode.clear();
}
void UpdateAllSignalAspects()
{
for (TileIndex tile = 0; tile != MapSize(); ++tile) {
@ -1479,8 +1578,8 @@ void UpdateAllSignalAspects()
if (HasSignalOnTrack(tile, track)) {
Trackdir trackdir = TrackToTrackdir(track);
if (!HasSignalOnTrackdir(tile, trackdir)) trackdir = ReverseTrackdir(trackdir);
if (GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_GREEN) {
uint8 aspect = GetForwardAspectFollowingTrackAndIncrement(tile, trackdir);
if (GetSignalStateByTrackdir(tile, trackdir) == SIGNAL_STATE_GREEN && !IsRailSpecialSignalAspect(tile, track)) {
uint8 aspect = GetForwardAspectFollowingTrackAndIncrement(tile, trackdir, IsRailCombinedNormalShuntSignalStyle(tile, track));
SetSignalAspect(tile, track, aspect);
PropagateAspectChange(tile, trackdir, aspect);
}
@ -1613,6 +1712,12 @@ static bool DetermineExtraAspectsVariable()
if (HasBit(_new_signal_styles[i].style_flags, NSSF_OPPOSITE_SIDE)) {
SetBit(_signal_style_masks.signal_opposite_side, i + 1);
}
if (HasBit(_new_signal_styles[i].style_flags, NSSF_COMBINED_NORMAL_SHUNT)) {
SetBit(_signal_style_masks.combined_normal_shunt, i + 1);
SetBit(_signal_style_masks.no_tunnel_bridge, i + 1);
_new_signal_styles[i].electric_mask &= (1 << SIGTYPE_PBS) | (1 << SIGTYPE_PBS_ONEWAY) | (1 << SIGTYPE_NO_ENTRY);
_new_signal_styles[i].semaphore_mask &= (1 << SIGTYPE_PBS) | (1 << SIGTYPE_PBS_ONEWAY) | (1 << SIGTYPE_NO_ENTRY);
}
}
for (uint i = _num_new_signal_styles; i < MAX_NEW_SIGNAL_STYLES; i++) {
_new_signal_styles[i].lookahead_extra_aspects = new_extra_aspects;
@ -1665,6 +1770,12 @@ void InitialiseExtraAspectsVariable()
DetermineExtraAspectsVariable();
}
bool IsRailSpecialSignalAspect(TileIndex tile, Track track)
{
return _signal_style_masks.combined_normal_shunt != 0 && GetSignalAspect(tile, track) == 1 &&
HasBit(_signal_style_masks.combined_normal_shunt, GetSignalStyle(tile, track));
}
void UpdateSignalReserveThroughBit(TileIndex tile, Track track, bool update_signal)
{
bool reserve_through = false;

@ -33,6 +33,7 @@ struct SignalStyleMasks {
uint16 always_reserve_through = 0;
uint16 no_tunnel_bridge = 0;
uint16 signal_opposite_side = 0;
uint16 combined_normal_shunt = 0;
};
extern SignalStyleMasks _signal_style_masks;
@ -188,21 +189,24 @@ void UpdateSignalsInBufferIfOwnerNotAddable(Owner owner);
uint8 GetForwardAspectFollowingTrack(TileIndex tile, Trackdir trackdir);
uint8 GetSignalAspectGeneric(TileIndex tile, Trackdir trackdir, bool check_non_inc_style);
void PropagateAspectChange(TileIndex tile, Trackdir trackdir, uint8 aspect);
void UpdateAspectDeferred(TileIndex tile, Trackdir trackdir);
void UpdateAspectDeferred(TileIndex tile, Trackdir trackdir, bool check_combined_normal_aspect);
void UpdateLookaheadCombinedNormalShuntSignalDeferred(TileIndex tile, Trackdir trackdir, int lookahead_position);
void FlushDeferredAspectUpdates();
void FlushDeferredDetermineCombineNormalShuntMode(Train *v);
void UpdateAllSignalAspects();
void UpdateExtraAspectsVariable();
void InitialiseExtraAspectsVariable();
bool IsRailSpecialSignalAspect(TileIndex tile, Track track);
inline void AdjustSignalAspectIfNonIncStyle(TileIndex tile, Track track, uint8 &aspect)
{
extern void AdjustSignalAspectIfNonIncStyleIntl(TileIndex tile, Track track, uint8 &aspect);
if (aspect > 0 && _signal_style_masks.non_aspect_inc != 0) AdjustSignalAspectIfNonIncStyleIntl(tile, track, aspect);
if (aspect > 0 && (_signal_style_masks.non_aspect_inc != 0 || _signal_style_masks.combined_normal_shunt != 0)) AdjustSignalAspectIfNonIncStyleIntl(tile, track, aspect);
}
inline uint8 GetForwardAspectFollowingTrackAndIncrement(TileIndex tile, Trackdir trackdir)
inline uint8 GetForwardAspectFollowingTrackAndIncrement(TileIndex tile, Trackdir trackdir, bool combined_normal_mode = false)
{
return std::min<uint8>(GetForwardAspectFollowingTrack(tile, trackdir) + 1, GetMaximumSignalAspect());
return std::min<uint8>(GetForwardAspectFollowingTrack(tile, trackdir) + (combined_normal_mode ? 2 : 1), GetMaximumSignalAspect());
}
void UpdateSignalReserveThroughBit(TileIndex tile, Track track, bool update_signal);

@ -279,6 +279,8 @@ class NIHVehicle : public NIHelper {
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 (HasBit(item.data_aux, TRSLAI_COMBINED)) b += seprintf(b, lastof(buffer), "c");
if (HasBit(item.data_aux, TRSLAI_COMBINED_SHUNT)) b += seprintf(b, lastof(buffer), "X");
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);

@ -3454,7 +3454,7 @@ static void SetTunnelBridgeEntranceSignalGreen(TileIndex tile)
MarkTunnelBridgeSignalDirty(tile, false);
if (_extra_aspects > 0) {
SetTunnelBridgeEntranceSignalAspect(tile, 0);
UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile));
UpdateAspectDeferred(tile, GetTunnelBridgeEntranceTrackdir(tile), false);
}
} else if (_extra_aspects > 0) {
UpdateTunnelBridgeEntranceSignalAspect(tile);
@ -4086,6 +4086,7 @@ static TileIndex CheckLongReservePbsTunnelBridgeOnTrackdir(Train* v, TileIndex t
} else {
raw_free_tiles = GetAvailableFreeTilesInSignalledTunnelBridgeWithStartOffset(tile, end, v->lookahead->tunnel_bridge_reserved_tiles + 1);
ApplyAvailableFreeTunnelBridgeTiles(v->lookahead.get(), raw_free_tiles, tile, end);
FlushDeferredDetermineCombineNormalShuntMode(v);
SetTrainReservationLookaheadEnd(v);
}
} else {
@ -4156,7 +4157,7 @@ static void TryLongReserveChooseTrainTrack(Train *v, TileIndex tile, Trackdir td
} else {
if (_extra_aspects > 0) {
SetTunnelBridgeExitSignalAspect(exit_tile, 0);
UpdateAspectDeferred(exit_tile, GetTunnelBridgeExitTrackdir(exit_tile));
UpdateAspectDeferred(exit_tile, GetTunnelBridgeExitTrackdir(exit_tile), false);
}
MarkTileDirtyByTile(exit_tile, VMDF_NOT_MAP_MODE);
}
@ -4250,7 +4251,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir,
SetSignalStateByTrackdir(tile, changed_signal, SIGNAL_STATE_GREEN);
if (_extra_aspects > 0) {
SetSignalAspect(tile, track, 0);
UpdateAspectDeferred(tile, changed_signal);
UpdateAspectDeferred(tile, changed_signal, true);
}
} else if (!do_track_reservation) {
return track;
@ -5141,7 +5142,7 @@ static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile)
if (ok) {
if (_extra_aspects > 0) {
SetTunnelBridgeExitSignalAspect(tile, 0);
UpdateAspectDeferred(tile, GetTunnelBridgeExitTrackdir(tile));
UpdateAspectDeferred(tile, GetTunnelBridgeExitTrackdir(tile), false);
}
mark_dirty = true;
if (t->lookahead->reservation_end_tile == veh_orig_tile && t->lookahead->reservation_end_position - t->lookahead->current_position <= (int)TILE_SIZE) {
@ -5186,7 +5187,7 @@ static bool CheckTrainStayInWormHolePathReserve(Train *t, TileIndex tile)
SetTunnelBridgeExitSignalState(tile, SIGNAL_STATE_GREEN);
if (_extra_aspects > 0) {
SetTunnelBridgeExitSignalAspect(tile, 0);
UpdateAspectDeferred(tile, GetTunnelBridgeExitTrackdir(tile));
UpdateAspectDeferred(tile, GetTunnelBridgeExitTrackdir(tile), false);
}
mark_dirty = true;
}

Loading…
Cancel
Save