From bdbbaafc83dd3a0275115cb27db74c96743114c3 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Mon, 31 Dec 2018 22:00:58 +0100 Subject: [PATCH] build 181231. cab control tweaks, python interpreter stderr initialization fail fallback, enabled cab reflections, more parameters exposed to python scripts, minor ai logic enhancements, minor debug enhancements --- Driver.cpp | 73 ++++++++++++++++++++++++++++++++---------- Driver.h | 1 + McZapkie/Mover.cpp | 39 +++++++++++++--------- PyInt.cpp | 12 +++---- PyInt.h | 2 +- Train.cpp | 49 ++++++++++++++++++++-------- Train.h | 2 +- driveruipanels.cpp | 7 ++-- renderer.cpp | 4 +++ renderer.h | 1 + scenarioloadermode.cpp | 2 +- translation.cpp | 7 ++-- translation.h | 1 + version.h | 2 +- 14 files changed, 140 insertions(+), 62 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index b8b21df3..38a01eb0 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -836,7 +836,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN double v; // prędkość double d; // droga double d_to_next_sem = 10000.0; //ustaiwamy na pewno dalej niż widzi AI - bool isatpassengerstop { false }; // true if the consist is within acceptable range of w4 post + IsAtPassengerStop = false; TCommandType go = TCommandType::cm_Unknown; eSignNext = NULL; // te flagi są ustawiane tutaj, w razie potrzeby @@ -924,7 +924,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN sSpeedTable[i].iFlags = 0; } } - isatpassengerstop = ( + IsAtPassengerStop = ( ( sSpeedTable[ i ].fDist <= passengerstopmaxdistance ) // Ra 2F1I: odległość plus długość pociągu musi być mniejsza od długości // peronu, chyba że pociąg jest dłuższy, to wtedy minimalna. @@ -944,7 +944,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN if( mvOccupied->Vel > 0.3 ) { // jeśli jedzie (nie trzeba czekać, aż się drgania wytłumią - drzwi zamykane od 1.0) to będzie zatrzymanie sSpeedTable[ i ].fVelNext = 0; - } else if( true == isatpassengerstop ) { + } else if( true == IsAtPassengerStop ) { // jeśli się zatrzymał przy W4, albo stał w momencie zobaczenia W4 if( !AIControllFlag ) { // w razie przełączenia na AI ma nie podciągać do W4, gdy użytkownik zatrzymał za daleko @@ -1035,7 +1035,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN // jeśli są dalsze stacje, czekamy do godziny odjazdu if (TrainParams->IsTimeToGo(simulation::Time.data().wHour, simulation::Time.data().wMinute)) { // z dalszą akcją czekamy do godziny odjazdu - isatpassengerstop = false; + IsAtPassengerStop = false; // przy jakim dystansie (stanie licznika) ma przesunąć na następny postój fLastStopExpDist = mvOccupied->DistCounter + 0.050 + 0.001 * fLength; TrainParams->StationIndexInc(); // przejście do następnej @@ -1376,7 +1376,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN // 2014-02: jeśli stoi, a ma do przejechania kawałek, to niech jedzie if( ( mvOccupied->Vel < 0.01 ) && ( true == TestFlag( sSpeedTable[ i ].iFlags, ( spEnabled | spEvent | spPassengerStopPoint ) ) ) - && ( false == isatpassengerstop ) ) { + && ( false == IsAtPassengerStop ) ) { // ma podjechać bliżej - czy na pewno w tym miejscu taki warunek? a = ( ( d > passengerstopmaxdistance ) || ( ( iDrivigFlags & moveStopCloser ) != 0 ) ? fAcc : @@ -1457,7 +1457,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN } //analiza spisanych z tabelki ograniczeń i nadpisanie aktualnego - if( ( true == isatpassengerstop ) && ( mvOccupied->Vel < 0.01 ) ) { + if( ( true == IsAtPassengerStop ) && ( mvOccupied->Vel < 0.01 ) ) { // if stopped at a valid passenger stop, hold there fVelDes = 0.0; } @@ -1625,6 +1625,11 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, mvOccupied->TrainType == dt_EZT ? -0.55 : mvOccupied->TrainType == dt_DMU ? -0.45 : -0.2 ); + // HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors + if( ( mvOccupied->TrainType == dt_EZT ) + && ( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) ) { + fAccThreshold += 0.10; + } } // TrainParams=NewTrainParams; // if (TrainParams) @@ -1944,7 +1949,13 @@ void TController::AutoRewident() 0.25 ); if( mvOccupied->TrainType == dt_EZT ) { - fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] ); + if( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) { + // HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors + fNominalAccThreshold = std::max( -0.60, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] ); + } + else { + fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] ); + } fBrakeReaction = 0.25; } else if( mvOccupied->TrainType == dt_DMU ) { @@ -2100,8 +2111,6 @@ bool TController::CheckVehicles(TOrders user) Lights( frontlights, rearlights ); - // nastawianie hamulca do jazdy pociągowej - AutoRewident(); } else if (OrderCurrentGet() & (Shunt | Connect)) { @@ -2134,6 +2143,10 @@ bool TController::CheckVehicles(TOrders user) Lights( 0, light::headlight_right ); } } + // nastawianie hamulca do jazdy pociągowej + if( OrderCurrentGet() & ( Obey_train | Shunt ) ) { + AutoRewident(); + } } else { // gdy człowiek i gdy nastąpiło połącznie albo rozłączenie // Ra 2014-02: lepiej tu niż w pętli obsługującej komendy, bo tam się zmieni informacja o składzie @@ -2841,7 +2854,7 @@ bool TController::IncSpeed() auto const sufficienttractionforce { std::abs( mvControlling->Ft ) > ( IsHeavyCargoTrain ? 125 : 100 ) * 1000.0 }; auto const seriesmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 ) }; auto const parallelmodefieldshunting { ( mvControlling->ScndCtrlPos > 0 ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 ) }; - auto const useseriesmodevoltage { 0.80 * mvControlling->EnginePowerSource.CollectorParameters.MaxV }; + auto const useseriesmodevoltage { mvControlling->EnginePowerSource.CollectorParameters.MaxV * ( IsHeavyCargoTrain ? 0.70 : 0.80 ) }; auto const useseriesmode = ( ( mvControlling->Imax > mvControlling->ImaxLo ) || ( fVoltage < useseriesmodevoltage ) @@ -3824,10 +3837,6 @@ TController::UpdateSituation(double dt) { // indywidualne luzowanko vehicle->BrakeReleaser( 1 ); } - if( ( vehicle->Power > 0.01 ) // jeśli ma silnik - && ( vehicle->FuseFlag ) ) { // wywalony nadmiarowy - Need_TryAgain = true; // reset jak przy wywaleniu nadmiarowego - } } } } @@ -3838,6 +3847,10 @@ TController::UpdateSituation(double dt) { // ciężar razy składowa styczna grawitacji fAccGravity -= vehicle->TotalMassxg * dy * ( p->DirectionGet() == iDirection ? 1 : -1 ); } + if( ( vehicle->Power > 0.01 ) // jeśli ma silnik + && ( vehicle->FuseFlag ) ) { // wywalony nadmiarowy + Need_TryAgain = true; // reset jak przy wywaleniu nadmiarowego + } p = p->Next(); // pojazd podłączony z tyłu (patrząc od czoła) } @@ -4090,6 +4103,12 @@ TController::UpdateSituation(double dt) { // dla nastawienia G koniecznie należy wydłużyć drogę na czas reakcji fBrakeDist += 2 * mvOccupied->Vel; } + if( ( mvOccupied->Vel > 0.05 ) + && ( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) + && ( ( mvControlling->TrainType & dt_EZT ) != 0 ) ) { + // HACK: make the induction motor powered EMUs start braking slightly earlier + fBrakeDist += 10.0; + } /* // take into account effect of gravity (but to stay on safe side of calculations, only downhill) if( fAccGravity > 0.025 ) { @@ -4746,8 +4765,8 @@ TController::UpdateSituation(double dt) { fMinProximityDist : // cars can bunch up tighter fMaxProximityDist ) ); // other vehicle types less so */ - double k = coupler->Connected->Vel; // prędkość pojazdu z przodu (zakładając, - // że jedzie w tę samą stronę!!!) + // prędkość pojazdu z przodu (zakładając, że jedzie w tę samą stronę!!!) + double k = coupler->Connected->Vel; if( k - vel < 5 ) { // porównanie modułów prędkości [km/h] // zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej @@ -4755,6 +4774,26 @@ TController::UpdateSituation(double dt) { ActualProximityDist, vehicle->fTrackBlock ); + if( ActualProximityDist <= ( + ( mvOccupied->CategoryFlag & 2 ) ? + 100.0 : // cars + 250.0 ) ) { // others + // regardless of driving mode at close distance take precaution measures: + // match the other vehicle's speed or slow down if the other vehicle is stopped + VelDesired = + min_speed( + VelDesired, + std::max( + k, + ( mvOccupied->CategoryFlag & 2 ) ? + 40.0 : // cars + 20.0 ) ); // others + if( vel > VelDesired + fVelPlus ) { + // if going too fast force some prompt braking + AccPreferred = std::min( -0.65, AccPreferred ); + } + } + double const distance = vehicle->fTrackBlock - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości if( distance < 0.0 ) { // jeśli odległość jest zbyt mała @@ -4804,7 +4843,7 @@ TController::UpdateSituation(double dt) { } } ReactionTime = ( - vel != 0.0 ? + mvOccupied->Vel > 0.01 ? 0.1 : // orientuj się, bo jest goraco 2.0 ); // we're already standing still, so take it easy } diff --git a/Driver.h b/Driver.h index 8ab06b2d..9140a899 100644 --- a/Driver.h +++ b/Driver.h @@ -261,6 +261,7 @@ private: int iDriverFailCount = 0; // licznik błędów AI bool Need_TryAgain = false; // true, jeśli druga pozycja w elektryku nie załapała bool Need_BrakeRelease = true; + bool IsAtPassengerStop{ false }; // true if the consist is within acceptable range of w4 post double fMinProximityDist = 30.0; // stawanie między 30 a 60 m przed przeszkodą // minimalna oległość do przeszkody, jaką należy zachować double fOverhead1 = 3000.0; // informacja o napięciu w sieci trakcyjnej (0=brak drutu, zatrzymaj!) double fOverhead2 = -1.0; // informacja o sposobie jazdy (-1=normalnie, 0=bez prądu, >0=z opuszczonym i ograniczeniem prędkości) diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 5cc0d1f9..b5ef617d 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -563,7 +563,7 @@ bool TMoverParameters::DirectionForward() SendCtrlToNext("Direction", ActiveDir, CabNo); return true; } - else if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType == TEngineType::ElectricSeriesMotor)) + else if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor)) return MinCurrentSwitch(true); //"wysoki rozruch" EN57 return false; }; @@ -635,8 +635,9 @@ bool TMoverParameters::ChangeCab(int direction) { // if (ActiveCab+direction=0) then LastCab:=ActiveCab; ActiveCab = ActiveCab + direction; - if ((BrakeSystem == TBrakeSystem::Pneumatic) && (BrakeCtrlPosNo > 0)) - { + if( ( BrakeCtrlPosNo > 0 ) + && ( ( BrakeSystem == TBrakeSystem::Pneumatic ) + || ( BrakeSystem == TBrakeSystem::ElectroPneumatic ) ) ) { // if (BrakeHandle==FV4a) //!!!POBIERAĆ WARTOŚĆ Z KLASY ZAWORU!!! // BrakeLevelSet(-2); //BrakeCtrlPos=-2; // else if ((BrakeHandle==FVel6)||(BrakeHandle==St113)) @@ -2389,7 +2390,7 @@ bool TMoverParameters::EpFuseSwitch(bool State) bool TMoverParameters::DirectionBackward(void) { bool DB = false; - if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType == TEngineType::ElectricSeriesMotor)) + if ((ActiveDir == 1) && (MainCtrlPos == 0) && (TrainType == dt_EZT) && (EngineType != TEngineType::ElectricInductionMotor)) if (MinCurrentSwitch(false)) { DB = true; // @@ -3555,9 +3556,8 @@ void TMoverParameters::UpdatePipePressure(double dt) dpMainValve = 0; - if ((BrakeCtrlPosNo > 1) /*&& (ActiveCab != 0)*/) - // with BrakePressureTable[BrakeCtrlPos] do - { + if( BrakeCtrlPosNo > 1 ) { + if ((EngineType != TEngineType::ElectricInductionMotor)) dpLocalValve = LocHandle->GetPF(std::max(LocalBrakePosA, LocalBrakePosAEIM), Hamulec->GetBCP(), ScndPipePress, dt, 0); else @@ -3573,13 +3573,21 @@ void TMoverParameters::UpdatePipePressure(double dt) temp = ScndPipePress; } Handle->SetReductor(BrakeCtrlPos2); + + if( ( ( BrakeOpModes & bom_PS ) == 0 ) + || ( ( ActiveCab != 0 ) + && ( BrakeOpModeFlag != bom_PS ) ) ) { - if ((BrakeOpModeFlag != bom_PS)) - if ((BrakeOpModeFlag < bom_EP) || ((Handle->GetPos(bh_EB) - 0.5) < BrakeCtrlPosR) || - (BrakeHandle != TBrakeHandle::MHZ_EN57)) - dpMainValve = Handle->GetPF(BrakeCtrlPosR, PipePress, temp, dt, EqvtPipePress); - else - dpMainValve = Handle->GetPF(0, PipePress, temp, dt, EqvtPipePress); + if( ( BrakeOpModeFlag < bom_EP ) + || ( ( Handle->GetPos( bh_EB ) - 0.5 ) < BrakeCtrlPosR ) + || ( ( BrakeHandle != TBrakeHandle::MHZ_EN57 ) + && ( BrakeHandle != TBrakeHandle::MHZ_K8P ) ) ) { + dpMainValve = Handle->GetPF( BrakeCtrlPosR, PipePress, temp, dt, EqvtPipePress ); + } + else { + dpMainValve = Handle->GetPF( 0, PipePress, temp, dt, EqvtPipePress ); + } + } if (dpMainValve < 0) // && (PipePressureVal > 0.01) //50 if (Compressor > ScndPipePress) @@ -5528,8 +5536,9 @@ bool TMoverParameters::MaxCurrentSwitch(bool State) bool TMoverParameters::MinCurrentSwitch(bool State) { bool MCS = false; - if (((EngineType == TEngineType::ElectricSeriesMotor) && (IminHi > IminLo)) || (TrainType == dt_EZT)) - { + if( ( ( EngineType == TEngineType::ElectricSeriesMotor ) && ( IminHi > IminLo ) ) + || ( ( TrainType == dt_EZT ) && ( EngineType != TEngineType::ElectricInductionMotor ) ) ) { + if (State && (Imin == IminLo)) { Imin = IminHi; diff --git a/PyInt.cpp b/PyInt.cpp index 042be17d..6765d7b4 100644 --- a/PyInt.cpp +++ b/PyInt.cpp @@ -90,13 +90,11 @@ auto python_taskqueue::init() -> bool { stringioclassname != nullptr ? PyObject_CallObject( stringioclassname, nullptr ) : nullptr ) }; - m_error = { ( + m_stderr = { ( stringioobject == nullptr ? nullptr : PySys_SetObject( "stderr", stringioobject ) != 0 ? nullptr : stringioobject ) }; - if( m_error == nullptr ) { goto release_and_exit; } - if( false == run_file( "abstractscreenrenderer" ) ) { goto release_and_exit; } // release the lock, save the state for future use @@ -315,13 +313,13 @@ python_taskqueue::error() { if( PyErr_Occurred() == nullptr ) { return; } - if( m_error != nullptr ) { + if( m_stderr != nullptr ) { // std err pythona jest buforowane PyErr_Print(); - auto *errortext { PyObject_CallMethod( m_error, "getvalue", nullptr ) }; + auto *errortext { PyObject_CallMethod( m_stderr, "getvalue", nullptr ) }; ErrorLog( PyString_AsString( errortext ) ); // czyscimy bufor na kolejne bledy - PyObject_CallMethod( m_error, "truncate", "i", 0 ); + PyObject_CallMethod( m_stderr, "truncate", "i", 0 ); } else { // nie dziala buffor pythona @@ -343,7 +341,7 @@ python_taskqueue::error() { } auto *tracebacktext { PyObject_Str( traceback ) }; if( tracebacktext != nullptr ) { - WriteLog( PyString_AsString( tracebacktext ) ); + ErrorLog( PyString_AsString( tracebacktext ) ); } else { WriteLog( "Python Interpreter: failed to retrieve the stack traceback" ); diff --git a/PyInt.h b/PyInt.h index 9d96206b..f03f931b 100644 --- a/PyInt.h +++ b/PyInt.h @@ -83,7 +83,7 @@ private: void error(); // members PyObject *m_main { nullptr }; - PyObject *m_error { nullptr }; + PyObject *m_stderr { nullptr }; PyThreadState *m_mainthread{ nullptr }; worker_array m_workers; threading::condition_variable m_condition; // wakes up the workers diff --git a/Train.cpp b/Train.cpp index c6d96739..2da16b35 100644 --- a/Train.cpp +++ b/Train.cpp @@ -543,13 +543,18 @@ PyObject *TTrain::GetTrainState() { PyDict_SetItemString( dict, "velnext", PyGetFloat( driver->VelNext ) ); PyDict_SetItemString( dict, "actualproximitydist", PyGetFloat( driver->ActualProximityDist ) ); // train data + auto const *timetable{ driver->TrainTimetable() }; + PyDict_SetItemString( dict, "trainnumber", PyGetString( driver->TrainName().c_str() ) ); + PyDict_SetItemString( dict, "train_brakingmassratio", PyGetFloat( timetable->BrakeRatio ) ); + PyDict_SetItemString( dict, "train_enginetype", PyGetString( timetable->LocSeries.c_str() ) ); + PyDict_SetItemString( dict, "train_engineload", PyGetFloat( timetable->LocLoad ) ); + PyDict_SetItemString( dict, "train_stationindex", PyGetInt( driver->StationIndex() ) ); auto const stationcount { driver->StationCount() }; PyDict_SetItemString( dict, "train_stationcount", PyGetInt( stationcount ) ); if( stationcount > 0 ) { // timetable stations data, if there's any - auto const *timetable { driver->TrainTimetable() }; for( auto stationidx = 1; stationidx <= stationcount; ++stationidx ) { auto const stationlabel { "train_station" + std::to_string( stationidx ) + "_" }; auto const &timetableline { timetable->TimeTable[ stationidx ] }; @@ -563,7 +568,9 @@ PyObject *TTrain::GetTrainState() { PyDict_SetItemString( dict, ( stationlabel + "dm" ).c_str(), PyGetInt( timetableline.Dm ) ); } } + PyDict_SetItemString( dict, "train_atpassengerstop", PyGetBool( driver->IsAtPassengerStop ) ); // world state data + PyDict_SetItemString( dict, "scenario", PyGetString( Global.SceneryFile.c_str() ) ); PyDict_SetItemString( dict, "hours", PyGetInt( simulation::Time.data().wHour ) ); PyDict_SetItemString( dict, "minutes", PyGetInt( simulation::Time.data().wMinute ) ); PyDict_SetItemString( dict, "seconds", PyGetInt( simulation::Time.second() ) ); @@ -1367,13 +1374,11 @@ void TTrain::OnCommand_trainbrakeoperationmodeincrease(TTrain *Train, command_da if( ( ( Train->mvOccupied->BrakeOpModeFlag << 1 ) & Train->mvOccupied->BrakeOpModes ) != 0 ) { // next mode Train->mvOccupied->BrakeOpModeFlag <<= 1; - // audio feedback - Train->dsbPneumaticSwitch.play(); // visual feedback Train->ggBrakeOperationModeCtrl.UpdateValue( Train->mvOccupied->BrakeOpModeFlag > 0 ? std::log2( Train->mvOccupied->BrakeOpModeFlag ) : - 0 ); + 0 ); // audio fallback } } } @@ -1385,8 +1390,6 @@ void TTrain::OnCommand_trainbrakeoperationmodedecrease(TTrain *Train, command_da if( ( ( Train->mvOccupied->BrakeOpModeFlag >> 1 ) & Train->mvOccupied->BrakeOpModes ) != 0 ) { // previous mode Train->mvOccupied->BrakeOpModeFlag >>= 1; - // audio feedback - Train->dsbPneumaticSwitch.play(); // visual feedback Train->ggBrakeOperationModeCtrl.UpdateValue( Train->mvOccupied->BrakeOpModeFlag > 0 ? @@ -5443,8 +5446,8 @@ bool TTrain::Update( double const Deltatime ) btLampkaRadioStop.Turn( mvOccupied->Radio && mvOccupied->RadioStopFlag ); btLampkaHamulecReczny.Turn(mvOccupied->ManualBrakePos > 0); // NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu - btLampkaDoorLeft.Turn(mvOccupied->DoorLeftOpened); - btLampkaDoorRight.Turn(mvOccupied->DoorRightOpened); + btLampkaDoorLeft.Turn( DynamicObject->dDoorMoveL > 0.0 );// mvOccupied->DoorLeftOpened); + btLampkaDoorRight.Turn( DynamicObject->dDoorMoveR > 0.0 ); //mvOccupied ->DoorRightOpened); btLampkaBlokadaDrzwi.Turn(mvOccupied->DoorBlockedFlag()); btLampkaDoorLockOff.Turn( false == mvOccupied->DoorLockEnabled ); btLampkaDepartureSignal.Turn( mvControlled->DepartureSignal ); @@ -5754,7 +5757,12 @@ bool TTrain::Update( double const Deltatime ) InstrumentLightType == 0 ? mvControlled->Battery || mvControlled->ConverterFlag : InstrumentLightType == 1 ? mvControlled->Mains : InstrumentLightType == 2 ? mvControlled->ConverterFlag : + InstrumentLightType == 3 ? mvControlled->Battery || mvControlled->ConverterFlag : false ) }; + if( InstrumentLightType == 3 ) { + // TODO: link the light state with the state of the master key + InstrumentLightActive = true; + } btInstrumentLight.Turn( InstrumentLightActive && lightpower ); btDashboardLight.Turn( DashboardLightActive && lightpower ); btTimetableLight.Turn( TimetableLightActive && lightpower ); @@ -5812,7 +5820,9 @@ bool TTrain::Update( double const Deltatime ) ggHornLowButton.Update(); ggHornHighButton.Update(); ggWhistleButton.Update(); - ggHelperButton.UpdateValue(DynamicObject->Mechanik->HelperState); + if( DynamicObject->Mechanik != nullptr ) { + ggHelperButton.UpdateValue( DynamicObject->Mechanik->HelperState ); + } ggHelperButton.Update(); for( auto &universal : ggUniversals ) { universal.Update(); @@ -5880,7 +5890,8 @@ bool TTrain::Update( double const Deltatime ) // NOTE: crude way to have the pantographs go back up if they're dropped due to insufficient pressure etc // TODO: rework it into something more elegant, when redoing the whole consist/unit/cab etc arrangement - if( false == DynamicObject->Mechanik->AIControllFlag ) { + if( ( DynamicObject->Mechanik == nullptr ) + || ( false == DynamicObject->Mechanik->AIControllFlag ) ) { // don't mess with the ai driving, at least not while switches don't follow ai-set vehicle state if( ( mvControlled->Battery ) || ( mvControlled->ConverterFlag ) ) { @@ -7298,8 +7309,8 @@ void TTrain::set_cab_controls( int const Cab ) { 0.f ) ); // doors // NOTE: we're relying on the cab models to have switches reversed for the rear cab(?) - ggDoorLeftButton.PutValue( mvOccupied->DoorLeftOpened ? 1.f : 0.f ); - ggDoorRightButton.PutValue( mvOccupied->DoorRightOpened ? 1.f : 0.f ); + ggDoorLeftButton.PutValue( /*mvOccupied->DoorLeftOpened*/ DynamicObject->dDoorMoveL > 0.0 ? 1.f : 0.f ); + ggDoorRightButton.PutValue( /*mvOccupied->DoorRightOpened*/ DynamicObject->dDoorMoveR > 0.0 ? 1.f : 0.f ); // door lock ggDoorSignallingButton.PutValue( mvOccupied->DoorLockEnabled ? @@ -7505,14 +7516,18 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co btInstrumentLight.Load( Parser, DynamicObject ); InstrumentLightType = 0; } - else if( Label == "i-instrumentlight_M:" ) { + else if( Label == "i-instrumentlight_m:" ) { btInstrumentLight.Load( Parser, DynamicObject ); InstrumentLightType = 1; } - else if( Label == "i-instrumentlight_C:" ) { + else if( Label == "i-instrumentlight_c:" ) { btInstrumentLight.Load( Parser, DynamicObject ); InstrumentLightType = 2; } + else if( Label == "i-instrumentlight_a:" ) { + btInstrumentLight.Load( Parser, DynamicObject ); + InstrumentLightType = 3; + } else if (Label == "i-doors:") { int i = Parser.getToken() - 1; @@ -7748,6 +7763,12 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con gauge.Load(Parser, DynamicObject, 0.1); gauge.AssignDouble(&mvOccupied->PipePress); } + else if( Label == "scndpress:" ) { + // manometr przewodu hamulcowego + auto &gauge = Cabine[ Cabindex ].Gauge( -1 ); // pierwsza wolna gałka + gauge.Load( Parser, DynamicObject, 0.1 ); + gauge.AssignDouble( &mvOccupied->ScndPipePress ); + } else if (Label == "limpipepress:") { // manometr zbiornika sterujacego zaworu maszynisty diff --git a/Train.h b/Train.h index e6fc3430..0279f257 100644 --- a/Train.h +++ b/Train.h @@ -508,7 +508,7 @@ public: // reszta może by?publiczna TButton btInstrumentLight; TButton btDashboardLight; TButton btTimetableLight; - int InstrumentLightType{ 0 }; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw. + int InstrumentLightType{ 0 }; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw., 3-rozrzad bool InstrumentLightActive{ false }; bool DashboardLightActive{ false }; bool TimetableLightActive{ false }; diff --git a/driveruipanels.cpp b/driveruipanels.cpp index da9e1ddb..41eb9fea 100644 --- a/driveruipanels.cpp +++ b/driveruipanels.cpp @@ -443,8 +443,8 @@ debug_panel::update_section_vehicle( std::vector &Output ) { std::abs( mover.enrot ) * 60, std::abs( mover.nrot ) * mover.Transmision.Ratio * 60, mover.RventRot * 60, - mover.MotorBlowers[side::front].revolutions, - mover.MotorBlowers[side::rear].revolutions, + std::abs( mover.MotorBlowers[side::front].revolutions ), + std::abs( mover.MotorBlowers[side::rear].revolutions ), mover.dizel_heat.rpmw, mover.dizel_heat.rpmw2 ); @@ -470,6 +470,7 @@ debug_panel::update_section_vehicle( std::vector &Output ) { // brakes mover.fBrakeCtrlPos, mover.LocalBrakePosA, + mover.BrakeOpModeFlag, update_vehicle_brake().c_str(), mover.LoadFlag, // cylinders @@ -482,7 +483,7 @@ debug_panel::update_section_vehicle( std::vector &Output ) { mover.ScndPipePress, mover.CntrlPipePress, // tanks - mover.Volume, + mover.Hamulec->GetBRP(), mover.Compressor, mover.Hamulec->GetCRP() ); diff --git a/renderer.cpp b/renderer.cpp index 6468b8f3..c866d4f1 100644 --- a/renderer.cpp +++ b/renderer.cpp @@ -554,7 +554,9 @@ opengl_renderer::Render_pass( rendermode const Mode ) { // without rain/snow we can render the cab early to limit the overdraw if( ( false == FreeFlyModeFlag ) && ( Global.Overcast <= 1.f ) ) { // precipitation happens when overcast is in 1-2 range +#ifdef EU07_DISABLECABREFLECTIONS switch_units( true, true, false ); +#endif setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix ); // cache shadow colour in case we need to account for cab light auto const shadowcolor { m_shadowcolor }; @@ -577,7 +579,9 @@ opengl_renderer::Render_pass( rendermode const Mode ) { Render_precipitation(); // cab render if( false == FreeFlyModeFlag ) { +#ifdef EU07_DISABLECABREFLECTIONS switch_units( true, true, false ); +#endif setup_shadow_map( m_cabshadowtexture, m_cabshadowtexturematrix ); // cache shadow colour in case we need to account for cab light auto const shadowcolor{ m_shadowcolor }; diff --git a/renderer.h b/renderer.h index 5d3d48b0..f1388c71 100644 --- a/renderer.h +++ b/renderer.h @@ -26,6 +26,7 @@ http://mozilla.org/MPL/2.0/. //#define EU07_USE_DEBUG_CAMERA //#define EU07_USE_DEBUG_SOUNDEMITTERS //#define EU07_USEIMGUIIMPLOPENGL2 +//#define EU07_DISABLECABREFLECTIONS struct opengl_light : public basic_light { diff --git a/scenarioloadermode.cpp b/scenarioloadermode.cpp index e412b25a..0c403aa1 100644 --- a/scenarioloadermode.cpp +++ b/scenarioloadermode.cpp @@ -36,7 +36,7 @@ scenarioloader_mode::init() { bool scenarioloader_mode::update() { - WriteLog( "\nLoading scenario..." ); + WriteLog( "\nLoading scenario \"" + Global.SceneryFile + "\"..." ); auto timestart = std::chrono::system_clock::now(); diff --git a/translation.cpp b/translation.cpp index 7881869b..469ce887 100644 --- a/translation.cpp +++ b/translation.cpp @@ -57,7 +57,7 @@ init() { "Controllers:\n master: %d(%d), secondary: %s\nEngine output: %.1f, current: %.0f\nRevolutions:\n engine: %.0f, motors: %.0f\n engine fans: %.0f, motor fans: %.0f+%.0f, cooling fans: %.0f+%.0f", " (shunt mode)", "\nTemperatures:\n engine: %.2f, oil: %.2f, water: %.2f%c%.2f", - "Brakes:\n train: %.2f, independent: %.2f, delay: %s, load flag: %d\nBrake cylinder pressures:\n train: %.2f, independent: %.2f, status: 0x%.2x\nPipe pressures:\n brake: %.2f (hat: %.2f), main: %.2f, control: %.2f\nTank pressures:\n auxiliary: %.2f, main: %.2f, control: %.2f", + "Brakes:\n train: %.2f, independent: %.2f, mode: %d, delay: %s, load flag: %d\nBrake cylinder pressures:\n train: %.2f, independent: %.2f, status: 0x%.2x\nPipe pressures:\n brake: %.2f (hat: %.2f), main: %.2f, control: %.2f\nTank pressures:\n auxiliary: %.2f, main: %.2f, control: %.2f", " pantograph: %.2f%cMT", "Forces:\n tractive: %.1f, brake: %.1f, friction: %.2f%s\nAcceleration:\n tangential: %.2f, normal: %.2f (path radius: %s)\nVelocity: %.2f, distance traveled: %.2f\nPosition: [%.2f, %.2f, %.2f]", @@ -72,6 +72,7 @@ init() { "brake acting speed", "brake acting speed: cargo", "brake acting speed: rapid", + "brake operation mode", "motor overload relay threshold", "water pump", "water pump breaker", @@ -194,7 +195,7 @@ init() { "Nastawniki:\n glowny: %d(%d), dodatkowy: %s\nMoc silnika: %.1f, prad silnika: %.0f\nObroty:\n silnik: %.0f, motory: %.0f\n went.silnika: %.0f, went.motorow: %.0f+%.0f, went.chlodnicy: %.0f+%.0f", " (tryb manewrowy)", "\nTemperatury:\n silnik: %.2f, olej: %.2f, woda: %.2f%c%.2f", - "Hamulce:\n zespolony: %.2f, pomocniczy: %.2f, nastawa: %s, ladunek: %d\nCisnienie w cylindrach:\n zespolony: %.2f, pomocniczy: %.2f, status: 0x%.2x\nCisnienia w przewodach:\n glowny: %.2f (kapturek: %.2f), zasilajacy: %.2f, kontrolny: %.2f\nCisnienia w zbiornikach:\n pomocniczy: %.2f, glowny: %.2f, sterujacy: %.2f", + "Hamulce:\n zespolony: %.2f, pomocniczy: %.2f, tryb: %d, nastawa: %s, ladunek: %d\nCisnienie w cylindrach:\n zespolony: %.2f, pomocniczy: %.2f, status: 0x%.2x\nCisnienia w przewodach:\n glowny: %.2f (kapturek: %.2f), zasilajacy: %.2f, kontrolny: %.2f\nCisnienia w zbiornikach:\n pomocniczy: %.2f, glowny: %.2f, sterujacy: %.2f", " pantograf: %.2f%cZG", "Sily:\n napedna: %.1f, hamowania: %.1f, tarcie: %.2f%s\nPrzyspieszenia:\n styczne: %.2f, normalne: %.2f (promien: %s)\nPredkosc: %.2f, pokonana odleglosc: %.2f\nPozycja: [%.2f, %.2f, %.2f]", @@ -209,6 +210,7 @@ init() { "nastawa hamulca", "nastawa hamulca: towarowy", "nastawa hamulca: pospieszny", + "tryb pracy hamulca", "zakres pradu rozruchu", "pompa wody", "wylacznik samoczynny pompy wody", @@ -318,6 +320,7 @@ init() { "brakeprofile_sw:", "brakeprofileg_sw:", "brakeprofiler_sw:", + "brakeopmode_sw:", "maxcurrent_sw:", "waterpump_sw:", "waterpumpbreaker_sw:", diff --git a/translation.h b/translation.h index 4d40b762..5bb378b1 100644 --- a/translation.h +++ b/translation.h @@ -61,6 +61,7 @@ enum string { cab_brakeprofile_sw, cab_brakeprofileg_sw, cab_brakeprofiler_sw, + cab_brakeopmode_sw, cab_maxcurrent_sw, cab_waterpump_sw, cab_waterpumpbreaker_sw, diff --git a/version.h b/version.h index 6cf18dee..88afd941 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 18 -#define VERSION_MINOR 1223 +#define VERSION_MINOR 1231 #define VERSION_REVISION 0