diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 447def89..a0b19e78 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -1161,6 +1161,11 @@ TMoverParameters::derail( int const Reason ) { AccS *= 0.65; V *= 0.65; + if( Vel < 5.0 ) { + // HACK: prevent permanent axle spin in static vehicle after a collision + nrot = 0.0; + SlippingWheels = false; + } WriteLog( "Bad driving: " + Name + " derailed" ); } @@ -6527,26 +6532,6 @@ void TMoverParameters::CheckEIMIC(double dt) } if (MainCtrlPos >= 3 && eimic < 0) eimic = 0; if (MainCtrlPos <= 3 && eimic > 0) eimic = 0; - if (LocHandleTimeTraxx) - { - if (LocalBrakeRatio() < 0.05) //pozycja 0 - { - eim_localbrake -= dt*0.17; //zmniejszanie - } - - if (LocalBrakeRatio() > 0.15) //pozycja 2 - { - eim_localbrake += dt*0.17; //wzrastanie - eim_localbrake = std::max(eim_localbrake, BrakePress / MaxBrakePress[0]); - } - else - { - if (eim_localbrake < Hamulec->GetEDBCP() / MaxBrakePress[0]) - eim_localbrake = 0; - } - eim_localbrake = clamp(eim_localbrake, 0.0, 1.0); - if (eim_localbrake > 0.04 && eimic > 0) eimic = 0; - } break; case 2: if ((MainCtrlActualPos != MainCtrlPos) || (LastRelayTime>InitialCtrlDelay)) @@ -6616,6 +6601,27 @@ void TMoverParameters::CheckEIMIC(double dt) } } + if (LocHandleTimeTraxx) + { + if (LocalBrakeRatio() < 0.05) //pozycja 0 + { + eim_localbrake -= dt*0.17; //zmniejszanie + } + + if (LocalBrakeRatio() > 0.15) //pozycja 2 + { + eim_localbrake += dt*0.17; //wzrastanie + eim_localbrake = std::max(eim_localbrake, BrakePress / MaxBrakePress[0]); + } + else + { + if (eim_localbrake < Hamulec->GetEDBCP() / MaxBrakePress[0]) + eim_localbrake = 0; + } + eim_localbrake = clamp(eim_localbrake, 0.0, 1.0); + if (eim_localbrake > 0.04 && eimic > 0) eimic = 0; + } + auto const eimicpowerenabled { ( ( true == Mains ) || ( Power == 0.0 ) ) && ( ( Doors.instances[ side::left ].open_permit == false ) diff --git a/Train.cpp b/Train.cpp index 580d4e02..576572a5 100644 --- a/Train.cpp +++ b/Train.cpp @@ -233,6 +233,10 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = { { user_command::pantographlowerfront, &TTrain::OnCommand_pantographlowerfront }, { user_command::pantographlowerrear, &TTrain::OnCommand_pantographlowerrear }, { user_command::pantographlowerall, &TTrain::OnCommand_pantographlowerall }, + { user_command::pantographselectnext, &TTrain::OnCommand_pantographselectnext }, + { user_command::pantographselectprevious, &TTrain::OnCommand_pantographselectprevious }, + { user_command::pantographraiseselected, &TTrain::OnCommand_pantographraiseselected }, + { user_command::pantographlowerselected, &TTrain::OnCommand_pantographlowerselected }, { user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle }, { user_command::linebreakeropen, &TTrain::OnCommand_linebreakeropen }, { user_command::linebreakerclose, &TTrain::OnCommand_linebreakerclose }, @@ -2020,18 +2024,9 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const if( Train->mvOccupied->PantSwitchType == "impulse" ) { if( Train->ggPantFrontButton.SubModel ) Train->ggPantFrontButton.UpdateValue( 0.0, Train->dsbSwitch ); - // NOTE: currently we animate the selectable pantograph control based on standard key presses - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - if( Train->ggPantSelectedButton.SubModel ) - Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch ); // also the switch off button, in cabs which have it if( Train->ggPantFrontButtonOff.SubModel ) Train->ggPantFrontButtonOff.UpdateValue( 0.0, Train->dsbSwitch ); - if( Train->ggPantSelectedDownButton.SubModel ) { - // NOTE: currently we animate the selectable pantograph control based on standard key presses - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - Train->ggPantSelectedDownButton.UpdateValue( 0.0, Train->dsbSwitch ); - } } } } @@ -2055,40 +2050,25 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const & if( Train->mvOccupied->PantSwitchType == "impulse" ) { if( Train->ggPantRearButton.SubModel ) Train->ggPantRearButton.UpdateValue( 0.0, Train->dsbSwitch ); - // NOTE: currently we animate the selectable pantograph control based on standard key presses - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - if( Train->ggPantSelectedButton.SubModel ) - Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch ); // also the switch off button, in cabs which have it if( Train->ggPantRearButtonOff.SubModel ) Train->ggPantRearButtonOff.UpdateValue( 0.0, Train->dsbSwitch ); - if( Train->ggPantSelectedDownButton.SubModel ) { - // NOTE: currently we animate the selectable pantograph control based on standard key presses - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - Train->ggPantSelectedDownButton.UpdateValue( 0.0, Train->dsbSwitch ); - } } } } void TTrain::OnCommand_pantographraisefront( TTrain *Train, command_data const &Command ) { + if( Train->ggPantFrontButton.SubModel == nullptr ) { return; } + if( Command.action == GLFW_PRESS ) { // only reacting to press, so the switch doesn't flip back and forth if key is held down // visual feedback if( Train->ggPantFrontButton.SubModel ) Train->ggPantFrontButton.UpdateValue( 1.0, Train->dsbSwitch ); - // NOTE: currently we animate the selectable pantograph control based on standard key presses - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - if( Train->ggPantSelectedButton.SubModel ) - Train->ggPantSelectedButton.UpdateValue( 1.0, Train->dsbSwitch ); // pantograph control can have two-button setup if( Train->ggPantFrontButtonOff.SubModel ) Train->ggPantFrontButtonOff.UpdateValue( 0.0, Train->dsbSwitch ); - // NOTE: currently we animate the selectable pantograph control based on standard key presses - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - if( Train->ggPantSelectedDownButton.SubModel ) - Train->ggPantSelectedDownButton.UpdateValue( 0.0, Train->dsbSwitch ); if( true == Train->mvControlled->PantFrontUp ) { return; } // already up @@ -2106,22 +2086,16 @@ void TTrain::OnCommand_pantographraisefront( TTrain *Train, command_data const & void TTrain::OnCommand_pantographraiserear( TTrain *Train, command_data const &Command ) { + if( Train->ggPantRearButton.SubModel == nullptr ) { return; } + if( Command.action == GLFW_PRESS ) { // only reacting to press, so the switch doesn't flip back and forth if key is held down // visual feedback if( Train->ggPantRearButton.SubModel ) Train->ggPantRearButton.UpdateValue( 1.0, Train->dsbSwitch ); - // NOTE: currently we animate the selectable pantograph control based on standard key presses - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - if( Train->ggPantSelectedButton.SubModel ) - Train->ggPantSelectedButton.UpdateValue( 1.0, Train->dsbSwitch ); // pantograph control can have two-button setup if( Train->ggPantRearButtonOff.SubModel ) Train->ggPantRearButtonOff.UpdateValue( 0.0, Train->dsbSwitch ); - // NOTE: currently we animate the selectable pantograph control based on standard key presses - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - if( Train->ggPantSelectedDownButton.SubModel ) - Train->ggPantSelectedDownButton.UpdateValue( 0.0, Train->dsbSwitch ); if( true == Train->mvControlled->PantRearUp ) { return; } // already up @@ -2139,32 +2113,28 @@ void TTrain::OnCommand_pantographraiserear( TTrain *Train, command_data const &C void TTrain::OnCommand_pantographlowerfront( TTrain *Train, command_data const &Command ) { + if( ( Train->ggPantFrontButton.SubModel == nullptr ) + && ( Train->ggPantFrontButtonOff.SubModel == nullptr ) ) { + // no buttons, either there's other switch types or none whatsoever + return; + } + if( Command.action == GLFW_PRESS ) { if( Train->mvOccupied->PantSwitchType == "impulse" ) { - if( ( Train->ggPantFrontButtonOff.SubModel == nullptr ) - && ( Train->ggPantSelectedDownButton.SubModel == nullptr ) ) { + if( Train->ggPantFrontButtonOff.SubModel == nullptr ) { // with impulse buttons we expect a dedicated switch to lower the pantograph, and if the cabin lacks it // then another control has to be used (like pantographlowerall) // TODO: we should have a way to define presence of cab controls without having to bind these to 3d submodels return; } } - // visual feedback if( Train->ggPantFrontButton.SubModel ) Train->ggPantFrontButton.UpdateValue( 0.0, Train->dsbSwitch ); - // NOTE: currently we animate the selectable pantograph control based on standard key presses - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - if( Train->ggPantSelectedButton.SubModel ) - Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch ); // pantograph control can have two-button setup if( Train->ggPantFrontButtonOff.SubModel ) Train->ggPantFrontButtonOff.UpdateValue( 1.0, Train->dsbSwitch ); - // NOTE: currently we animate the selectable pantograph control based on standard key presses - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - if( Train->ggPantSelectedDownButton.SubModel ) - Train->ggPantSelectedDownButton.UpdateValue( 1.0, Train->dsbSwitch ); if( false == Train->mvControlled->PantFrontUp ) { return; } // already down @@ -2182,32 +2152,28 @@ void TTrain::OnCommand_pantographlowerfront( TTrain *Train, command_data const & void TTrain::OnCommand_pantographlowerrear( TTrain *Train, command_data const &Command ) { + if( ( Train->ggPantRearButton.SubModel == nullptr ) + && ( Train->ggPantRearButtonOff.SubModel == nullptr ) ) { + // no buttons, either there's other switch types or none whatsoever + return; + } + if( Command.action == GLFW_PRESS ) { if( Train->mvOccupied->PantSwitchType == "impulse" ) { - if( ( Train->ggPantRearButtonOff.SubModel == nullptr ) - && ( Train->ggPantSelectedDownButton.SubModel == nullptr ) ) { + if( Train->ggPantRearButtonOff.SubModel == nullptr ) { // with impulse buttons we expect a dedicated switch to lower the pantograph, and if the cabin lacks it // then another control has to be used (like pantographlowerall) // TODO: we should have a way to define presence of cab controls without having to bind these to 3d submodels return; } } - // visual feedback if( Train->ggPantRearButton.SubModel ) Train->ggPantRearButton.UpdateValue( 0.0, Train->dsbSwitch ); - // NOTE: currently we animate the selectable pantograph control based on standard key presses - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - if( Train->ggPantSelectedButton.SubModel ) - Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch ); // pantograph control can have two-button setup if( Train->ggPantRearButtonOff.SubModel ) Train->ggPantRearButtonOff.UpdateValue( 1.0, Train->dsbSwitch ); - // NOTE: currently we animate the selectable pantograph control based on standard key presses - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - if( Train->ggPantSelectedDownButton.SubModel ) - Train->ggPantSelectedDownButton.UpdateValue( 1.0, Train->dsbSwitch ); if( false == Train->mvControlled->PantRearUp ) { return; } // already down @@ -2227,8 +2193,7 @@ void TTrain::OnCommand_pantographlowerall( TTrain *Train, command_data const &Co if( Command.action == GLFW_REPEAT ) { return; } - if( ( Train->ggPantAllDownButton.SubModel == nullptr ) - && ( Train->ggPantSelectedDownButton.SubModel == nullptr ) ) { + if( Train->ggPantAllDownButton.SubModel == nullptr ) { // TODO: expand definition of cab controls so we can know if the control is present without testing for presence of 3d switch if( Command.action == GLFW_PRESS ) { WriteLog( "Lower All Pantographs switch is missing, or wasn't defined" ); @@ -2248,20 +2213,12 @@ void TTrain::OnCommand_pantographlowerall( TTrain *Train, command_data const &Co Train->mvControlled->PantRearSP = false; Train->mvControlled->PantRear( false ); // visual feedback - if( Train->ggPantAllDownButton.SubModel ) - Train->ggPantAllDownButton.UpdateValue( 1.0, Train->dsbSwitch ); - if( Train->ggPantSelectedDownButton.SubModel ) { - Train->ggPantSelectedDownButton.UpdateValue( 1.0, Train->dsbSwitch ); - } + Train->ggPantAllDownButton.UpdateValue( 1.0, Train->dsbSwitch ); } else if( Command.action == GLFW_RELEASE ) { // release the button // visual feedback - if( Train->ggPantAllDownButton.SubModel ) - Train->ggPantAllDownButton.UpdateValue( 0.0 ); - if( Train->ggPantSelectedDownButton.SubModel ) { - Train->ggPantSelectedDownButton.UpdateValue( 0.0 ); - } + Train->ggPantAllDownButton.UpdateValue( 0.0 ); } } else { @@ -2278,25 +2235,146 @@ void TTrain::OnCommand_pantographlowerall( TTrain *Train, command_data const &Co Train->mvControlled->PantRearSP = false; Train->mvControlled->PantRear( false ); // visual feedback - if( Train->ggPantAllDownButton.SubModel ) - Train->ggPantAllDownButton.UpdateValue( 1.0, Train->dsbSwitch ); - if( Train->ggPantSelectedDownButton.SubModel ) { - Train->ggPantSelectedDownButton.UpdateValue( 1.0, Train->dsbSwitch ); - } + Train->ggPantAllDownButton.UpdateValue( 1.0, Train->dsbSwitch ); } else { // currently active, move it back to neutral position // visual feedback - if( Train->ggPantAllDownButton.SubModel ) - Train->ggPantAllDownButton.UpdateValue( 0.0 ); - if( Train->ggPantSelectedDownButton.SubModel ) { - Train->ggPantSelectedDownButton.UpdateValue( 0.0 ); - } + Train->ggPantAllDownButton.UpdateValue( 0.0 ); } } } } +void TTrain::OnCommand_pantographselectnext( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_PRESS ) { return; } + + Train->change_pantograph_selection( 1 ); +} + +void TTrain::OnCommand_pantographselectprevious( TTrain *Train, command_data const &Command ) { + + if( Command.action != GLFW_PRESS ) { return; } + + Train->change_pantograph_selection( -1 ); +} + +void TTrain::OnCommand_pantographraiseselected( TTrain *Train, command_data const &Command ) { + + if( Command.action == GLFW_REPEAT ) { return; } + + if( Train->ggPantSelectedButton.type() == TGaugeType::push ) { + // impulse switch + if( Command.action == GLFW_PRESS ) { + // visual feedback + Train->ggPantSelectedButton.UpdateValue( 1.0, Train->dsbSwitch ); + // raise selected + Train->change_pantograph_selection_state( true ); + } + else if( Command.action == GLFW_RELEASE ) { + // visual feedback + Train->ggPantSelectedButton.UpdateValue( 0.0, Train->dsbSwitch ); + } + } + else { + // two-state switch, only cares about press events + if( Command.action == GLFW_PRESS ) { + // visual feedback + Train->ggPantSelectedButton.UpdateValue( 1.0, Train->dsbSwitch ); + // raise selected + Train->change_pantograph_selection_state( true ); + } + } +} + +void TTrain::OnCommand_pantographlowerselected( TTrain *Train, command_data const &Command ) { + + if( Command.action == GLFW_REPEAT ) { return; } + + if( Train->ggPantSelectedDownButton.type() == TGaugeType::push ) { + // impulse switch + if( Command.action == GLFW_PRESS ) { + // visual feedback + Train->ggPantSelectedDownButton.UpdateValue( 1.0, Train->dsbSwitch ); + // lower selected + Train->change_pantograph_selection_state( false ); + } + else if( Command.action == GLFW_RELEASE ) { + // visual feedback + Train->ggPantSelectedDownButton.UpdateValue( 0.0, Train->dsbSwitch ); + } + } + else { + // two-state switch, only cares about press events + if( Command.action == GLFW_PRESS ) { + // visual feedback + Train->ggPantSelectedDownButton.UpdateValue( 0.0, Train->dsbSwitch ); + // lower selected + Train->change_pantograph_selection_state( false ); + } + } +} + +void TTrain::change_pantograph_selection( int const Change, bool const Force ) { + + auto const initialstate { m_pantselection }; + + m_pantselection = clamp( m_pantselection + Change, 0, 3 ); + // visual feedback + ggPantSelectButton.UpdateValue( m_pantselection ); + + if( ( m_pantselection == initialstate ) && ( false == Force ) ) { return; } // no change, nothing to do + + // crude way to determine whether pantograph state change is automatic + // if there's button to raise/lower selected panthograph, we presume the change has to be invoked manually + if( ggPantSelectedButton.SubModel != nullptr ) { return; } + + // raise or lower pantographs according to new requested state + auto const swapends{ cab_to_end() != end::front }; + // check desired states for both pantographs; value: whether the pantograph should be raised + auto const frontstate{ ( m_pantselection == 2 ) || ( m_pantselection == ( swapends ? 1 : 3 ) ) }; + auto const rearstate{ ( m_pantselection == 2 ) || ( m_pantselection == ( swapends ? 3 : 1 ) ) }; + // potentially adjust front pantograph state + if( mvControlled->PantFrontUp != frontstate ) { + // TBD, TODO: impulse switch should only work when the power is on? + if( mvControlled->PantFront( frontstate ) == frontstate ) { + mvControlled->PantFrontSP = false; + } + } + // potentially adjust rear pantograph state + if( mvControlled->PantRearUp != rearstate ) { + // TBD, TODO: impulse switch should only work when the power is on? + if( mvControlled->PantRear( rearstate ) == rearstate ) { + mvControlled->PantRearSP = false; + } + } +} + +void TTrain::change_pantograph_selection_state( bool const State ) { + + auto const swapends { cab_to_end() != end::front }; + // check desired states for both pantographs; value: whether the pantograph should be raised + auto const frontselected { ( m_pantselection == 0 ) || ( m_pantselection == 2 ) || ( m_pantselection == ( swapends ? 1 : 3 ) ) }; + auto const rearselected { ( m_pantselection == 0 ) || ( m_pantselection == 2 ) || ( m_pantselection == ( swapends ? 3 : 1 ) ) }; + // potentially adjust front pantograph state + if( ( true == frontselected ) + && ( mvControlled->PantFrontUp != State ) ) { + // TBD, TODO: impulse switch should only work when the power is on? + if( mvControlled->PantFront( State ) == State ) { + mvControlled->PantFrontSP = false; + } + } + // potentially adjust rear pantograph state + if( ( true == rearselected ) + && ( mvControlled->PantRearUp != State ) ) { + // TBD, TODO: impulse switch should only work when the power is on? + if( mvControlled->PantRear( State ) == State ) { + mvControlled->PantRearSP = false; + } + } +} + void TTrain::OnCommand_pantographcompressorvalvetoggle( TTrain *Train, command_data const &Command ) { if( ( Train->ggPantCompressorValve.SubModel == nullptr ) @@ -6036,11 +6114,15 @@ bool TTrain::Update( double const Deltatime ) } Cabine[iCabn].Update( lowvoltagepower ); // nowy sposób ustawienia animacji +/* if (ggZbS.SubModel) { ggZbS.UpdateValue(mvOccupied->Handle->GetCP()); ggZbS.Update(); } +*/ + // replacement for the above. TODO: move it to a more suitable place + m_brakehandlecp = mvOccupied->Handle->GetCP(); // youBy - napiecie na silnikach if (ggEngineVoltage.SubModel) @@ -6710,6 +6792,7 @@ bool TTrain::Update( double const Deltatime ) ggPantRearButtonOff.Update(); ggPantSelectedDownButton.Update(); ggPantAllDownButton.Update(); + ggPantSelectButton.Update(); ggPantCompressorButton.Update(); ggPantCompressorValve.Update(); @@ -6834,6 +6917,18 @@ bool TTrain::Update( double const Deltatime ) mvControlled->PantRear( true ); } } + if( ggPantSelectButton.SubModel ) { + if( ggPantSelectedButton.SubModel ) { + if( ( ggPantSelectedButton.type() == TGaugeType::toggle ) + && ( ggPantSelectedButton.GetDesiredValue() >= 0.95 ) ) { + change_pantograph_selection_state( true ); + } + } + else { + // HACK: force pantographs into currently selected state + change_pantograph_selection( 0, true ); + } + } } } /* @@ -8012,9 +8107,9 @@ void TTrain::clear_cab_controls() ggPantRearButtonOff.Clear(); ggPantSelectedDownButton.Clear(); ggPantAllDownButton.Clear(); + ggPantSelectButton.Clear(); ggPantCompressorButton.Clear(); ggPantCompressorValve.Clear(); - ggZbS.Clear(); ggI1B.Clear(); ggI2B.Clear(); ggI3B.Clear(); @@ -8168,20 +8263,6 @@ void TTrain::set_cab_controls( int const Cab ) { 0.f : 1.f ) ); } - // NOTE: currently we animate the selectable pantograph control for both pantographs - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - if( ggPantSelectedButton.SubModel ) { - ggPantSelectedButton.PutValue( - ( mvControlled->PantFrontUp ? - 1.f : - 0.f ) ); - } - if( ggPantSelectedDownButton.SubModel ) { - ggPantSelectedDownButton.PutValue( - ( mvControlled->PantFrontUp ? - 0.f : - 1.f ) ); - } } if( mvOccupied->PantSwitchType != "impulse" ) { if( ggPantRearButton.SubModel ) { @@ -8196,17 +8277,41 @@ void TTrain::set_cab_controls( int const Cab ) { 0.f : 1.f ) ); } - // NOTE: currently we animate the selectable pantograph control for both pantographs - // TODO: implement actual selection control, and refactor handling this control setup in a separate method - if( ggPantSelectedButton.SubModel ) { + } + // front/end pantograph selection is relative to occupied cab + m_pantselection = ( + m_pantselection == 1 ? ( cab_to_end( Cab ) == cab_to_end() ? 1 : 3 ) : + m_pantselection == 3 ? ( cab_to_end( Cab ) == cab_to_end() ? 3 : 1 ) : + m_pantselection ); // other settings affect both pantographs + if( ggPantSelectButton.SubModel ) { + ggPantSelectButton.PutValue( m_pantselection ); + } + if( ggPantSelectedButton.type() == TGaugeType::toggle ) { + if( ggPantSelectButton.SubModel ) { + auto const swapends{ cab_to_end( Cab ) != end::front }; + auto const pantraised{ ( + m_pantselection == 0 ? false : + m_pantselection == 1 ? ( swapends ? mvControlled->PantFrontUp : mvControlled->PantRearUp ) : + m_pantselection == 2 ? ( mvControlled->PantFrontUp & mvControlled->PantRearUp ) : + m_pantselection == 3 ? ( swapends ? mvControlled->PantRearUp : mvControlled->PantFrontUp ) : + false ) }; ggPantSelectedButton.PutValue( - ( mvControlled->PantRearUp ? + ( pantraised ? 1.f : 0.f ) ); } + } + if( ggPantSelectedDownButton.type() == TGaugeType::toggle ) { if( ggPantSelectedDownButton.SubModel ) { + auto const swapends{ cab_to_end( Cab ) != end::front }; + auto const pantraised{ ( + m_pantselection == 0 ? false : + m_pantselection == 1 ? ( swapends ? mvControlled->PantFrontUp : mvControlled->PantRearUp ) : + m_pantselection == 2 ? ( mvControlled->PantFrontUp & mvControlled->PantRearUp ) : + m_pantselection == 3 ? ( swapends ? mvControlled->PantRearUp : mvControlled->PantFrontUp ) : + false ) }; ggPantSelectedDownButton.PutValue( - ( mvControlled->PantRearUp ? + ( pantraised ? 0.f : 1.f ) ); } @@ -8707,6 +8812,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con { "pantalloff_sw:", ggPantAllDownButton }, { "pantselected_sw:", ggPantSelectedButton }, { "pantselectedoff_sw:", ggPantSelectedDownButton }, + { "pantselect_sw:", ggPantSelectButton }, { "pantcompressor_sw:", ggPantCompressorButton }, { "pantcompressorvalve_sw:", ggPantCompressorValve }, { "trainheating_sw:", ggTrainHeatingButton }, @@ -8896,7 +9002,9 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con else if (Label == "limpipepress:") { // manometr zbiornika sterujacego zaworu maszynisty - ggZbS.Load(Parser, DynamicObject, 0.1); + auto &gauge = Cabine[ Cabindex ].Gauge( -1 ); // pierwsza wolna gałka + gauge.Load( Parser, DynamicObject, 0.1 ); + gauge.AssignDouble( &m_brakehandlecp ); } else if (Label == "cntrlpress:") { diff --git a/Train.h b/Train.h index ae72ee1b..e57b61b0 100644 --- a/Train.h +++ b/Train.h @@ -155,6 +155,9 @@ class TTrain { void set_train_brake_speed( TDynamicObject *Vehicle, int const Speed ); // sets the motor connector button in paired unit to specified state void set_paired_open_motor_connectors_button( bool const State ); + // helper, common part of pantograph selection methods + void change_pantograph_selection( int const Change, bool const Force = false ); + void change_pantograph_selection_state( bool const State ); // update function subroutines void update_sounds( double const Deltatime ); void update_sounds_runningnoise( sound_source &Sound ); @@ -249,6 +252,10 @@ class TTrain { static void OnCommand_pantographlowerfront( TTrain *Train, command_data const &Command ); static void OnCommand_pantographlowerrear( TTrain *Train, command_data const &Command ); static void OnCommand_pantographlowerall( TTrain *Train, command_data const &Command ); + static void OnCommand_pantographselectnext( TTrain *Train, command_data const &Command ); + static void OnCommand_pantographselectprevious( TTrain *Train, command_data const &Command ); + static void OnCommand_pantographraiseselected( TTrain *Train, command_data const &Command ); + static void OnCommand_pantographlowerselected( TTrain *Train, command_data const &Command ); static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command ); static void OnCommand_linebreakeropen( TTrain *Train, command_data const &Command ); static void OnCommand_linebreakerclose( TTrain *Train, command_data const &Command ); @@ -404,7 +411,6 @@ public: // reszta może by?publiczna // McZapkie: definicje wskaźników // Ra 2014-08: częsciowo przeniesione do tablicy w TCab - TGauge ggZbS; TGauge ggClockSInd; TGauge ggClockMInd; TGauge ggClockHInd; @@ -539,6 +545,7 @@ public: // reszta może by?publiczna TGauge ggPantAllDownButton; TGauge ggPantSelectedButton; TGauge ggPantSelectedDownButton; + TGauge ggPantSelectButton; TGauge ggPantCompressorButton; TGauge ggPantCompressorValve; // Winger 020304 - wlacznik ogrzewania @@ -742,6 +749,8 @@ private: float m_mastercontrollerreturndelay { 0.f }; std::vector> m_screens; float m_distancecounter { -1.f }; // distance traveled since meter was activated or -1 if inactive + double m_brakehandlecp{ 0.0 }; + int m_pantselection{ 0 }; public: float fPress[20][3]; // cisnienia dla wszystkich czlonow diff --git a/command.cpp b/command.cpp index 1ffc4b7c..2189a597 100644 --- a/command.cpp +++ b/command.cpp @@ -178,6 +178,10 @@ commanddescription_sequence Commands_descriptions = { { "pantographlowerfront", command_target::vehicle }, { "pantographlowerrear", command_target::vehicle }, { "pantographlowerall", command_target::vehicle }, + { "pantographselectnext", command_target::vehicle }, + { "pantographselectprevious", command_target::vehicle }, + { "pantographraiseselected", command_target::vehicle }, + { "pantographlowerselected", command_target::vehicle }, { "heatingtoggle", command_target::vehicle }, { "heatingenable", command_target::vehicle }, { "heatingdisable", command_target::vehicle }, @@ -262,7 +266,6 @@ commanddescription_sequence Commands_descriptions = { { "speedcontrolbutton7", command_target::vehicle }, { "speedcontrolbutton8", command_target::vehicle }, { "speedcontrolbutton9", command_target::vehicle } - }; } // simulation diff --git a/command.h b/command.h index f6fa01f0..a4fdc03e 100644 --- a/command.h +++ b/command.h @@ -171,6 +171,10 @@ enum class user_command { pantographlowerfront, pantographlowerrear, pantographlowerall, + pantographselectnext, + pantographselectprevious, + pantographraiseselected, + pantographlowerselected, heatingtoggle, heatingenable, heatingdisable, diff --git a/driverkeyboardinput.cpp b/driverkeyboardinput.cpp index f13a2f31..fb693475 100644 --- a/driverkeyboardinput.cpp +++ b/driverkeyboardinput.cpp @@ -180,6 +180,10 @@ driverkeyboard_input::default_bindings() { // pantographlowerfront, // pantographlowerrear, { user_command::pantographlowerall, GLFW_KEY_P | keymodifier::control }, + { user_command::pantographselectnext, GLFW_KEY_P | keymodifier::shift }, + { user_command::pantographselectprevious, GLFW_KEY_O | keymodifier::shift }, + { user_command::pantographraiseselected, GLFW_KEY_O | keymodifier::shift | keymodifier::control }, + { user_command::pantographlowerselected, GLFW_KEY_O | keymodifier::control }, { user_command::heatingtoggle, GLFW_KEY_H }, // heatingenable, // heatingdisable, diff --git a/drivermouseinput.cpp b/drivermouseinput.cpp index 94ed3b07..706d16c3 100644 --- a/drivermouseinput.cpp +++ b/drivermouseinput.cpp @@ -772,19 +772,22 @@ drivermouse_input::default_bindings() { user_command::none } }, { "pantfrontoff_sw:", { user_command::pantographlowerfront, - user_command::none } }, // TODO: dedicated lower pantograph commands + user_command::none } }, { "pantrearoff_sw:", { user_command::pantographlowerrear, - user_command::none } }, // TODO: dedicated lower pantograph commands + user_command::none } }, { "pantalloff_sw:", { user_command::pantographlowerall, user_command::none } }, { "pantselected_sw:", { - user_command::none, - user_command::none } }, // TODO: selected pantograph(s) operation command + user_command::pantographraiseselected, + user_command::none } }, // TBD: bind lowerselected in case of toggle switch { "pantselectedoff_sw:", { - user_command::none, - user_command::none } }, // TODO: lower selected pantograp(s) command + user_command::pantographlowerselected, + user_command::none } }, + { "pantselect_sw:", { + user_command::pantographselectnext, + user_command::pantographselectprevious } }, { "pantcompressor_sw:", { user_command::pantographcompressoractivate, user_command::none } }, diff --git a/driveruipanels.cpp b/driveruipanels.cpp index 0f3d133d..7ca3461c 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -523,7 +523,22 @@ debug_panel::render() { } // sections ImGui::Separator(); - render_section( "Vehicle", m_vehiclelines ); + if( true == render_section( "Vehicle", m_vehiclelines ) ) { + if( ( m_input.mover ) + && ( m_input.mover->DamageFlag != 0 ) ) { + if( true == ImGui::Button( "Fix Status" ) ) { + // TODO: refactor status reset into mover method + m_input.mover->DamageFlag = 0; + m_input.mover->EngDmgFlag = 0; + m_input.mover->V = 0.0001; // HACK: force vehicle position re-calculation + m_input.mover->DistCounter = 0.0; + m_input.mover->WheelFlat = 0.0; + m_input.mover->AlarmChainFlag = false; + m_input.mover->OffsetTrackH = 0.0; + m_input.mover->OffsetTrackV = 0.0; + } + } + } render_section( "Vehicle Engine", m_enginelines ); render_section( "Vehicle AI", m_ailines ); render_section( "Vehicle Scan Table", m_scantablelines ); diff --git a/driveruipanels.h b/driveruipanels.h index ddd4eff2..82a48404 100644 --- a/driveruipanels.h +++ b/driveruipanels.h @@ -76,7 +76,7 @@ private: TDynamicObject const *controlled; TCamera const *camera; TDynamicObject const *vehicle; - TMoverParameters const *mover; + TMoverParameters *mover; TController const *mechanik; }; // methods diff --git a/translation.cpp b/translation.cpp index 0010d472..4b52c8bd 100644 --- a/translation.cpp +++ b/translation.cpp @@ -170,6 +170,7 @@ init() { "all pantographs", "selected pantograph", "selected pantograph", + "selected pantograph", "pantograph compressor", "pantograph 3 way valve", "heating", @@ -344,6 +345,7 @@ init() { "wszystkie pantografy", "wybrany pantograf", "wybrany pantograf", + "wybrany pantograf", "sprezarka pantografow", "kurek trojdrogowy pantografow", "ogrzewanie pociagu", @@ -471,6 +473,7 @@ init() { "pantalloff_sw:", "pantselected_sw:", "pantselectedoff_sw:", + "pantselect_sw:", "pantcompressor_sw:", "pantcompressorvalve_sw:", "trainheating_sw:", diff --git a/translation.h b/translation.h index 77da90b3..ec43a056 100644 --- a/translation.h +++ b/translation.h @@ -159,6 +159,7 @@ enum string { cab_pantalloff_sw, cab_pantselected_sw, cab_pantselectedoff_sw, + cab_pantselect_sw, cab_pantcompressor_sw, cab_pantcompressorvalve_sw, cab_trainheating_sw, diff --git a/version.h b/version.h index 44c490d7..be631c54 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 20 -#define VERSION_MINOR 112 +#define VERSION_MINOR 116 #define VERSION_REVISION 0