Add signal style flag for unconditional reserve through

Add map bits for unconditional reserve through
Adjust signal aspect/state handling
pull/400/head
Jonathan G Rennison 2 years ago
parent 7ae06124ae
commit bdd73a19a1

@ -510,6 +510,8 @@
<li>m4 bits 7..4: bit clear = signal 3..0 shows red</li> <li>m4 bits 7..4: bit clear = signal 3..0 shows red</li>
<li style="color: blue">m6 bits 7..4: signal style for signal 0 and 1</li> <li style="color: blue">m6 bits 7..4: signal style for signal 0 and 1</li>
<li style="color: blue">m6 bits 3..0: signal style for signal 2 and 3</li> <li style="color: blue">m6 bits 3..0: signal style for signal 2 and 3</li>
<li style="color: blue">m7 bits 7: reserve through always set for signal 0 or 1</li>
<li style="color: blue">m7 bits 6: reserve through always set for signal 2 or 3</li>
<li style="color: blue">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)</li> <li style="color: blue">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)</li>
<li style="color: blue">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)</li> <li style="color: blue">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)</li>
</ul> </ul>

@ -114,7 +114,7 @@ the array so you can quickly see what is used and what is not.
<td class="bits"><span class="used" title="Signals colors">XXXX</span> <span class="used" title="Ground type: fences, snow, desert">XXXX</span></td> <td class="bits"><span class="used" title="Signals colors">XXXX</span> <span class="used" title="Ground type: fences, snow, desert">XXXX</span></td>
<td class="bits"><span class="used" title="Rail tile type: rail, rail with signals, depot">O1</span> <span class="used" title="Track pieces">XXXXXX</span></td> <td class="bits"><span class="used" title="Rail tile type: rail, rail with signals, depot">O1</span> <span class="used" title="Track pieces">XXXXXX</span></td>
<td class="bits"><span class="patch" title="Signal styles">PPPP PPPP</span></td> <td class="bits"><span class="patch" title="Signal styles">PPPP PPPP</span></td>
<td class="bits"><span class="free">OO</span> <span class="patch" title="Signal aspects">PPPPPP</span></td> <td class="bits"><span class="patch" title="Signal always reserve through">PP</span> <span class="patch" title="Signal aspects">PPPPPP</span></td>
</tr> </tr>
<tr> <tr>
<td class="caption">depot</td> <td class="caption">depot</td>

@ -466,6 +466,11 @@ item (FEAT_GLOBALVARS) {
the signal aspect with respect to the signals either side (i.e. function like a banner repeater). the signal aspect with respect to the signals either side (i.e. function like a banner repeater).
</td> </td>
</tr> </tr>
<tr><td>style_always_reserve_through</td><td>0 or 1</td>
<td>
Set whether reserve through is unconditionally enabled for the most recently defined style (defined using the define_style property).
</td>
</tr>
<tr><td>no_default_style</td><td>0 or 1</td> <tr><td>no_default_style</td><td>0 or 1</td>
<td> <td>
When enabled, custom signal graphics from this GRF are only used for custom signal styles, not the default style When enabled, custom signal graphics from this GRF are only used for custom signal styles, not the default style

@ -438,6 +438,13 @@
The Action 0 Id field is not used, the value is ignored. The Action 0 Id field is not used, the value is ignored.
</p> </p>
<p>This is indicated by the feature name: <font face="monospace">action0_signals_style</font>, version 1</p> <p>This is indicated by the feature name: <font face="monospace">action0_signals_style</font>, version 1</p>
<h4 id="signals_style_always_reserve_through">Set custom signal style always reserve through mode (mappable property: signals_style_always_reserve_through)</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 have reserve through unconditionally enabled.</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_no_default_style">Set whether custom signal sprites should not be used for the default signal style (mappable property: signals_no_default_style)</h4> <h4 id="signals_no_default_style">Set whether custom signal sprites should not be used for the default signal style (mappable property: signals_no_default_style)</h4>
<p>This applies to <a href="#a3signals_custom_signal_sprites">Action 2/3 Signals (Feature 0E) custom signal sprites</a> for this GRF.<br /> <p>This applies to <a href="#a3signals_custom_signal_sprites">Action 2/3 Signals (Feature 0E) custom signal sprites</a> for this GRF.<br />
When enabled, this GRF is not used for the default signal style, it is only used for custom signal styles defined with <a href="#signals_define_style">signals_define_style</a>.</p> When enabled, this GRF is not used for the default signal style, it is only used for custom signal styles defined with <a href="#signals_define_style">signals_define_style</a>.</p>

@ -4234,6 +4234,15 @@ static ChangeInfoResult SignalsChangeInfo(uint id, int numinfo, int prop, const
break; 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: default:
ret = HandleAction0PropertyDefault(buf, prop); ret = HandleAction0PropertyDefault(buf, prop);
break; break;

@ -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_DEFINE_STYLE, "signals_define_style"),
GRFPropertyMapDefinition(GSF_SIGNALS, A0RPI_SIGNALS_STYLE_NAME, "signals_style_name"), 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_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_USE_LAND_GROUND, "object_use_land_ground"),
GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_EDGE_FOUNDATION_MODE, "object_edge_foundation_mode"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_EDGE_FOUNDATION_MODE, "object_edge_foundation_mode"),
GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_FLOOD_RESISTANT, "object_flood_resistant"), GRFPropertyMapDefinition(GSF_OBJECTS, A0RPI_OBJECT_FLOOD_RESISTANT, "object_flood_resistant"),

@ -39,6 +39,7 @@ enum Action0RemapPropertyIds {
A0RPI_SIGNALS_DEFINE_STYLE, A0RPI_SIGNALS_DEFINE_STYLE,
A0RPI_SIGNALS_STYLE_NAME, A0RPI_SIGNALS_STYLE_NAME,
A0RPI_SIGNALS_STYLE_NO_ASPECT_INCREASE, A0RPI_SIGNALS_STYLE_NO_ASPECT_INCREASE,
A0RPI_SIGNALS_STYLE_ALWAYS_RESERVE_THROUGH,
A0RPI_OBJECT_USE_LAND_GROUND, A0RPI_OBJECT_USE_LAND_GROUND,
A0RPI_OBJECT_EDGE_FOUNDATION_MODE, A0RPI_OBJECT_EDGE_FOUNDATION_MODE,
A0RPI_OBJECT_FLOOD_RESISTANT, A0RPI_OBJECT_FLOOD_RESISTANT,

@ -46,7 +46,7 @@ static uint8 MapSignalStyle(uint8 style)
switch (variable) { switch (variable) {
case 0x40: return GetTerrainType(this->tile, this->context); case 0x40: return GetTerrainType(this->tile, this->context);
case A2VRI_SIGNALS_SIGNAL_RESTRICTION_INFO: 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: case A2VRI_SIGNALS_SIGNAL_CONTEXT:
return GetNewSignalsSignalContext(this->signal_context, this->tile); return GetNewSignalsSignalContext(this->signal_context, this->tile);
case A2VRI_SIGNALS_SIGNAL_STYLE: return MapSignalStyle(this->signal_style); 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; 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 = 0;
if (signal_style != 0 && HasBit(_always_reserve_through_style_mask, signal_style)) result |= 2;
uint result = 1; if (prog != nullptr) {
if ((prog->actions_used_flags & TRPAUF_RESERVE_THROUGH_ALWAYS) && !IsTileType(tile, MP_TUNNELBRIDGE)) result |= 2; result |= 1;
if ((prog->actions_used_flags & TRPAUF_REVERSE) && !IsTileType(tile, MP_TUNNELBRIDGE)) result |= 4; 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; return result;
} }

@ -26,6 +26,7 @@ enum {
enum NewSignalStyleFlags { enum NewSignalStyleFlags {
NSSF_NO_ASPECT_INC = 0, NSSF_NO_ASPECT_INC = 0,
NSSF_ALWAYS_RESERVE_THROUGH = 1,
}; };
struct NewSignalStyle { struct NewSignalStyle {
@ -82,7 +83,7 @@ struct NewSignalsResolverObject : public ResolverObject {
GrfSpecFeature GetFeature() const override; 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) inline uint GetNewSignalsSignalContext(CustomSignalSpriteContext signal_context, TileIndex tile)
{ {

@ -55,7 +55,7 @@
return t != nullptr ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE; return t != nullptr ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE;
} }
case A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO: case A2VRI_RAILTYPE_SIGNAL_RESTRICTION_INFO:
return GetNewSignalsRestrictedSignalsInfo(this->prog, this->tile); return GetNewSignalsRestrictedSignalsInfo(this->prog, this->tile, 0);
case A2VRI_RAILTYPE_SIGNAL_CONTEXT: case A2VRI_RAILTYPE_SIGNAL_CONTEXT:
return GetNewSignalsSignalContext(this->signal_context, this->tile); return GetNewSignalsSignalContext(this->signal_context, this->tile);
} }

@ -1259,10 +1259,10 @@ bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bo
/* PBS signal on next trackdir? Conditionally safe position. */ /* PBS signal on next trackdir? Conditionally safe position. */
if (HasPbsSignalOnTrackdir(ft.m_new_tile, td)) { if (HasPbsSignalOnTrackdir(ft.m_new_tile, td)) {
if (GetSignalType(ft.m_new_tile, TrackdirToTrack(td)) == SIGTYPE_NO_ENTRY) return include_line_end; 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)) { if (IsRestrictedSignal(ft.m_new_tile)) {
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(ft.m_new_tile, TrackdirToTrack(td)); const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(ft.m_new_tile, TrackdirToTrack(td));
if (prog && prog->actions_used_flags & TRPAUF_RESERVE_THROUGH) { if (prog && prog->actions_used_flags & TRPAUF_RESERVE_THROUGH) {
if (prog->actions_used_flags & TRPAUF_RESERVE_THROUGH_ALWAYS) return false;
TraceRestrictProgramResult out; TraceRestrictProgramResult out;
prog->Execute(v, TraceRestrictProgramInput(ft.m_new_tile, td, &VehiclePosTraceRestrictPreviousSignalCallback, nullptr), out); prog->Execute(v, TraceRestrictProgramInput(ft.m_new_tile, td, &VehiclePosTraceRestrictPreviousSignalCallback, nullptr), out);
if (out.flags & TRPRF_RESERVE_THROUGH) { if (out.flags & TRPRF_RESERVE_THROUGH) {

@ -1720,6 +1720,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
SetSignalType(tile, track, sigtype); SetSignalType(tile, track, sigtype);
SetSignalVariant(tile, track, sigvar); SetSignalVariant(tile, track, sigvar);
SetSignalStyle(tile, track, signal_style); SetSignalStyle(tile, track, signal_style);
UpdateSignalReserveThroughBit(tile, track, false);
} }
/* Subtract old signal infrastructure count. */ /* 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); if (sigtype == SIGTYPE_NO_ENTRY) CycleSignalSide(tile, track);
UpdateSignalReserveThroughBit(tile, track, false);
} }
} else if (ctrl_pressed) { } else if (ctrl_pressed) {
@ -1794,6 +1797,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1,
FreeSignalProgram(SignalReference(tile, track)); FreeSignalProgram(SignalReference(tile, track));
SetSignalType(tile, track, sigtype); SetSignalType(tile, track, sigtype);
SetSignalStyle(tile, track, signal_style); SetSignalStyle(tile, track, signal_style);
UpdateSignalReserveThroughBit(tile, track, false);
} }
/* Add new signal infrastructure count. */ /* Add new signal infrastructure count. */

@ -397,6 +397,11 @@ static inline void SetSignalAspect(TileIndex t, Track track, uint8 aspect)
SB(_me[t].m7, pos, 3, 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) static inline uint8 GetSignalStyle(TileIndex t, Track track)
{ {
assert_tile(GetRailTileType(t) == RAIL_TILE_SIGNALS, t); 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); 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) * Set the states of the signals (Along/AgainstTrackDir)
* @param tile the tile to set the states for * @param tile the tile to set the states for

@ -4078,6 +4078,10 @@ bool AfterLoadGame()
} }
} }
if (SlXvIsFeatureMissing(XSLFI_REALISTIC_TRAIN_BRAKING, 8)) {
_aspect_cfg_hash = 0;
}
InitializeRoadGUI(); InitializeRoadGUI();
/* This needs to be done after conversion. */ /* This needs to be done after conversion. */

@ -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_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_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_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_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_WATER_FLOODING, XSCF_NULL, 2, 2, "water_flooding", nullptr, nullptr, nullptr },
{ XSLFI_MORE_HOUSES, XSCF_NULL, 2, 2, "more_houses", nullptr, nullptr, nullptr }, { XSLFI_MORE_HOUSES, XSCF_NULL, 2, 2, "more_houses", nullptr, nullptr, nullptr },

@ -31,6 +31,7 @@
uint8 _extra_aspects = 0; uint8 _extra_aspects = 0;
uint64 _aspect_cfg_hash = 0; uint64 _aspect_cfg_hash = 0;
uint16 _non_aspect_inc_style_mask = 0; uint16 _non_aspect_inc_style_mask = 0;
uint16 _always_reserve_through_style_mask = 0;
uint16 _no_tunnel_bridge_style_mask = 0; uint16 _no_tunnel_bridge_style_mask = 0;
bool _signal_sprite_oversized = false; bool _signal_sprite_oversized = false;
@ -382,6 +383,10 @@ static SigInfo ExploreSegment(Owner owner)
if (_extra_aspects > 0) { if (_extra_aspects > 0) {
info.out_signal_tile = tile; info.out_signal_tile = tile;
info.out_signal_trackdir = trackdir; 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 */ /* if it is a presignal EXIT in OUR direction, count it */
@ -856,6 +861,10 @@ static void UpdateSignalsAroundSegment(SigInfo info)
// Progsig dependencies // Progsig dependencies
MarkDependencidesForUpdate(SignalReference(tile, track)); 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); SetSignalStateByTrackdir(tile, trackdir, newstate);
refresh = true; refresh = true;
@ -1503,6 +1512,7 @@ static bool DetermineExtraAspectsVariable()
_non_aspect_inc_style_mask = 0; _non_aspect_inc_style_mask = 0;
_no_tunnel_bridge_style_mask = 0; _no_tunnel_bridge_style_mask = 0;
_always_reserve_through_style_mask = 0;
if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) { if (_settings_game.vehicle.train_braking_model == TBM_REALISTIC) {
for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { 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(_non_aspect_inc_style_mask, i + 1);
SetBit(_no_tunnel_bridge_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; SimpleChecksum64 checksum;
checksum.Update(SimpleHash32(_extra_aspects)); checksum.Update(SimpleHash32(_extra_aspects));
checksum.Update(SimpleHash32(_non_aspect_inc_style_mask)); checksum.Update(SimpleHash32(_non_aspect_inc_style_mask));
checksum.Update(SimpleHash32(_always_reserve_through_style_mask));
if (checksum.state != _aspect_cfg_hash) { if (checksum.state != _aspect_cfg_hash) {
_aspect_cfg_hash = checksum.state; _aspect_cfg_hash = checksum.state;
@ -1539,7 +1554,9 @@ void UpdateExtraAspectsVariable()
bool changed = DetermineExtraAspectsVariable(); bool changed = DetermineExtraAspectsVariable();
if (changed) { if (changed) {
UpdateAllSignalReserveThroughBits();
if (_extra_aspects > 0) UpdateAllSignalAspects(); if (_extra_aspects > 0) UpdateAllSignalAspects();
UpdateAllBlockSignals();
MarkWholeScreenDirty(); MarkWholeScreenDirty();
} }
} }
@ -1548,3 +1565,41 @@ void InitialiseExtraAspectsVariable()
{ {
DetermineExtraAspectsVariable(); 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());
}

@ -22,6 +22,7 @@
extern uint8 _extra_aspects; extern uint8 _extra_aspects;
extern uint64 _aspect_cfg_hash; extern uint64 _aspect_cfg_hash;
extern uint16 _non_aspect_inc_style_mask; extern uint16 _non_aspect_inc_style_mask;
extern uint16 _always_reserve_through_style_mask;
extern uint16 _no_tunnel_bridge_style_mask; extern uint16 _no_tunnel_bridge_style_mask;
extern bool _signal_sprite_oversized; extern bool _signal_sprite_oversized;
@ -192,4 +193,7 @@ inline uint8 GetForwardAspectFollowingTrackAndIncrement(TileIndex tile, Trackdir
return std::min<uint8>(GetForwardAspectFollowingTrack(tile, trackdir) + 1, _extra_aspects + 1); return std::min<uint8>(GetForwardAspectFollowingTrack(tile, trackdir) + 1, _extra_aspects + 1);
} }
void UpdateSignalReserveThroughBit(TileIndex tile, Track track, bool update_signal);
void UpdateAllSignalReserveThroughBits();
#endif /* SIGNAL_FUNC_H */ #endif /* SIGNAL_FUNC_H */

@ -1313,6 +1313,8 @@ bool TraceRestrictRemoveProgramMapping(TraceRestrictRefId ref)
// Found // Found
TraceRestrictProgram *prog = _tracerestrictprogram_pool.Get(iter->second.program_id); 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 // check to see if another mapping needs to be removed as well
// do this before decrementing the refcount // do this before decrementing the refcount
bool remove_other_mapping = prog->refcount == 2 && prog->items.empty(); bool remove_other_mapping = prog->refcount == 2 && prog->items.empty();
@ -1329,14 +1331,25 @@ bool TraceRestrictRemoveProgramMapping(TraceRestrictRefId ref)
if (remove_other_mapping) { if (remove_other_mapping) {
TraceRestrictRemoveProgramMapping(const_cast<const TraceRestrictProgram *>(prog)->GetRefIdsPtr()[0]); TraceRestrictRemoveProgramMapping(const_cast<const TraceRestrictProgram *>(prog)->GetRefIdsPtr()[0]);
} }
if (update_reserve_through) UpdateSignalReserveThroughBit(tile, track, true);
return true; return true;
} else { } else {
return false; 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 (_network_dedicated) return;
if (!((old_actions_used_flags ^ prog->actions_used_flags) & (TRPAUF_RESERVE_THROUGH_ALWAYS | TRPAUF_REVERSE))) 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 // so delete it, as it's redundant
TraceRestrictRemoveProgramMapping(MakeTraceRestrictRefId(tile, track)); TraceRestrictRemoveProgramMapping(MakeTraceRestrictRefId(tile, track));
} else { } else {
TraceRestrictCheckRefreshSignals(prog, tile, old_size, old_actions_used_flags); TraceRestrictCheckRefreshSignals(prog, old_size, old_actions_used_flags);
} }
// update windows // update windows
@ -1821,6 +1834,8 @@ CommandCost CmdProgramSignalTraceRestrictProgMgmt(TileIndex tile, DoCommandFlag
} }
prog->items = source_prog->items; // copy prog->items = source_prog->items; // copy
prog->Validate(); prog->Validate();
TraceRestrictCheckRefreshSignals(prog, 0, static_cast<TraceRestrictProgramActionsUsedFlags>(0));
} }
break; 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->items.insert(prog->items.end(), source_prog->items.begin(), source_prog->items.end()); // append
prog->Validate(); prog->Validate();
TraceRestrictCheckRefreshSignals(prog, tile, old_size, old_actions_used_flags); TraceRestrictCheckRefreshSignals(prog, old_size, old_actions_used_flags);
} }
break; break;
} }

Loading…
Cancel
Save