Add combined normal and shunt aspect signal style flag
This commit is contained in:
@@ -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);
|
||||
|
||||
|
21
src/pbs.cpp
21
src/pbs.cpp
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
127
src/signal.cpp
127
src/signal.cpp
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user