Add tracerestrict action to set combined normal/shunt signal mode

Add associated conditional to get reservation end tile
pull/407/head
Jonathan G Rennison 2 years ago
parent 52f28eb5c1
commit 6a69a5495f

@ -3242,6 +3242,8 @@ STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL :PBS entry signa
STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL_LONG :entered signal of PBS block
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_SIGNAL :PBS end signal
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_SIGNAL_LONG :signal at current end of PBS reservation
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_TILE :PBS reservation end tile
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_TILE_LONG :tile at end of PBS reservation from this signal
STR_TRACE_RESTRICT_VARIABLE_TRAIN_GROUP :train group
STR_TRACE_RESTRICT_VARIABLE_TRAIN_SLOT :train in slot
STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY :slot occupancy
@ -3330,6 +3332,7 @@ 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_SPEED_ADAPTATION_CONTROL :Speed adap. control
STR_TRACE_RESTRICT_SIGNAL_MODE_CONTROL :Signal mode control
STR_TRACE_RESTRICT_SLOT_ACQUIRE_WAIT :Acquire or wait
STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE :Try to acquire
STR_TRACE_RESTRICT_SLOT_TRY_ACQUIRE_ON_RES :Try to acquire (on reserve)
@ -3384,6 +3387,10 @@ STR_TRACE_RESTRICT_MAKE_TRAIN_SPEED_ADAPTATION_EXEMPT :Make train exem
STR_TRACE_RESTRICT_REMOVE_TRAIN_SPEED_ADAPTATION_EXEMPT :Remove train exemption from automatic speed adaptation
STR_TRACE_RESTRICT_MAKE_TRAIN_SPEED_ADAPTATION_EXEMPT_SHORT :Make exempt
STR_TRACE_RESTRICT_REMOVE_TRAIN_SPEED_ADAPTATION_EXEMPT_SHORT :Remove exemption
STR_TRACE_RESTRICT_USE_NORMAL_ASPECT_MODE :Use normal signal aspect (combined normal/shunt aspect signal)
STR_TRACE_RESTRICT_USE_SHUNT_ASPECT_MODE :Use shunt signal aspect (combined normal/shunt aspect signal)
STR_TRACE_RESTRICT_USE_NORMAL_ASPECT_MODE_SHORT :Use normal signal aspect
STR_TRACE_RESTRICT_USE_SHUNT_ASPECT_MODE_SHORT :Use shunt signal aspect
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)
@ -3451,6 +3458,7 @@ STR_TRACE_RESTRICT_SHARE :{BLACK}Share
STR_TRACE_RESTRICT_UNSHARE :{BLACK}Unshare
STR_TRACE_RESTRICT_SELECT_TARGET :{BLACK}Select Target
STR_TRACE_RESTRICT_SELECT_SIGNAL :{BLACK}Select Signal
STR_TRACE_RESTRICT_SELECT_TILE :{BLACK}Select Tile
STR_TRACE_RESTRICT_INSERT_TOOLTIP :{BLACK}Insert an instruction
STR_TRACE_RESTRICT_REMOVE_TOOLTIP :{BLACK}Remove the selected instruction{}Ctrl+Click to remove the selected conditional instruction but retain its contents
STR_TRACE_RESTRICT_RESET_TOOLTIP :{BLACK}Reset the current signal (without affecting shared programs)
@ -3461,6 +3469,8 @@ STR_TRACE_RESTRICT_SIGNAL_GUI_TOOLTIP :{BLACK}Routefin
STR_TRACE_RESTRICT_INSTRUCTION_LIST_TOOLTIP :{BLACK}Click an instruction to select it{}Ctrl+Click to scroll to the instruction's target (if any)
STR_TRACE_RESTRICT_HIGHLIGHT_TOOLTIP :{BLACK}Toggle highlighting all signals sharing this program
STR_TRACE_RESTRICT_WARNING_REQUIRES_REALISTIC_BRAKING :{STRING} {PUSH_COLOUR}{RED}(requires realistic braking){POP_COLOUR}
STR_TRACE_RESTRICT_WARNING_SIGNAL_MODE_CONTROL_ONLY :{STRING} {PUSH_COLOUR}{RED}(only for signal mode control actions){POP_COLOUR}
STR_TRACE_RESTRICT_WARNING_NO_SIGNAL_MODE_CONTROL :{STRING} {PUSH_COLOUR}{RED}(not for signal mode control actions){POP_COLOUR}
STR_TRACE_RESTRICT_ERROR_CAN_T_INSERT_ITEM :{WHITE}Can't insert instruction
STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM :{WHITE}Can't modify instruction
STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ITEM :{WHITE}Can't remove instruction

@ -6025,7 +6025,6 @@ STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL :Sinal de entrad
STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL_LONG :entrou nun sinal de entrada a cantón
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_SIGNAL :Sinal de saída de ruta
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_SIGNAL_LONG :sinal no final da reserva actual de ruta
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_SIGNAL_LONG_WARN :sinal no final da reserva actual de ruta {PUSH_COLOUR}{RED}(require freo realista){POP_COLOUR}
STR_TRACE_RESTRICT_VARIABLE_TRAIN_GROUP :o grupo de tren
STR_TRACE_RESTRICT_VARIABLE_TRAIN_SLOT :tren no slot
STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY :ocupación de slots
@ -6237,6 +6236,7 @@ STR_TRACE_RESTRICT_SELECT_TARGET :{BLACK}Seleccio
STR_TRACE_RESTRICT_SELECT_SIGNAL :{BLACK}Seleccionar sinal
STR_TRACE_RESTRICT_SIGNAL_GUI_TOOLTIP :{BLACK}Restrición de busca de ruta
STR_TRACE_RESTRICT_INSTRUCTION_LIST_TOOLTIP :{BLACK}Fai click nunha instrución para seleccionala{}Ctrl+Click para desplazarte ata o obxectivo da instrución(se o hai)
STR_TRACE_RESTRICT_WARNING_REQUIRES_REALISTIC_BRAKING :{STRING} {PUSH_COLOUR}{RED}(require freo realista){POP_COLOUR}
STR_TRACE_RESTRICT_ERROR_CAN_T_INSERT_ITEM :{WHITE}Non se pode insertar a instrución
STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM :{WHITE}Non se pode modificar a instrución
STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ITEM :{WHITE}Non se pode eliminar a instrución

@ -3243,7 +3243,6 @@ STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL :경로 신호
STR_TRACE_RESTRICT_VARIABLE_PBS_ENTRY_SIGNAL_LONG :통과한 경로 신호기
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_SIGNAL :끝 경로 신호기
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_SIGNAL_LONG :현재 예약된 경로의 끝에 있는 신호기
STR_TRACE_RESTRICT_VARIABLE_PBS_RES_END_SIGNAL_LONG_WARN :현재 예약된 경로의 끝에 있는 신호기 {PUSH_COLOUR}{RED}(현실적인 감속을 켜야 함){POP_COLOUR}
STR_TRACE_RESTRICT_VARIABLE_TRAIN_GROUP :열차 그룹
STR_TRACE_RESTRICT_VARIABLE_TRAIN_SLOT :열차 슬롯
STR_TRACE_RESTRICT_VARIABLE_SLOT_OCCUPANCY :슬롯 사용량
@ -3462,6 +3461,7 @@ STR_TRACE_RESTRICT_UNSHARE_TOOLTIP :{BLACK}다른
STR_TRACE_RESTRICT_SIGNAL_GUI_TOOLTIP :{BLACK}경로 탐색 제한
STR_TRACE_RESTRICT_INSTRUCTION_LIST_TOOLTIP :{BLACK}선택하려면 구문을 클릭하십시오.{}구문에서 지정된 장소가 있다면, 지정된 장소로 가려면 구문을 Ctrl+클릭하십시오.
STR_TRACE_RESTRICT_HIGHLIGHT_TOOLTIP :{BLACK}이 프로그램을 공유하는 모든 신호기를 선택하여 표시합니다.
STR_TRACE_RESTRICT_WARNING_REQUIRES_REALISTIC_BRAKING :{STRING} {PUSH_COLOUR}{RED}(현실적인 감속을 켜야 함){POP_COLOUR}
STR_TRACE_RESTRICT_ERROR_CAN_T_INSERT_ITEM :{WHITE}구문을 삽입할 수 없습니다.
STR_TRACE_RESTRICT_ERROR_CAN_T_MODIFY_ITEM :{WHITE}구문을 수정할 수 없습니다.
STR_TRACE_RESTRICT_ERROR_CAN_T_REMOVE_ITEM :{WHITE}구문을 제거할 수 없습니다.

@ -189,6 +189,8 @@ private:
*/
static TileIndex TraceRestrictPreviousSignalCallback(const Train *v, const void *node_ptr, TraceRestrictPBSEntrySignalAuxField mode)
{
if (mode == TRPESAF_RES_END_TILE) return INVALID_TILE;
const Node *node = static_cast<const Node *>(node_ptr);
for (;;) {
TileIndex last_signal_tile = node->m_last_non_reserve_through_signal_tile;

@ -1247,6 +1247,8 @@ CommandCost CheckTrainInTunnelBridgePreventsTrackModification(TileIndex start, T
*/
TileIndex VehiclePosTraceRestrictPreviousSignalCallback(const Train *v, const void *, TraceRestrictPBSEntrySignalAuxField mode)
{
if (mode == TRPESAF_RES_END_TILE) return INVALID_TILE;
TileIndex tile;
Trackdir trackdir;

@ -78,7 +78,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_TRACE_RESTRICT_NEWSCTRL,XSCF_NULL, 1, 1, "tracerestrict_newsctrl", nullptr, nullptr, nullptr },
{ XSLFI_TRACE_RESTRICT_COUNTER, XSCF_NULL, 1, 1, "tracerestrict_counter", nullptr, nullptr, "TRRC" },
{ XSLFI_TRACE_RESTRICT_TIMEDATE,XSCF_NULL, 2, 2, "tracerestrict_timedate", nullptr, nullptr, nullptr },
{ XSLFI_TRACE_RESTRICT_BRKCND, XSCF_NULL, 2, 2, "tracerestrict_braking_cond",nullptr, nullptr, nullptr },
{ XSLFI_TRACE_RESTRICT_BRKCND, XSCF_NULL, 3, 3, "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_TRACE_RESTRICT_TUNBRIDGE,XSCF_NULL, 1, 1, "tracerestrict_sigtunbridge",nullptr, nullptr, nullptr },

@ -1514,6 +1514,29 @@ void DetermineCombineNormalShuntModeWithLookahead(Train *v, TileIndex tile, Trac
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 }));
if (IsRestrictedSignal(tile)) {
const TraceRestrictProgram *prog = GetExistingTraceRestrictProgram(tile, TrackdirToTrack(trackdir));
if (prog && prog->actions_used_flags & TRPAUF_CMB_SIGNAL_MODE_CTRL) {
TraceRestrictProgramResult out;
TraceRestrictProgramInput input(tile, trackdir, [](const Train *v, const void *, TraceRestrictPBSEntrySignalAuxField mode) {
if (mode == TRPESAF_RES_END_TILE) {
return v->lookahead->reservation_end_tile;
} else {
return INVALID_TILE;
}
}, nullptr);
prog->Execute(v, input, out);
if (out.flags & TRPRF_SIGNAL_MODE_NORMAL) {
return;
}
if (out.flags & TRPRF_SIGNAL_MODE_SHUNT) {
SetSignalAspect(tile, TrackdirToTrack(trackdir), 1);
SetBit(item.data_aux, TRSLAI_COMBINED_SHUNT);
return;
}
}
}
for (size_t j = i + 1; j < count; j++) {
const TrainReservationLookAheadItem &ahead = v->lookahead->items[j];
if (ahead.type == TRLIT_SIGNAL) {

@ -248,7 +248,7 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
condstack.clear();
byte have_previous_signal = 0;
TileIndex previous_signal_tile[2];
TileIndex previous_signal_tile[3];
size_t size = this->items.size();
for (size_t i = 0; i < size; i++) {
@ -358,7 +358,7 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
// TRIT_COND_PBS_ENTRY_SIGNAL value type uses the next slot
i++;
TraceRestrictPBSEntrySignalAuxField mode = static_cast<TraceRestrictPBSEntrySignalAuxField>(GetTraceRestrictAuxField(item));
assert(mode == TRPESAF_VEH_POS || mode == TRPESAF_RES_END);
assert(mode == TRPESAF_VEH_POS || mode == TRPESAF_RES_END || mode == TRPESAF_RES_END_TILE);
uint32_t signal_tile = this->items[i];
if (!HasBit(have_previous_signal, mode)) {
if (input.previous_signal_callback) {
@ -804,6 +804,24 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
}
break;
case TRIT_SIGNAL_MODE_CONTROL:
switch (static_cast<TraceRestrictSignalModeControlField>(GetTraceRestrictValue(item))) {
case TRSMCF_NORMAL_ASPECT:
out.flags |= TRPRF_SIGNAL_MODE_NORMAL;
out.flags &= ~TRPRF_SIGNAL_MODE_SHUNT;
break;
case TRSMCF_SHUNT_ASPECT:
out.flags &= ~TRPRF_SIGNAL_MODE_NORMAL;
out.flags |= TRPRF_SIGNAL_MODE_SHUNT;
break;
default:
NOT_REACHED();
break;
}
break;
default:
NOT_REACHED();
}
@ -1092,6 +1110,10 @@ CommandCost TraceRestrictProgram::Validate(const std::vector<TraceRestrictItem>
actions_used_flags |= TRPAUF_SPEED_ADAPTATION;
break;
case TRIT_SIGNAL_MODE_CONTROL:
actions_used_flags |= TRPAUF_CMB_SIGNAL_MODE_CTRL;
break;
default:
return_cmd_error(STR_TRACE_RESTRICT_ERROR_VALIDATE_UNKNOWN_INSTRUCTION);
}
@ -1159,6 +1181,7 @@ void SetTraceRestrictValueDefault(TraceRestrictItem &item, TraceRestrictValueTyp
case TRVT_ENGINE_CLASS:
case TRVT_PF_PENALTY_CONTROL:
case TRVT_SPEED_ADAPTATION_CONTROL:
case TRVT_SIGNAL_MODE_CONTROL:
SetTraceRestrictValue(item, 0);
if (!IsTraceRestrictTypeAuxSubtype(GetTraceRestrictType(item))) {
SetTraceRestrictAuxField(item, 0);

@ -161,6 +161,7 @@ enum TraceRestrictItemType {
TRIT_COUNTER = 51, ///< Change counter value
TRIT_PF_PENALTY_CONTROL = 52, ///< Control base signal penalties
TRIT_SPEED_ADAPTATION_CONTROL = 53, ///< Control speed adaptation
TRIT_SIGNAL_MODE_CONTROL = 54, ///< Control signal modes
/* space up to 63 */
};
@ -300,6 +301,14 @@ enum TraceRestrictSpeedAdaptationControlField {
TRSACF_REMOVE_SPEED_ADAPT_EXEMPT = 1, ///< Remove train exempt from speed adaptation
};
/**
* TraceRestrictItem value field, for TRIT_SIGNAL_MODE_CONTROL
*/
enum TraceRestrictSignalModeControlField {
TRSMCF_NORMAL_ASPECT = 0, ///< Combined normal/shunt aspect signals: use normal mode
TRSMCF_SHUNT_ASPECT = 1, ///< Combined normal/shunt aspect signals: use shunt mode
};
/**
* TraceRestrictItem value field, for TRIT_COND_TRAIN_STATUS
*/
@ -369,6 +378,7 @@ enum TraceRestrictCounterCondOpField {
enum TraceRestrictPBSEntrySignalAuxField {
TRPESAF_VEH_POS = 0, ///< vehicle position signal
TRPESAF_RES_END = 1, ///< reservation end signal
TRPESAF_RES_END_TILE = 2, ///< reservation end tile
/* space up to 3 */
};
@ -398,6 +408,8 @@ enum TraceRestrictProgramResultFlags {
TRPRF_NO_PBS_BACK_PENALTY = 1 << 8, ///< Do not apply PBS back penalty
TRPRF_SPEED_ADAPT_EXEMPT = 1 << 9, ///< Make speed adaptation exempt
TRPRF_RM_SPEED_ADAPT_EXEMPT = 1 << 10, ///< Remove speed adaptation exemption
TRPRF_SIGNAL_MODE_NORMAL = 1 << 11, ///< Combined normal/shunt signal mode control: normal
TRPRF_SIGNAL_MODE_SHUNT = 1 << 12, ///< Combined normal/shunt signal mode control: shunt
};
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramResultFlags)
@ -423,13 +435,14 @@ enum TraceRestrictProgramActionsUsedFlags {
TRPAUF_SPEED_ADAPTATION = 1 << 15, ///< Speed adaptation control
TRPAUF_PBS_RES_END_SIMULATE = 1 << 16, ///< PBS reservations ending at this signal slot changes must be fully simulated in dry run mode
TRPAUF_RESERVE_THROUGH_ALWAYS = 1 << 17, ///< Reserve through action is unconditionally set
TRPAUF_CMB_SIGNAL_MODE_CTRL = 1 << 18, ///< Combined normal/shunt signal mode control
};
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramActionsUsedFlags)
/**
* Enumeration for TraceRestrictProgramInput::permitted_slot_operations
*/
enum TraceRestrictProgramInputSlotPermissions {
enum TraceRestrictProgramInputSlotPermissions : uint8 {
TRPISP_ACQUIRE = 1 << 0, ///< Slot acquire is permitted
TRPISP_RELEASE_BACK = 1 << 1, ///< Slot release (back) is permitted
TRPISP_RELEASE_FRONT = 1 << 2, ///< Slot release (front) is permitted
@ -691,6 +704,7 @@ enum TraceRestrictValueType {
TRVT_ENGINE_CLASS = 46,///< takes a EngineClass
TRVT_PF_PENALTY_CONTROL = 47,///< takes a TraceRestrictPfPenaltyControlField
TRVT_SPEED_ADAPTATION_CONTROL = 48,///< takes a TraceRestrictSpeedAdaptationControlField
TRVT_SIGNAL_MODE_CONTROL = 49,///< takes a TraceRestrictSignalModeControlField
};
/**
@ -870,6 +884,8 @@ static inline TraceRestrictTypePropertySet GetTraceRestrictTypeProperties(TraceR
out.value_type = TRVT_PF_PENALTY_CONTROL;
} else if (GetTraceRestrictType(item) == TRIT_SPEED_ADAPTATION_CONTROL) {
out.value_type = TRVT_SPEED_ADAPTATION_CONTROL;
} else if (GetTraceRestrictType(item) == TRIT_SIGNAL_MODE_CONTROL) {
out.value_type = TRVT_SIGNAL_MODE_CONTROL;
} else {
out.value_type = TRVT_NONE;
}

@ -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(),

Loading…
Cancel
Save