Add tracerestrict action to set combined normal/shunt signal mode

Add associated conditional to get reservation end tile
This commit is contained in:
Jonathan G Rennison
2022-06-28 01:16:57 +01:00
parent 52f28eb5c1
commit 6a69a5495f
10 changed files with 216 additions and 16 deletions

View File

@@ -77,6 +77,7 @@ enum TraceRestrictWindowWidgets {
TR_WIDGET_VALUE_DROPDOWN,
TR_WIDGET_VALUE_DEST,
TR_WIDGET_VALUE_SIGNAL,
TR_WIDGET_VALUE_TILE,
TR_WIDGET_LEFT_AUX_DROPDOWN,
TR_WIDGET_BLANK_L2,
@@ -120,6 +121,7 @@ enum PanelWidgets {
DPR_VALUE_DROPDOWN,
DPR_VALUE_DEST,
DPR_VALUE_SIGNAL,
DPR_VALUE_TILE,
DPR_BLANK,
// Share
@@ -160,6 +162,7 @@ static const StringID _program_insert_str[] = {
STR_TRACE_RESTRICT_COUNTER_OP,
STR_TRACE_RESTRICT_PF_PENALTY_CONTROL,
STR_TRACE_RESTRICT_SPEED_ADAPTATION_CONTROL,
STR_TRACE_RESTRICT_SIGNAL_MODE_CONTROL,
INVALID_STRING_ID
};
static const uint32 _program_insert_else_hide_mask = 8; ///< disable bitmask for else
@@ -172,6 +175,7 @@ static const uint32 _program_speed_res_hide_mask = 0x800; ///< disable bitm
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 uint32 _program_speed_adapt_hide_mask = 0x8000; ///< disable bitmask for speed adaptation
static const uint32 _program_signal_mode_hide_mask = 0x10000; ///< disable bitmask for signal mode control
static const uint _program_insert_val[] = {
TRIT_COND_UNDEFINED, // if block
TRIT_COND_UNDEFINED | (TRCF_ELSE << 16), // elif block
@@ -189,6 +193,7 @@ static const uint _program_insert_val[] = {
TRIT_COUNTER, // counter operation
TRIT_PF_PENALTY_CONTROL, // penalty control
TRIT_SPEED_ADAPTATION_CONTROL, // speed adaptation control
TRIT_SIGNAL_MODE_CONTROL, // signal mode control
};
/** insert drop down list strings and values */
@@ -422,6 +427,21 @@ static const TraceRestrictDropDownListSet _speed_adaptation_control_value = {
_speed_adaptation_control_value_str, _speed_adaptation_control_value_val,
};
static const StringID _signal_mode_control_value_str[] = {
STR_TRACE_RESTRICT_USE_NORMAL_ASPECT_MODE_SHORT,
STR_TRACE_RESTRICT_USE_SHUNT_ASPECT_MODE_SHORT,
INVALID_STRING_ID
};
static const uint _signal_mode_control_value_val[] = {
TRSMCF_NORMAL_ASPECT,
TRSMCF_SHUNT_ASPECT,
};
/** value drop down list for speed adaptation control types strings and values */
static const TraceRestrictDropDownListSet _signal_mode_control_value = {
_signal_mode_control_value_str, _signal_mode_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
@@ -476,14 +496,15 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
STR_TRACE_RESTRICT_PF_PENALTY,
STR_TRACE_RESTRICT_RESERVE_THROUGH,
STR_TRACE_RESTRICT_LONG_RESERVE,
STR_TRACE_RESTRICT_WAIT_AT_PBS,
STR_TRACE_RESTRICT_WAIT_AT_PBS, // 0x10
STR_TRACE_RESTRICT_SLOT_OP,
STR_TRACE_RESTRICT_REVERSE,
STR_TRACE_RESTRICT_SPEED_RESTRICTION,
STR_TRACE_RESTRICT_NEWS_CONTROL,
STR_TRACE_RESTRICT_NEWS_CONTROL, // 0x100
STR_TRACE_RESTRICT_COUNTER_OP,
STR_TRACE_RESTRICT_PF_PENALTY_CONTROL,
STR_TRACE_RESTRICT_SPEED_ADAPTATION_CONTROL,
STR_TRACE_RESTRICT_SIGNAL_MODE_CONTROL, // 0x1000
INVALID_STRING_ID,
};
static const uint val_action[] = {
@@ -499,6 +520,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
TRIT_COUNTER,
TRIT_PF_PENALTY_CONTROL,
TRIT_SPEED_ADAPTATION_CONTROL,
TRIT_SIGNAL_MODE_CONTROL,
};
static const TraceRestrictDropDownListSet set_action = {
str_action, val_action,
@@ -530,6 +552,7 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
STR_TRACE_RESTRICT_VARIABLE_COUNTER_VALUE,
STR_TRACE_RESTRICT_VARIABLE_TIME_DATE_VALUE,
STR_TRACE_RESTRICT_VARIABLE_RESERVED_TILES_AHEAD,
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_TILE,
STR_TRACE_RESTRICT_VARIABLE_UNDEFINED,
INVALID_STRING_ID,
};
@@ -538,27 +561,28 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
TRIT_COND_MAX_SPEED,
TRIT_COND_CURRENT_ORDER,
TRIT_COND_NEXT_ORDER,
TRIT_COND_LAST_STATION,
TRIT_COND_LAST_STATION, // 0x10
TRIT_COND_CARGO,
TRIT_COND_LOAD_PERCENT,
TRIT_COND_ENTRY_DIRECTION,
TRIT_COND_TRAIN_GROUP,
TRIT_COND_TRAIN_GROUP, // 0x100
TRIT_COND_TRAIN_OWNER,
TRIT_COND_TRAIN_STATUS,
TRIT_COND_PHYS_PROP | (TRPPCAF_WEIGHT << 16),
TRIT_COND_PHYS_PROP | (TRPPCAF_POWER << 16),
TRIT_COND_PHYS_PROP | (TRPPCAF_POWER << 16), // 0x1000
TRIT_COND_PHYS_PROP | (TRPPCAF_MAX_TE << 16),
TRIT_COND_PHYS_RATIO | (TRPPRCAF_POWER_WEIGHT << 16),
TRIT_COND_PHYS_RATIO | (TRPPRCAF_MAX_TE_WEIGHT << 16),
TRIT_COND_CATEGORY | (TRCCAF_ENGINE_CLASS << 16),
TRIT_COND_CATEGORY | (TRCCAF_ENGINE_CLASS << 16), // 0x10000
TRIT_COND_PBS_ENTRY_SIGNAL | (TRPESAF_VEH_POS << 16),
TRIT_COND_PBS_ENTRY_SIGNAL | (TRPESAF_RES_END << 16),
TRIT_COND_TRAIN_IN_SLOT,
TRIT_COND_SLOT_OCCUPANCY | (TRSOCAF_OCCUPANTS << 16),
TRIT_COND_SLOT_OCCUPANCY | (TRSOCAF_OCCUPANTS << 16), // 0x100000
TRIT_COND_SLOT_OCCUPANCY | (TRSOCAF_REMAINING << 16),
TRIT_COND_COUNTER_VALUE,
TRIT_COND_TIME_DATE_VALUE,
TRIT_COND_RESERVED_TILES,
TRIT_COND_RESERVED_TILES, // 0x1000000
TRIT_COND_PBS_ENTRY_SIGNAL | (TRPESAF_RES_END_TILE << 16),
TRIT_COND_UNDEFINED,
};
static const TraceRestrictDropDownListSet set_cond = {
@@ -574,6 +598,10 @@ static const TraceRestrictDropDownListSet *GetTypeDropDownListSet(TraceRestrictG
}
if (is_conditional && _settings_game.vehicle.train_braking_model != TBM_REALISTIC) *hide_mask |= 0x1040000;
if (!is_conditional && !_settings_game.vehicle.train_speed_adaptation) *hide_mask |= 0x800;
if (!(_settings_client.gui.show_adv_tracerestrict_features && _settings_game.vehicle.train_braking_model == TBM_REALISTIC && _signal_style_masks.combined_normal_shunt != 0)) {
*hide_mask |= is_conditional ? 0x2000000 : 0x1000;
}
}
return is_conditional ? &set_cond : &set_action;
}
@@ -1077,6 +1105,28 @@ static uint GetPathfinderPenaltyDropdownIndex(TraceRestrictItem item)
}
}
template <typename F>
void IterateActionsInsideConditional(const TraceRestrictProgram *prog, int index, F handler)
{
size_t instruction_count = prog->GetInstructionCount();
int depth = 1;
for (size_t i = index; i < instruction_count; i++) {
TraceRestrictItem item = prog->items[prog->InstructionOffsetToArrayOffset(i)];
if (IsTraceRestrictConditional(item)) {
if (GetTraceRestrictCondFlags(item) & (TRCF_ELSE | TRCF_OR)) {
/* do nothing */
} else if (GetTraceRestrictType(item) == TRIT_COND_ENDIF) {
depth--;
if (depth == 0) return;
} else {
depth++;
}
} else {
handler(item);
}
}
}
/** Common function for drawing an ordinary conditional instruction */
static void DrawInstructionStringConditionalCommon(TraceRestrictItem item, const TraceRestrictTypePropertySet &properties)
{
@@ -1215,13 +1265,28 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric
_temp_special_strings[0].assign(buf, end);
SetDParam(1, SPECSTR_TEMP_START);
};
auto check_signal_mode_control = [&](bool allowed) {
bool warn = false;
IterateActionsInsideConditional(prog, index, [&](const TraceRestrictItem &item) {
if ((GetTraceRestrictType(item) == TRIT_SIGNAL_MODE_CONTROL) != allowed) warn = true;
});
if (warn) insert_warning(allowed ? STR_TRACE_RESTRICT_WARNING_SIGNAL_MODE_CONTROL_ONLY : STR_TRACE_RESTRICT_WARNING_NO_SIGNAL_MODE_CONTROL);
};
switch (static_cast<TraceRestrictPBSEntrySignalAuxField>(GetTraceRestrictAuxField(item))) {
case TRPESAF_VEH_POS:
SetDParam(1, STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL_LONG);
check_signal_mode_control(false);
break;
case TRPESAF_RES_END:
SetDParam(1, STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_SIGNAL_LONG);
check_signal_mode_control(false);
if (_settings_game.vehicle.train_braking_model != TBM_REALISTIC) insert_warning(STR_TRACE_RESTRICT_WARNING_REQUIRES_REALISTIC_BRAKING);
break;
case TRPESAF_RES_END_TILE:
SetDParam(1, STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_TILE_LONG);
check_signal_mode_control(true);
if (_settings_game.vehicle.train_braking_model != TBM_REALISTIC) insert_warning(STR_TRACE_RESTRICT_WARNING_REQUIRES_REALISTIC_BRAKING);
break;
@@ -1603,6 +1668,22 @@ static void DrawInstructionString(const TraceRestrictProgram *prog, TraceRestric
}
break;
case TRIT_SIGNAL_MODE_CONTROL:
switch (static_cast<TraceRestrictSignalModeControlField>(GetTraceRestrictValue(item))) {
case TRSMCF_NORMAL_ASPECT:
instruction_string = STR_TRACE_RESTRICT_USE_NORMAL_ASPECT_MODE;
break;
case TRSMCF_SHUNT_ASPECT:
instruction_string = STR_TRACE_RESTRICT_USE_SHUNT_ASPECT_MODE;
break;
default:
NOT_REACHED();
break;
}
break;
default:
NOT_REACHED();
break;
@@ -1744,6 +1825,9 @@ public:
if (!_settings_client.gui.show_adv_tracerestrict_features || !_settings_game.vehicle.train_speed_adaptation) {
hidden |= _program_speed_adapt_hide_mask;
}
if (!(_settings_client.gui.show_adv_tracerestrict_features && _settings_game.vehicle.train_braking_model == TBM_REALISTIC && _signal_style_masks.combined_normal_shunt != 0)) {
hidden |= _program_signal_mode_hide_mask;
}
this->ShowDropDownListWithValue(&_program_insert, 0, true, TR_WIDGET_INSERT, disabled, hidden, 0);
break;
@@ -1940,6 +2024,10 @@ public:
this->ShowDropDownListWithValue(&_speed_adaptation_control_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, 0, 0);
break;
case TRVT_SIGNAL_MODE_CONTROL:
this->ShowDropDownListWithValue(&_signal_mode_control_value, GetTraceRestrictValue(item), false, TR_WIDGET_VALUE_DROPDOWN, 0, 0, 0);
break;
default:
break;
}
@@ -1984,6 +2072,11 @@ public:
break;
}
case TR_WIDGET_VALUE_TILE: {
SetObjectToPlaceAction(widget, SPR_CURSOR_MOUSE);
break;
}
case TR_WIDGET_GOTO_SIGNAL: {
ScrollMainWindowToTile(this->tile);
this->UpdateButtonState();
@@ -2194,6 +2287,10 @@ public:
OnPlaceObjectSignalTileValue(pt, tile, widget, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
break;
case TR_WIDGET_VALUE_TILE:
OnPlaceObjectTileValue(pt, tile, widget, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
break;
default:
NOT_REACHED();
break;
@@ -2339,6 +2436,17 @@ public:
TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_DUAL_ITEM, this->selected_instruction - 1, tile, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
}
/**
* Common OnPlaceObject handler for instruction value modification actions which involve selecting a tile value
*/
void OnPlaceObjectTileValue(Point pt, TileIndex tile, int widget, int error_message)
{
TraceRestrictItem item = GetSelected();
if (GetTraceRestrictTypeProperties(item).value_type != TRVT_TILE_INDEX) return;
TraceRestrictDoCommandP(this->tile, this->track, TRDCT_MODIFY_DUAL_ITEM, this->selected_instruction - 1, tile, STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM);
}
virtual void OnPlaceObjectAbort() override
{
this->RaiseButtons();
@@ -2648,6 +2756,7 @@ private:
this->RaiseWidget(TR_WIDGET_VALUE_DROPDOWN);
this->RaiseWidget(TR_WIDGET_VALUE_DEST);
this->RaiseWidget(TR_WIDGET_VALUE_SIGNAL);
this->RaiseWidget(TR_WIDGET_VALUE_TILE);
this->RaiseWidget(TR_WIDGET_LEFT_AUX_DROPDOWN);
NWidgetStacked *left_2_sel = this->GetWidget<NWidgetStacked>(TR_WIDGET_SEL_TOP_LEFT_2);
@@ -2669,6 +2778,7 @@ private:
this->DisableWidget(TR_WIDGET_VALUE_DROPDOWN);
this->DisableWidget(TR_WIDGET_VALUE_DEST);
this->DisableWidget(TR_WIDGET_VALUE_SIGNAL);
this->DisableWidget(TR_WIDGET_VALUE_TILE);
this->DisableWidget(TR_WIDGET_LEFT_AUX_DROPDOWN);
this->DisableWidget(TR_WIDGET_INSERT);
@@ -2852,8 +2962,13 @@ private:
break;
case TRVT_TILE_INDEX:
right_sel->SetDisplayedPlane(DPR_VALUE_SIGNAL);
this->EnableWidget(TR_WIDGET_VALUE_SIGNAL);
if (GetTraceRestrictType(item) == TRIT_COND_PBS_ENTRY_SIGNAL && GetTraceRestrictAuxField(item) == TRPESAF_RES_END_TILE) {
right_sel->SetDisplayedPlane(DPR_VALUE_TILE);
this->EnableWidget(TR_WIDGET_VALUE_TILE);
} else {
right_sel->SetDisplayedPlane(DPR_VALUE_SIGNAL);
this->EnableWidget(TR_WIDGET_VALUE_SIGNAL);
}
break;
case TRVT_PF_PENALTY:
@@ -3047,6 +3162,13 @@ private:
GetDropDownStringByValue(&_speed_adaptation_control_value, GetTraceRestrictValue(item));
break;
case TRVT_SIGNAL_MODE_CONTROL:
right_sel->SetDisplayedPlane(DPR_VALUE_DROPDOWN);
this->EnableWidget(TR_WIDGET_VALUE_DROPDOWN);
this->GetWidget<NWidgetCore>(TR_WIDGET_VALUE_DROPDOWN)->widget_data =
GetDropDownStringByValue(&_signal_mode_control_value, GetTraceRestrictValue(item));
break;
default:
break;
}
@@ -3228,6 +3350,8 @@ static const NWidgetPart _nested_program_widgets[] = {
SetDataTip(STR_TRACE_RESTRICT_SELECT_TARGET, STR_TRACE_RESTRICT_SELECT_TARGET), SetResize(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_VALUE_SIGNAL), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_TRACE_RESTRICT_SELECT_SIGNAL, STR_TRACE_RESTRICT_SELECT_SIGNAL), SetResize(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_VALUE_TILE), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_TRACE_RESTRICT_SELECT_TILE, STR_TRACE_RESTRICT_SELECT_TILE), SetResize(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_GREY, TR_WIDGET_BLANK_R), SetMinimalSize(124, 12), SetFill(1, 0),
SetDataTip(STR_EMPTY, STR_NULL), SetResize(1, 0),
EndContainer(),