Add tracerestrict action: No PBS signal back PF penalty

This commit is contained in:
Jonathan G Rennison
2021-05-25 18:50:36 +01:00
parent 112b235b71
commit 0579c8755c
7 changed files with 109 additions and 6 deletions

View File

@@ -2957,6 +2957,7 @@ STR_TRACE_RESTRICT_REVERSE :Reverse
STR_TRACE_RESTRICT_SPEED_RESTRICTION :Speed restriction
STR_TRACE_RESTRICT_NEWS_CONTROL :News control
STR_TRACE_RESTRICT_COUNTER_OP :Counter operation
STR_TRACE_RESTRICT_PF_PENALTY_CONTROL :Penalty config
STR_TRACE_RESTRICT_SLOT_ACQUIRE_WAIT :Acquire or wait
STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE :Try to acquire
STR_TRACE_RESTRICT_SLOT_RELEASE_FRONT :Release (front)
@@ -3000,6 +3001,10 @@ STR_TRACE_RESTRICT_TRAIN_NOT_STUCK :Train is not st
STR_TRACE_RESTRICT_TRAIN_NOT_STUCK_CANCEL :Cancel train is not stuck, do not show news reports about waiting at this PBS signal
STR_TRACE_RESTRICT_TRAIN_NOT_STUCK_SHORT :Train is not stuck...
STR_TRACE_RESTRICT_TRAIN_NOT_STUCK_CANCEL_SHORT :Cancel train is not stuck...
STR_TRACE_RESTRICT_NO_PBS_BACK_PENALTY :Do not apply the penalty for passing this PBS signal from the back
STR_TRACE_RESTRICT_NO_PBS_BACK_PENALTY_CANCEL :Cancel do not apply the penalty for passing this PBS signal from the back
STR_TRACE_RESTRICT_NO_PBS_BACK_PENALTY_SHORT :No PBS back penalty
STR_TRACE_RESTRICT_NO_PBS_BACK_PENALTY_CANCEL_SHORT :Cancel no PBS back penalty
STR_TRACE_RESTRICT_TIME_MINUTE :current minute (0 - 59)
STR_TRACE_RESTRICT_TIME_HOUR :current hour (0 - 23)
STR_TRACE_RESTRICT_TIME_HOUR_MINUTE :current hour and minute (0 - 2359)

View File

@@ -266,7 +266,7 @@ private:
}
// returns true if dead end bit has been set
inline bool ExecuteTraceRestrict(Node& n, TileIndex tile, Trackdir trackdir, int& cost, TraceRestrictProgramResult &out, bool *is_res_through)
inline bool ExecuteTraceRestrict(Node& n, TileIndex tile, Trackdir trackdir, int& cost, TraceRestrictProgramResult &out, bool *is_res_through, bool *no_pbs_back_penalty)
{
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(tile, TrackdirToTrack(trackdir));
TraceRestrictProgramActionsUsedFlags flags_to_check = TRPAUF_PF;
@@ -274,6 +274,10 @@ private:
*is_res_through = false;
flags_to_check |= TRPAUF_RESERVE_THROUGH;
}
if (no_pbs_back_penalty != nullptr) {
*no_pbs_back_penalty = false;
flags_to_check |= TRPAUF_NO_PBS_BACK_PENALTY;
}
if (GetSignalType(tile, TrackdirToTrack(trackdir)) == SIGTYPE_PBS && !HasSignalOnTrackdir(tile, trackdir)) {
flags_to_check |= TRPAUF_REVERSE;
}
@@ -282,6 +286,9 @@ private:
if (out.flags & TRPRF_RESERVE_THROUGH && is_res_through != nullptr) {
*is_res_through = true;
}
if (out.flags & TRPRF_NO_PBS_BACK_PENALTY && no_pbs_back_penalty != nullptr) {
*no_pbs_back_penalty = true;
}
if (out.flags & TRPRF_DENY) {
n.m_segment->m_end_segment_reason |= ESRB_DEAD_END;
return true;
@@ -358,7 +365,7 @@ public:
bool is_reserve_through = false;
if (ShouldCheckTraceRestrict(n, tile)) {
TraceRestrictProgramResult out;
if (ExecuteTraceRestrict(n, tile, trackdir, cost, out, &is_reserve_through)) {
if (ExecuteTraceRestrict(n, tile, trackdir, cost, out, &is_reserve_through, nullptr)) {
return -1;
}
if (is_reserve_through) n.m_num_signals_res_through_passed++;
@@ -374,14 +381,18 @@ public:
}
if (has_signal_against && IsPbsSignal(GetSignalType(tile, TrackdirToTrack(trackdir)))) {
cost += n.m_num_signals_passed < Yapf().PfGetSettings().rail_look_ahead_max_signals ? Yapf().PfGetSettings().rail_pbs_signal_back_penalty : 0;
bool no_add_cost = false;
if (ShouldCheckTraceRestrict(n, tile)) {
TraceRestrictProgramResult out;
if (ExecuteTraceRestrict(n, tile, trackdir, cost, out, nullptr)) {
if (ExecuteTraceRestrict(n, tile, trackdir, cost, out, nullptr, &no_add_cost)) {
return -1;
}
}
if (!no_add_cost) {
cost += n.m_num_signals_passed < Yapf().PfGetSettings().rail_look_ahead_max_signals ? Yapf().PfGetSettings().rail_pbs_signal_back_penalty : 0;
}
}
}
}

View File

@@ -78,6 +78,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_TRACE_RESTRICT_TIMEDATE,XSCF_NULL, 1, 1, "tracerestrict_timedate", nullptr, nullptr, nullptr },
{ XSLFI_TRACE_RESTRICT_BRKCND, XSCF_NULL, 2, 2, "tracerestrict_braking_cond",nullptr, nullptr, nullptr },
{ XSLFI_TRACE_RESTRICT_CTGRYCND,XSCF_NULL, 1, 1, "tracerestrict_ctgry_cond", nullptr, nullptr, nullptr },
{ XSLFI_TRACE_RESTRICT_PENCTRL, XSCF_NULL, 1, 1, "tracerestrict_pfpenctrl", nullptr, nullptr, nullptr },
{ XSLFI_PROG_SIGS, XSCF_NULL, 2, 2, "programmable_signals", nullptr, nullptr, "SPRG" },
{ XSLFI_ADJACENT_CROSSINGS, XSCF_NULL, 1, 1, "adjacent_crossings", nullptr, nullptr, nullptr },
{ XSLFI_SAFER_CROSSINGS, XSCF_NULL, 1, 1, "safer_crossings", nullptr, nullptr, nullptr },

View File

@@ -32,6 +32,7 @@ enum SlXvFeatureIndex {
XSLFI_TRACE_RESTRICT_TIMEDATE, ///< Trace restrict: time/date
XSLFI_TRACE_RESTRICT_BRKCND, ///< Trace restrict: realistic braking related conditionals
XSLFI_TRACE_RESTRICT_CTGRYCND, ///< Trace restrict: category conditionals
XSLFI_TRACE_RESTRICT_PENCTRL, ///< Trace restrict: PF penalty control
XSLFI_PROG_SIGS, ///< programmable pre-signals patch
XSLFI_ADJACENT_CROSSINGS, ///< Adjacent level crossings closure patch
XSLFI_SAFER_CROSSINGS, ///< Safer level crossings

View File

@@ -743,6 +743,22 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
break;
}
case TRIT_PF_PENALTY_CONTROL:
switch (static_cast<TraceRestrictPfPenaltyControlField>(GetTraceRestrictValue(item))) {
case TRPPCF_NO_PBS_BACK_PENALTY:
out.flags |= TRPRF_NO_PBS_BACK_PENALTY;
break;
case TRPPCF_CANCEL_NO_PBS_BACK_PENALTY:
out.flags &= ~TRPRF_NO_PBS_BACK_PENALTY;
break;
default:
NOT_REACHED();
break;
}
break;
default:
NOT_REACHED();
}
@@ -930,6 +946,10 @@ CommandCost TraceRestrictProgram::Validate(const std::vector<TraceRestrictItem>
actions_used_flags |= TRPAUF_CHANGE_COUNTER;
break;
case TRIT_PF_PENALTY_CONTROL:
actions_used_flags |= TRPAUF_NO_PBS_BACK_PENALTY;
break;
default:
return_cmd_error(STR_TRACE_RESTRICT_ERROR_VALIDATE_UNKNOWN_INSTRUCTION);
}
@@ -995,6 +1015,7 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp
case TRVT_NEWS_CONTROL:
case TRVT_TIME_DATE_INT:
case TRVT_ENGINE_CLASS:
case TRVT_PF_PENALTY_CONTROL:
SetTraceRestrictValue(item, 0);
if (!IsTraceRestrictTypeAuxSubtype(GetTraceRestrictType(item))) {
SetTraceRestrictAuxField(item, 0);

View File

@@ -159,6 +159,7 @@ enum TraceRestrictItemType {
TRIT_SPEED_RESTRICTION = 49, ///< Speed restriction
TRIT_NEWS_CONTROL = 50, ///< News control
TRIT_COUNTER = 51, ///< Change counter value
TRIT_PF_PENALTY_CONTROL = 52, ///< Control base signal penalties
/* space up to 63 */
};
@@ -280,6 +281,14 @@ enum TraceRestrictNewsControlField {
TRNCF_CANCEL_TRAIN_NOT_STUCK = 1, ///< Cancel train is not stuck
};
/**
* TraceRestrictItem value field, for TRIT_PF_PENALTY_CONTROL
*/
enum TraceRestrictPfPenaltyControlField {
TRPPCF_NO_PBS_BACK_PENALTY = 0, ///< Do not apply PBS signal back penalty
TRPPCF_CANCEL_NO_PBS_BACK_PENALTY = 1, ///< Cancel do not apply PBS signal back penalty
};
/**
* TraceRestrictItem value field, for TRIT_COND_TRAIN_STATUS
*/
@@ -372,6 +381,7 @@ enum TraceRestrictProgramResultFlags {
TRPRF_REVERSE = 1 << 5, ///< Reverse behind signal
TRPRF_SPEED_RETRICTION_SET = 1 << 6, ///< Speed restriction field set
TRPRF_TRAIN_NOT_STUCK = 1 << 7, ///< Train is not stuck
TRPRF_NO_PBS_BACK_PENALTY = 1 << 8, ///< Do not apply PBS back penalty
};
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramResultFlags)
@@ -392,6 +402,7 @@ enum TraceRestrictProgramActionsUsedFlags {
TRPAUF_SPEED_RESTRICTION = 1 << 10, ///< Speed restriction
TRPAUF_TRAIN_NOT_STUCK = 1 << 11, ///< Train is not stuck
TRPAUF_CHANGE_COUNTER = 1 << 12, ///< Change counter value is present
TRPAUF_NO_PBS_BACK_PENALTY = 1 << 13, ///< No PBS back penalty is present
};
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramActionsUsedFlags)
@@ -631,6 +642,7 @@ enum TraceRestrictValueType {
TRVT_COUNTER_INDEX_INT = 44,///< takes a TraceRestrictCounterID, and an integer in the next item slot
TRVT_TIME_DATE_INT = 45,///< takes a TraceRestrictTimeDateValueField, and an integer in the next item slot
TRVT_ENGINE_CLASS = 46,///< takes a EngineClass
TRVT_PF_PENALTY_CONTROL = 47,///< takes a TraceRestrictPfPenaltyControlField
};
/**
@@ -806,6 +818,8 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR
out.value_type = TRVT_NEWS_CONTROL;
} else if (GetTraceRestrictType(item) == TRIT_COUNTER) {
out.value_type = TRVT_COUNTER_INDEX_INT;
} else if (GetTraceRestrictType(item) == TRIT_PF_PENALTY_CONTROL) {
out.value_type = TRVT_PF_PENALTY_CONTROL;
} else {
out.value_type = TRVT_NONE;
}

View File

@@ -157,6 +157,7 @@ static const StringID _program_insert_str[] = {
STR_TRACE_RESTRICT_SPEED_RESTRICTION,
STR_TRACE_RESTRICT_NEWS_CONTROL,
STR_TRACE_RESTRICT_COUNTER_OP,
STR_TRACE_RESTRICT_PF_PENALTY_CONTROL,
INVALID_STRING_ID
};
static const uint32 _program_insert_else_hide_mask = 8; ///< disable bitmask for else
@@ -167,6 +168,7 @@ static const uint32 _program_slot_hide_mask = 0x200; ///< disable bitm
static const uint32 _program_reverse_hide_mask = 0x400; ///< disable bitmask for reverse
static const uint32 _program_speed_res_hide_mask = 0x800; ///< disable bitmask for speed restriction
static const uint32 _program_counter_hide_mask = 0x2000; ///< disable bitmask for counter
static const uint32 _program_penalty_adj_hide_mask = 0x4000; ///< disable bitmask for penalty adjust
static const uint _program_insert_val[] = {
TRIT_COND_UNDEFINED, // if block
TRIT_COND_UNDEFINED | (TRCF_ELSE << 16), // elif block
@@ -182,6 +184,7 @@ static const uint _program_insert_val[] = {
TRIT_SPEED_RESTRICTION, // speed restriction
TRIT_NEWS_CONTROL, // news control
TRIT_COUNTER, // counter operation
TRIT_PF_PENALTY_CONTROL, // penalty control
};
/** insert drop down list strings and values */
@@ -377,6 +380,21 @@ static const TraceRestrictDropDownListSet _engine_class_value = {
_engine_class_value_str, _engine_class_value_val,
};
static const StringID _pf_penalty_control_value_str[] = {
STR_TRACE_RESTRICT_NO_PBS_BACK_PENALTY_SHORT,
STR_TRACE_RESTRICT_NO_PBS_BACK_PENALTY_CANCEL_SHORT,
INVALID_STRING_ID
};
static const uint _pf_penalty_control_value_val[] = {
TRPPCF_NO_PBS_BACK_PENALTY,
TRPPCF_CANCEL_NO_PBS_BACK_PENALTY,
};
/** value drop down list for PF penalty control types strings and values */
static const TraceRestrictDropDownListSet _pf_penalty_control_value = {
_pf_penalty_control_value_str, _pf_penalty_control_value_val,
};
/**
* Get index of @p value in @p list_set
* if @p value is not present, assert if @p missing_ok is false, otherwise return -1
@@ -437,6 +455,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
STR_TRACE_RESTRICT_SPEED_RESTRICTION,
STR_TRACE_RESTRICT_NEWS_CONTROL,
STR_TRACE_RESTRICT_COUNTER_OP,
STR_TRACE_RESTRICT_PF_PENALTY_CONTROL,
INVALID_STRING_ID,
};
static const uint val_action[] = {
@@ -450,6 +469,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
TRIT_SPEED_RESTRICTION,
TRIT_NEWS_CONTROL,
TRIT_COUNTER,
TRIT_PF_PENALTY_CONTROL,
};
static const TraceRestrictDropDownListSet set_action = {
str_action, val_action,
@@ -521,7 +541,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
if (_settings_client.gui.show_adv_tracerestrict_features) {
*hide_mask = 0;
} else {
*hide_mask = is_conditional ? 0x1FE0000 : 0x2F0;
*hide_mask = is_conditional ? 0x1FE0000 : 0x6F0;
}
if (is_conditional && !_settings_game.game_time.time_in_minutes) *hide_mask |= 0x800000;
if (is_conditional && _settings_game.vehicle.train_braking_model != TBM_REALISTIC) *hide_mask |= 0x1040000;
@@ -1473,6 +1493,22 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric
break;
}
case TRIT_PF_PENALTY_CONTROL:
switch (static_cast<TraceRestrictPfPenaltyControlField>(GetTraceRestrictValue(item))) {
case TRPPCF_NO_PBS_BACK_PENALTY:
instruction_string = STR_TRACE_RESTRICT_NO_PBS_BACK_PENALTY;
break;
case TRPPCF_CANCEL_NO_PBS_BACK_PENALTY:
instruction_string = STR_TRACE_RESTRICT_NO_PBS_BACK_PENALTY_CANCEL;
break;
default:
NOT_REACHED();
break;
}
break;
default:
NOT_REACHED();
break;
@@ -1596,7 +1632,10 @@ public:
if (ElseIfInsertionDryRun(false)) disabled &= ~_program_insert_or_if_hide_mask;
}
}
if (!_settings_client.gui.show_adv_tracerestrict_features) hidden |= _program_slot_hide_mask | _program_wait_pbs_hide_mask | _program_reverse_hide_mask | _program_speed_res_hide_mask | _program_counter_hide_mask;
if (!_settings_client.gui.show_adv_tracerestrict_features) {
hidden |= _program_slot_hide_mask | _program_wait_pbs_hide_mask | _program_reverse_hide_mask |
_program_speed_res_hide_mask | _program_counter_hide_mask | _program_penalty_adj_hide_mask;
}
this->ShowDropDownListWithValue(&_program_insert, 0, true, TR_WIDGET_INSERT, disabled, hidden, 0);
break;
@@ -1785,6 +1824,10 @@ public:
this->ShowDropDownListWithValue(&_engine_class_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, 0, 0);
break;
case TRVT_PF_PENALTY_CONTROL:
this->ShowDropDownListWithValue(&_pf_penalty_control_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, 0, 0);
break;
default:
break;
}
@@ -2851,6 +2894,13 @@ private:
GetDropDownStringByValue(&_engine_class_value, GetTraceRestrictValue(item));
break;
case TRVT_PF_PENALTY_CONTROL:
right_sel->SetDisplayedPlane(DPR_VALUE_DROPDOWN);
this->EnableWidget(TR_WIDGET_VALUE_DROPDOWN);
this->GetWidget<NWidgetCore>(TR_WIDGET_VALUE_DROPDOWN)->widget_data =
GetDropDownStringByValue(&_pf_penalty_control_value, GetTraceRestrictValue(item));
break;
default:
break;
}