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