From 3456fbd651b13ef741b877e6447e5fe8e5731995 Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Wed, 1 Nov 2017 03:25:54 +0100 Subject: [PATCH] improved recognition and handling of light emitting vehicles --- Driver.cpp | 4 +- DynObj.cpp | 75 +++++++++++++----------- DynObj.h | 3 +- McZapkie/MOVER.h | 28 ++++----- Train.cpp | 144 +++++++++++++++++++++++------------------------ World.cpp | 14 ++--- lightarray.cpp | 33 ++++------- simulation.cpp | 9 +-- 8 files changed, 155 insertions(+), 155 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 01478ac6..adce34d5 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -1793,7 +1793,7 @@ void TController::AutoRewident() } if (mvOccupied->TrainType == dt_EZT) { - fAccThreshold = std::max(-fBrake_a0[BrakeAccTableSize] - 8 * fBrake_a1[BrakeAccTableSize], -0.75); + fAccThreshold = std::max(-fBrake_a0[BrakeAccTableSize] - 8 * fBrake_a1[BrakeAccTableSize], -0.6); fBrakeReaction = 0.25; } else if (ustaw > 16) @@ -5662,7 +5662,7 @@ bool TController::IsStop() double TController::TrackBlock() const { - return pVehicles[ TMoverParameters::side::front ]->fTrackBlock; + return pVehicles[ side::front ]->fTrackBlock; } void TController::MoveTo(TDynamicObject *to) diff --git a/DynObj.cpp b/DynObj.cpp index 4156d8be..b30cbabb 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -1274,21 +1274,21 @@ void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir) { if (MyScanDir > 0) { // pojazd od strony sprzęgu 0 if( ( PrevConnected != nullptr ) - && ( MoverParameters->Couplers[ TMoverParameters::side::front ].CoupleDist > MinDist ) ) { + && ( MoverParameters->Couplers[ side::front ].CoupleDist > MinDist ) ) { // sprzęgi wirtualne zawsze przekraczają - if( ( PrevConnectedNo == TMoverParameters::side::front ? + if( ( PrevConnectedNo == side::front ? PrevConnected->PrevConnected : PrevConnected->NextConnected ) == this ) { // Ra: nie rozłączamy znalezionego, jeżeli nie do nas podłączony // (może jechać w innym kierunku) PrevConnected->MoverParameters->Couplers[PrevConnectedNo].Connected = nullptr; - if( PrevConnectedNo == TMoverParameters::side::front ) { + if( PrevConnectedNo == side::front ) { // sprzęg 0 nie podłączony PrevConnected->PrevConnectedNo = 2; PrevConnected->PrevConnected = nullptr; } - else if( PrevConnectedNo == TMoverParameters::side::rear ) { + else if( PrevConnectedNo == side::rear ) { // sprzęg 1 nie podłączony PrevConnected->NextConnectedNo = 2; PrevConnected->NextConnected = nullptr; @@ -1297,27 +1297,27 @@ void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir) { // za to zawsze odłączamy siebie PrevConnected = nullptr; PrevConnectedNo = 2; // sprzęg 0 nie podłączony - MoverParameters->Couplers[ TMoverParameters::side::front ].Connected = nullptr; + MoverParameters->Couplers[ side::front ].Connected = nullptr; } } else { // pojazd od strony sprzęgu 1 if( ( NextConnected != nullptr ) - && ( MoverParameters->Couplers[ TMoverParameters::side::rear ].CoupleDist > MinDist ) ) { + && ( MoverParameters->Couplers[ side::rear ].CoupleDist > MinDist ) ) { // sprzęgi wirtualne zawsze przekraczają - if( ( NextConnectedNo == TMoverParameters::side::front ? + if( ( NextConnectedNo == side::front ? NextConnected->PrevConnected : NextConnected->NextConnected ) == this) { // Ra: nie rozłączamy znalezionego, jeżeli nie do nas podłączony // (może jechać w innym kierunku) NextConnected->MoverParameters->Couplers[ NextConnectedNo ].Connected = nullptr; - if( NextConnectedNo == TMoverParameters::side::front ) { + if( NextConnectedNo == side::front ) { // sprzęg 0 nie podłączony NextConnected->PrevConnectedNo = 2; NextConnected->PrevConnected = nullptr; } - else if( NextConnectedNo == TMoverParameters::side::rear ) { + else if( NextConnectedNo == side::rear ) { // sprzęg 1 nie podłączony NextConnected->NextConnectedNo = 2; NextConnected->NextConnected = nullptr; @@ -1409,7 +1409,7 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance ) // siebie można bezpiecznie podłączyć jednostronnie do znalezionego MoverParameters->Attach( mycoupler, foundcoupler, foundobject->MoverParameters, coupling::faux ); // MoverParameters->Couplers[MyCouplFound].Render=false; //wirtualnego nie renderujemy - if( mycoupler == TMoverParameters::side::front ) { + if( mycoupler == side::front ) { PrevConnected = foundobject; // pojazd od strony sprzęgu 0 PrevConnectedNo = foundcoupler; } @@ -1420,7 +1420,7 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance ) if( foundobject->MoverParameters->Couplers[ foundcoupler ].CouplingFlag == coupling::faux ) { // Ra: wpinamy się wirtualnym tylko jeśli znaleziony ma wirtualny sprzęg - if( ( foundcoupler == TMoverParameters::side::front ? + if( ( foundcoupler == side::front ? foundobject->PrevConnected : foundobject->NextConnected ) != this ) { @@ -1428,13 +1428,13 @@ void TDynamicObject::ABuScanObjects( int Direction, double Distance ) // otherwise we risk leaving the target's connected vehicle with active one-side connection foundobject->CouplersDettach( 1.0, - ( foundcoupler == TMoverParameters::side::front ? + ( foundcoupler == side::front ? 1 : -1 ) ); } foundobject->MoverParameters->Attach( foundcoupler, mycoupler, this->MoverParameters, coupling::faux ); - if( foundcoupler == TMoverParameters::side::front ) { + if( foundcoupler == side::front ) { // jeśli widoczny sprzęg 0 znalezionego if( ( DebugModeFlag ) && ( foundobject->PrevConnected ) @@ -1551,8 +1551,6 @@ TDynamicObject::TDynamicObject() iAxleFirst = 0; // numer pierwszej osi w kierunku ruchu (przełączenie // następuje, gdy osie sa na // tym samym torze) - iInventory = 0; // flagi bitowe posiadanych submodeli (zaktualizuje się po - // wczytaniu MMD) RaLightsSet(0, 0); // początkowe zerowanie stanu świateł // Ra: domyślne ilości animacji dla zgodności wstecz (gdy brak ilości podanych // w MMD) @@ -1929,19 +1927,19 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424" btEndSignals21.Init("endsignal23", mdModel, false); btEndSignals13.Init("endsignal12", mdModel, false); btEndSignals23.Init("endsignal22", mdModel, false); - iInventory |= btEndSignals11.Active() ? 0x01 : 0; // informacja, czy ma poszczególne światła - iInventory |= btEndSignals21.Active() ? 0x02 : 0; - iInventory |= btEndSignals13.Active() ? 0x04 : 0; - iInventory |= btEndSignals23.Active() ? 0x08 : 0; + iInventory[ side::front ] |= btEndSignals11.Active() ? light::redmarker_left : 0; // informacja, czy ma poszczególne światła + iInventory[ side::front ] |= btEndSignals13.Active() ? light::redmarker_right : 0; + iInventory[ side::rear ] |= btEndSignals21.Active() ? light::redmarker_left : 0; + iInventory[ side::rear ] |= btEndSignals23.Active() ? light::redmarker_right : 0; // ABu: to niestety zostawione dla kompatybilnosci modeli: btEndSignals1.Init("endsignals1", mdModel, false); btEndSignals2.Init("endsignals2", mdModel, false); btEndSignalsTab1.Init("endtab1", mdModel, false); btEndSignalsTab2.Init("endtab2", mdModel, false); - iInventory |= btEndSignals1.Active() ? 0x10 : 0; - iInventory |= btEndSignals2.Active() ? 0x20 : 0; - iInventory |= btEndSignalsTab1.Active() ? 0x40 : 0; // tabliczki blaszane - iInventory |= btEndSignalsTab2.Active() ? 0x80 : 0; + iInventory[ side::front ] |= btEndSignals1.Active() ? ( light::redmarker_left | light::redmarker_right ) : 0; + iInventory[ side::front ] |= btEndSignalsTab1.Active() ? light::rearendsignals : 0; // tabliczki blaszane + iInventory[ side::rear ] |= btEndSignals2.Active() ? ( light::redmarker_left | light::redmarker_right ) : 0; + iInventory[ side::rear ] |= btEndSignalsTab2.Active() ? light::rearendsignals : 0; // ABu Uwaga! tu zmienic w modelu! btHeadSignals11.Init("headlamp13", mdModel, false); // lewe btHeadSignals12.Init("headlamp11", mdModel, false); // górne @@ -1949,7 +1947,13 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424" btHeadSignals21.Init("headlamp23", mdModel, false); btHeadSignals22.Init("headlamp21", mdModel, false); btHeadSignals23.Init("headlamp22", mdModel, false); - btMechanik1.Init("mechanik1", mdLowPolyInt, false); + iInventory[ side::front ] |= btHeadSignals11.Active() ? light::headlight_left : 0; + iInventory[ side::front ] |= btHeadSignals12.Active() ? light::headlight_upper : 0; + iInventory[ side::front ] |= btHeadSignals13.Active() ? light::headlight_right : 0; + iInventory[ side::rear ] |= btHeadSignals21.Active() ? light::headlight_left : 0; + iInventory[ side::rear ] |= btHeadSignals22.Active() ? light::headlight_upper : 0; + iInventory[ side::rear ] |= btHeadSignals23.Active() ? light::headlight_right : 0; + btMechanik1.Init("mechanik1", mdLowPolyInt, false); btMechanik2.Init("mechanik2", mdLowPolyInt, false); TurnOff(); // resetowanie zmiennych submodeli @@ -4984,7 +4988,7 @@ void TDynamicObject::RaLightsSet(int head, int rear) // pojazdu if (!MoverParameters) return; // może tego nie być na początku - if (rear == 2 + 32 + 64) + if (rear == ( light::redmarker_left | light::redmarker_right | light::rearendsignals ) ) { // jeśli koniec pociągu, to trzeba ustalić, czy // jest tam czynna lokomotywa // EN57 może nie mieć końcówek od środka członu @@ -4993,15 +4997,20 @@ void TDynamicObject::RaLightsSet(int head, int rear) { // jeśli ma zarówno światła jak i końcówki, ustalić, czy jest w stanie // aktywnym // np. lokomotywa na zimno będzie mieć końcówki a nie światła - rear = 64; // tablice blaszane + rear = light::rearendsignals; // tablice blaszane // trzeba to uzależnić od "załączenia baterii" w pojeździe } - if (rear == 2 + 32 + 64) // jeśli nadal obydwie możliwości - if (iInventory & - (iDirection ? 0x2A : 0x15)) // czy ma jakieś światła czerowone od danej strony - rear = 2 + 32; // dwa światła czerwone - else - rear = 64; // tablice blaszane + if( rear == ( light::redmarker_left | light::redmarker_right | light::rearendsignals ) ) // jeśli nadal obydwie możliwości + if( iInventory[ + ( iDirection ? + side::rear : + side::front ) ] & ( light::redmarker_left | light::redmarker_right ) ) { + // czy ma jakieś światła czerowone od danej strony + rear = ( light::redmarker_left | light::redmarker_right ); // dwa światła czerwone + } + else { + rear = light::rearendsignals; // tablice blaszane + } } if (iDirection) // w zależności od kierunku pojazdu w składzie { // jesli pojazd stoi sprzęgiem 0 w stronę czoła @@ -5423,7 +5432,7 @@ vehicle_table::update_traction( TDynamicObject *Vehicle ) { // pętla po pantografach auto pantograph { Vehicle->pants[ pantographindex ].fParamPants }; if( true == ( - pantographindex == TMoverParameters::side::front ? + pantographindex == side::front ? Vehicle->MoverParameters->PantFrontUp : Vehicle->MoverParameters->PantRearUp ) ) { // jeśli pantograf podniesiony diff --git a/DynObj.h b/DynObj.h index fbdbd0da..7f8aeb2f 100644 --- a/DynObj.h +++ b/DynObj.h @@ -340,7 +340,7 @@ private: bool bBrakeAcc; TRealSound rsUnbrake; // yB - odglos luzowania float ModCamRot; - int iInventory; // flagi bitowe posiadanych submodeli (np. świateł) + int iInventory[ 2 ] { 0, 0 }; // flagi bitowe posiadanych submodeli (np. świateł) void TurnOff(); public: @@ -466,6 +466,7 @@ private: void RadioStop(); void Damage(char flag); void RaLightsSet(int head, int rear); + int LightList( side const Side ) const { return iInventory[ Side ]; } TDynamicObject * FirstFind(int &coupler_nr, int cf = 1); float GetEPP(); // wyliczanie sredniego cisnienia w PG int DirectionSet(int d); // ustawienie kierunku w składzie diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index 2d84007d..ce949609 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -140,6 +140,11 @@ static int const ctrain_passenger = 16; //mostek przejściowy static int const ctrain_scndpneumatic = 32; //przewody 8 atm (żółte; zasilanie powietrzem) static int const ctrain_heating = 64; //przewody ogrzewania WN static int const ctrain_depot = 128; //nie rozłączalny podczas zwykłych manewrów (międzyczłonowy), we wpisie wartość ujemna +// vehicle sides; exclusive +enum side { + front = 0, + rear +}; // possible coupling types; can be combined enum coupling { faux = 0x0, @@ -162,6 +167,16 @@ enum range { enum start { manual, automatic +}; +// recognized vehicle light locations and types; can be combined +enum light { + + headlight_left = 0x01, + redmarker_left = 0x02, + headlight_upper = 0x04, + headlight_right = 0x10, + redmarker_right = 0x20, + rearendsignals = 0x40 }; /*typ hamulca elektrodynamicznego*/ static int const dbrake_none = 0; @@ -699,15 +714,6 @@ public: int LightsDefPos = 1; bool LightsWrap = false; int Lights[2][17]; // pozycje świateł, przód - tył, 1 .. 16 - enum light { - - headlight_left = 0x01, - redmarker_left = 0x02, - headlight_upper = 0x04, - headlight_right = 0x10, - redmarker_right = 0x20, - rearendsignals = 0x40 - }; int ScndInMain{ 0 }; /*zaleznosc bocznika od nastawnika*/ bool MBrake = false; /*Czy jest hamulec reczny*/ double StopBrakeDecc = 0.0; @@ -802,10 +808,6 @@ public: TRotation Rot; std::string Name; /*nazwa wlasna*/ TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami - enum side { - front = 0, - rear - }; #ifdef EU07_USE_OLD_HVCOUPLERS double HVCouplers[ 2 ][ 2 ]; //przewod WN enum hvcoupler { diff --git a/Train.cpp b/Train.cpp index c76f97ec..9ab64c0f 100644 --- a/Train.cpp +++ b/Train.cpp @@ -2074,26 +2074,26 @@ void TTrain::OnCommand_headlighttoggleleft( TTrain *Train, command_data const &C return; } - int const lightsindex = + int const vehicleside = ( Train->mvOccupied->ActiveCab == 1 ? - 0 : - 1 ); + side::front : + side::rear ); if( Command.action == GLFW_PRESS ) { // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_left ) == 0 ) { + if( ( Train->DynamicObject->iLights[ vehicleside ] & light::headlight_left ) == 0 ) { // turn on - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left; + Train->DynamicObject->iLights[ vehicleside ] ^= light::headlight_left; // visual feedback Train->ggLeftLightButton.UpdateValue( 1.0, Train->dsbSwitch ); // if the light is controlled by 3-way switch, disable marker light if( Train->ggLeftEndLightButton.SubModel == nullptr ) { - Train->DynamicObject->iLights[ lightsindex ] &= ~TMoverParameters::light::redmarker_left; + Train->DynamicObject->iLights[ vehicleside ] &= ~light::redmarker_left; } } else { //turn off - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left; + Train->DynamicObject->iLights[ vehicleside ] ^= light::headlight_left; // visual feedback Train->ggLeftLightButton.UpdateValue( 0.0, Train->dsbSwitch ); } @@ -2107,26 +2107,26 @@ void TTrain::OnCommand_headlighttoggleright( TTrain *Train, command_data const & return; } - int const lightsindex = + int const vehicleside = ( Train->mvOccupied->ActiveCab == 1 ? - 0 : - 1 ); + side::front : + side::rear ); if( Command.action == GLFW_PRESS ) { // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_right ) == 0 ) { + if( ( Train->DynamicObject->iLights[ vehicleside ] & light::headlight_right ) == 0 ) { // turn on - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right; + Train->DynamicObject->iLights[ vehicleside ] ^= light::headlight_right; // visual feedback Train->ggRightLightButton.UpdateValue( 1.0, Train->dsbSwitch ); // if the light is controlled by 3-way switch, disable marker light if( Train->ggRightEndLightButton.SubModel == nullptr ) { - Train->DynamicObject->iLights[ lightsindex ] &= ~TMoverParameters::light::redmarker_right; + Train->DynamicObject->iLights[ vehicleside ] &= ~light::redmarker_right; } } else { //turn off - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right; + Train->DynamicObject->iLights[ vehicleside ] ^= light::headlight_right; // visual feedback Train->ggRightLightButton.UpdateValue( 0.0, Train->dsbSwitch ); } @@ -2140,22 +2140,22 @@ void TTrain::OnCommand_headlighttoggleupper( TTrain *Train, command_data const & return; } - int const lightsindex = + int const vehicleside = ( Train->mvOccupied->ActiveCab == 1 ? - 0 : - 1 ); + side::front : + side::rear ); if( Command.action == GLFW_PRESS ) { // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_upper ) == 0 ) { + if( ( Train->DynamicObject->iLights[ vehicleside ] & light::headlight_upper ) == 0 ) { // turn on - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_upper; + Train->DynamicObject->iLights[ vehicleside ] ^= light::headlight_upper; // visual feedback Train->ggUpperLightButton.UpdateValue( 1.0, Train->dsbSwitch ); } else { //turn off - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_upper; + Train->DynamicObject->iLights[ vehicleside ] ^= light::headlight_upper; // visual feedback Train->ggUpperLightButton.UpdateValue( 0.0, Train->dsbSwitch ); } @@ -2169,16 +2169,16 @@ void TTrain::OnCommand_redmarkertoggleleft( TTrain *Train, command_data const &C return; } - int const lightsindex = + int const vehicleside = ( Train->mvOccupied->ActiveCab == 1 ? - 0 : - 1 ); + side::front : + side::rear ); if( Command.action == GLFW_PRESS ) { // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_left ) == 0 ) { + if( ( Train->DynamicObject->iLights[ vehicleside ] & light::redmarker_left ) == 0 ) { // turn on - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left; + Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_left; // visual feedback if( Train->ggLeftEndLightButton.SubModel != nullptr ) { Train->ggLeftEndLightButton.UpdateValue( 1.0, Train->dsbSwitch ); @@ -2188,12 +2188,12 @@ void TTrain::OnCommand_redmarkertoggleleft( TTrain *Train, command_data const &C // this is crude, but for now will do Train->ggLeftLightButton.UpdateValue( -1.0, Train->dsbSwitch ); // if the light is controlled by 3-way switch, disable the headlight - Train->DynamicObject->iLights[ lightsindex ] &= ~TMoverParameters::light::headlight_left; + Train->DynamicObject->iLights[ vehicleside ] &= ~light::headlight_left; } } else { //turn off - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left; + Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_left; // visual feedback if( Train->ggLeftEndLightButton.SubModel != nullptr ) { Train->ggLeftEndLightButton.UpdateValue( 0.0, Train->dsbSwitch ); @@ -2214,16 +2214,16 @@ void TTrain::OnCommand_redmarkertoggleright( TTrain *Train, command_data const & return; } - int const lightsindex = + int const vehicleside = ( Train->mvOccupied->ActiveCab == 1 ? - 0 : - 1 ); + side::front : + side::rear ); if( Command.action == GLFW_PRESS ) { // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_right ) == 0 ) { + if( ( Train->DynamicObject->iLights[ vehicleside ] & light::redmarker_right ) == 0 ) { // turn on - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right; + Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_right; // visual feedback if( Train->ggRightEndLightButton.SubModel != nullptr ) { Train->ggRightEndLightButton.UpdateValue( 1.0, Train->dsbSwitch ); @@ -2233,12 +2233,12 @@ void TTrain::OnCommand_redmarkertoggleright( TTrain *Train, command_data const & // this is crude, but for now will do Train->ggRightLightButton.UpdateValue( -1.0, Train->dsbSwitch ); // if the light is controlled by 3-way switch, disable the headlight - Train->DynamicObject->iLights[ lightsindex ] &= ~TMoverParameters::light::headlight_right; + Train->DynamicObject->iLights[ vehicleside ] &= ~light::headlight_right; } } else { //turn off - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right; + Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_right; // visual feedback if( Train->ggRightEndLightButton.SubModel != nullptr ) { Train->ggRightEndLightButton.UpdateValue( 0.0, Train->dsbSwitch ); @@ -2259,23 +2259,23 @@ void TTrain::OnCommand_headlighttogglerearleft( TTrain *Train, command_data cons return; } - int const lightsindex = + int const vehicleside = ( Train->mvOccupied->ActiveCab == 1 ? - 1 : - 0 ); + side::rear : + side::front ); if( Command.action == GLFW_PRESS ) { // NOTE: we toggle the light on opposite side, as 'rear right' is 'front left' on the rear end etc // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_right ) == 0 ) { + if( ( Train->DynamicObject->iLights[ vehicleside ] & light::headlight_right ) == 0 ) { // turn on - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right; + Train->DynamicObject->iLights[ vehicleside ] ^= light::headlight_right; // visual feedback Train->ggRearLeftLightButton.UpdateValue( 1.0, Train->dsbSwitch ); } else { //turn off - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_right; + Train->DynamicObject->iLights[ vehicleside ] ^= light::headlight_right; // visual feedback Train->ggRearLeftLightButton.UpdateValue( 0.0, Train->dsbSwitch ); } @@ -2289,23 +2289,23 @@ void TTrain::OnCommand_headlighttogglerearright( TTrain *Train, command_data con return; } - int const lightsindex = + int const vehicleside = ( Train->mvOccupied->ActiveCab == 1 ? - 1 : - 0 ); + side::rear : + side::front ); if( Command.action == GLFW_PRESS ) { // NOTE: we toggle the light on opposite side, as 'rear right' is 'front left' on the rear end etc // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_left ) == 0 ) { + if( ( Train->DynamicObject->iLights[ vehicleside ] & light::headlight_left ) == 0 ) { // turn on - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left; + Train->DynamicObject->iLights[ vehicleside ] ^= light::headlight_left; // visual feedback Train->ggRearRightLightButton.UpdateValue( 1.0, Train->dsbSwitch ); } else { //turn off - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_left; + Train->DynamicObject->iLights[ vehicleside ] ^= light::headlight_left; // visual feedback Train->ggRearRightLightButton.UpdateValue( 0.0, Train->dsbSwitch ); } @@ -2319,22 +2319,22 @@ void TTrain::OnCommand_headlighttogglerearupper( TTrain *Train, command_data con return; } - int const lightsindex = + int const vehicleside = ( Train->mvOccupied->ActiveCab == 1 ? - 1 : - 0 ); + side::rear : + side::front ); if( Command.action == GLFW_PRESS ) { // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_upper ) == 0 ) { + if( ( Train->DynamicObject->iLights[ vehicleside ] & light::headlight_upper ) == 0 ) { // turn on - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_upper; + Train->DynamicObject->iLights[ vehicleside ] ^= light::headlight_upper; // visual feedback Train->ggRearUpperLightButton.UpdateValue( 1.0, Train->dsbSwitch ); } else { //turn off - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::headlight_upper; + Train->DynamicObject->iLights[ vehicleside ] ^= light::headlight_upper; // visual feedback Train->ggRearUpperLightButton.UpdateValue( 0.0, Train->dsbSwitch ); } @@ -2348,23 +2348,23 @@ void TTrain::OnCommand_redmarkertogglerearleft( TTrain *Train, command_data cons return; } - int const lightsindex = + int const vehicleside = ( Train->mvOccupied->ActiveCab == 1 ? - 1 : - 0 ); + side::rear : + side::front ); if( Command.action == GLFW_PRESS ) { // NOTE: we toggle the light on opposite side, as 'rear right' is 'front left' on the rear end etc // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_right ) == 0 ) { + if( ( Train->DynamicObject->iLights[ vehicleside ] & light::redmarker_right ) == 0 ) { // turn on - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right; + Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_right; // visual feedback Train->ggRearLeftEndLightButton.UpdateValue( 1.0, Train->dsbSwitch ); } else { //turn off - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_right; + Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_right; // visual feedback Train->ggRearLeftEndLightButton.UpdateValue( 0.0, Train->dsbSwitch ); } @@ -2378,23 +2378,23 @@ void TTrain::OnCommand_redmarkertogglerearright( TTrain *Train, command_data con return; } - int const lightsindex = + int const vehicleside = ( Train->mvOccupied->ActiveCab == 1 ? - 1 : - 0 ); + side::rear : + side::front ); if( Command.action == GLFW_PRESS ) { // NOTE: we toggle the light on opposite side, as 'rear right' is 'front left' on the rear end etc // only reacting to press, so the switch doesn't flip back and forth if key is held down - if( ( Train->DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_left ) == 0 ) { + if( ( Train->DynamicObject->iLights[ vehicleside ] & light::redmarker_left ) == 0 ) { // turn on - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left; + Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_left; // visual feedback Train->ggRearRightEndLightButton.UpdateValue( 1.0, Train->dsbSwitch ); } else { //turn off - Train->DynamicObject->iLights[ lightsindex ] ^= TMoverParameters::light::redmarker_left; + Train->DynamicObject->iLights[ vehicleside ] ^= light::redmarker_left; // visual feedback Train->ggRearRightEndLightButton.UpdateValue( 0.0, Train->dsbSwitch ); } @@ -6706,21 +6706,21 @@ void TTrain::set_cab_controls() { ggMaxCurrentCtrl.PutValue( 1.0 ); } // lights - int const lightsindex = + int const vehicleside = ( mvOccupied->ActiveCab == 1 ? - 0 : - 1 ); + side::front : + side::rear ); - if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_left ) != 0 ) { + if( ( DynamicObject->iLights[ vehicleside ] & light::headlight_left ) != 0 ) { ggLeftLightButton.PutValue( 1.0 ); } - if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_right ) != 0 ) { + if( ( DynamicObject->iLights[ vehicleside ] & light::headlight_right ) != 0 ) { ggRightLightButton.PutValue( 1.0 ); } - if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::headlight_upper ) != 0 ) { + if( ( DynamicObject->iLights[ vehicleside ] & light::headlight_upper ) != 0 ) { ggUpperLightButton.PutValue( 1.0 ); } - if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_left ) != 0 ) { + if( ( DynamicObject->iLights[ vehicleside ] & light::redmarker_left ) != 0 ) { if( ggLeftEndLightButton.SubModel != nullptr ) { ggLeftEndLightButton.PutValue( 1.0 ); } @@ -6728,7 +6728,7 @@ void TTrain::set_cab_controls() { ggLeftLightButton.PutValue( -1.0 ); } } - if( ( DynamicObject->iLights[ lightsindex ] & TMoverParameters::light::redmarker_right ) != 0 ) { + if( ( DynamicObject->iLights[ vehicleside ] & light::redmarker_right ) != 0 ) { if( ggRightEndLightButton.SubModel != nullptr ) { ggRightEndLightButton.PutValue( 1.0 ); } diff --git a/World.cpp b/World.cpp index 7949b346..65b364f5 100644 --- a/World.cpp +++ b/World.cpp @@ -707,9 +707,9 @@ void TWorld::OnKeyDown(int cKey) CouplNr = 0; // z [-1,1] zrobić [0,1] int mask, set = 0; // Ra: [Shift]+[Ctrl]+[T] odpala mi jakąś idiotyczną zmianę tapety pulpitu :/ if (Global::shiftState) // z [Shift] zapalanie - set = mask = TMoverParameters::light::rearendsignals; // bez [Ctrl] założyć tabliczki + set = mask = light::rearendsignals; // bez [Ctrl] założyć tabliczki else if (Global::ctrlState) - set = mask = ( TMoverParameters::light::redmarker_left | TMoverParameters::light::redmarker_right ); // z [Ctrl] zapalić światła czerwone + set = mask = ( light::redmarker_left | light::redmarker_right ); // z [Ctrl] zapalić światła czerwone else mask = 2 + 32 + 64; // wyłączanie ściąga wszystko if (((vehicle->iLights[CouplNr]) & mask) != set) @@ -1435,15 +1435,15 @@ TWorld::Update_UI() { "; TC:" + to_string( vehicle->MoverParameters->TotalCurrent, 0 ); auto const frontcouplerhighvoltage = - to_string( vehicle->MoverParameters->Couplers[ TMoverParameters::side::front ].power_high.voltage, 0 ) + to_string( vehicle->MoverParameters->Couplers[ side::front ].power_high.voltage, 0 ) + "@" - + to_string( vehicle->MoverParameters->Couplers[ TMoverParameters::side::front ].power_high.current, 0 ); + + to_string( vehicle->MoverParameters->Couplers[ side::front ].power_high.current, 0 ); auto const rearcouplerhighvoltage = - to_string( vehicle->MoverParameters->Couplers[ TMoverParameters::side::rear ].power_high.voltage, 0 ) + to_string( vehicle->MoverParameters->Couplers[ side::rear ].power_high.voltage, 0 ) + "@" - + to_string( vehicle->MoverParameters->Couplers[ TMoverParameters::side::rear ].power_high.current, 0 ); + + to_string( vehicle->MoverParameters->Couplers[ side::rear ].power_high.current, 0 ); uitextline2 += ", HV: "; - if( vehicle->MoverParameters->Couplers[ TMoverParameters::side::front ].power_high.local == false ) { + if( vehicle->MoverParameters->Couplers[ side::front ].power_high.local == false ) { uitextline2 += "(" + frontcouplerhighvoltage + ")-" + ":F" + ( vehicle->DirectionGet() ? "<<" : ">>" ) + "R:" diff --git a/lightarray.cpp b/lightarray.cpp index f0486b7f..9655da56 100644 --- a/lightarray.cpp +++ b/lightarray.cpp @@ -23,8 +23,8 @@ light_array::insert( TDynamicObject const *Owner ) { // we're only storing lights for locos, which have two sets of lights, front and rear // for a more generic role this function would have to be tweaked to add vehicle type-specific light combinations - data.emplace_back( Owner, 0 ); - data.emplace_back( Owner, 1 ); + data.emplace_back( Owner, side::front ); + data.emplace_back( Owner, side::rear ); } void @@ -44,7 +44,7 @@ light_array::update() { for( auto &light : data ) { // update light parameters to match current data of the owner - if( light.index == 0 ) { + if( light.index == side::front ) { // front light set light.position = light.owner->GetPosition() + ( light.owner->VectorFront() * light.owner->GetLength() * 0.4 ); light.direction = glm::make_vec3( light.owner->VectorFront().getArray() ); @@ -57,34 +57,25 @@ light_array::update() { light.direction.z = -light.direction.z; } // determine intensity of this light set - if( ( true == light.owner->MoverParameters->Battery ) || ( true == light.owner->MoverParameters->ConverterFlag ) ) { + if( ( true == light.owner->MoverParameters->Battery ) + || ( true == light.owner->MoverParameters->ConverterFlag ) ) { // with power on, the intensity depends on the state of activated switches - auto const &lightbits = light.owner->iLights[ light.index ]; + // first we cross-check the list of enabled lights with the lights installed in the vehicle... + auto const lights { light.owner->iLights[ light.index ] & light.owner->LightList( static_cast( light.index ) ) }; + // ...then check their individual state light.count = 0 - + ( ( lightbits & TMoverParameters::light::headlight_left ) ? 1 : 0 ) - + ( ( lightbits & TMoverParameters::light::headlight_right ) ? 1 : 0 ) - + ( ( lightbits & TMoverParameters::light::headlight_upper ) ? 1 : 0 ); + + ( ( lights & light::headlight_left ) ? 1 : 0 ) + + ( ( lights & light::headlight_right ) ? 1 : 0 ) + + ( ( lights & light::headlight_upper ) ? 1 : 0 ); if( light.count > 0 ) { - // TODO: intensity can be affected further by dim switch or other factors light.intensity = std::max( 0.0f, std::log( (float)light.count + 1.0f ) ); light.intensity *= ( light.owner->DimHeadlights ? 0.6f : 1.0f ); + // TBD, TODO: intensity can be affected further by other factors } else { light.intensity = 0.0f; } -/* - // crude catch for unmanned modules which share the light state with the controlled unit. - // why don't they get their own light bits btw ._. - // TODO, TBD: have separate light bits for each vehicle, so this override isn't necessary - // NOTE: should be no longer needed, test and delete if there's no ill effects - if( ( light.owner->Controller == AIdriver ) - && ( light.owner->Mechanik == nullptr ) ) { - - light.intensity = 0.0f; - light.count = 0; - } -*/ } else { // with battery off the lights are off diff --git a/simulation.cpp b/simulation.cpp index 181e22b3..450c35d2 100644 --- a/simulation.cpp +++ b/simulation.cpp @@ -307,11 +307,8 @@ state_manager::deserialize_node( cParser &Input, scene::scratch_data &Scratchpad } if( ( vehicle->MoverParameters->CategoryFlag == 1 ) // trains only - && ( ( vehicle->MoverParameters->SecuritySystem.SystemType != 0 ) - || ( vehicle->MoverParameters->SandCapacity > 0.0 ) ) ) { - // we check for presence of security system or sand load, as a way to determine whether the vehicle is a controllable engine - // NOTE: this isn't 100% precise, e.g. middle EZT module comes with security system, while it has no lights, and some engines - // don't have security systems fitted + && ( ( vehicle->LightList( side::front ) & ( light::headlight_left | light::headlight_right | light::headlight_upper ) != 0 ) + || ( vehicle->LightList( side::rear ) & ( light::headlight_left | light::headlight_right | light::headlight_upper ) != 0 ) ) ) { simulation::Lights.insert( vehicle ); } } @@ -603,7 +600,7 @@ state_manager::deserialize_endtrainset( cParser &Input, scene::scratch_data &Scr } if( Scratchpad.trainset.couplings.back() == coupling::faux ) { // jeśli ostatni pojazd ma sprzęg 0 to założymy mu końcówki blaszane (jak AI się odpali, to sobie poprawi) - Scratchpad.trainset.vehicles.back()->RaLightsSet( -1, TMoverParameters::light::rearendsignals ); + Scratchpad.trainset.vehicles.back()->RaLightsSet( -1, light::rearendsignals ); } // all done Scratchpad.trainset.is_open = false;