From 0d010e8c6aaba82bc6c4c4897a96f9195b83c994 Mon Sep 17 00:00:00 2001 From: jakubg1 <24206305+jakubg1@users.noreply.github.com> Date: Sat, 4 Apr 2026 02:05:49 +0200 Subject: [PATCH] Simplify derailing logic, derail reason enum - The `TMoverParameters::derail()` function has been renamed to `::Derail()`, with a capital D. - All derail events now use that function. - Simplified and unified the logic behind different derail types. - The `dtrack_freerail` track type is now slightly increasing the chance of derailing on a tight curve, as it was the intention. - A new `DerailReason` enum has been created which holds all derail types. - The `DerailReason` field in the `TMoverParameters` class has been removed. - This was a transient field which is not necessary anymore. - The logging functionality as such has been moved from `DynObj.cpp` to `Mover.cpp`. --- McZapkie/MOVER.h | 16 ++++++++++--- McZapkie/Mover.cpp | 60 ++++++++++++++++------------------------------ vehicle/DynObj.cpp | 21 ---------------- 3 files changed, 34 insertions(+), 63 deletions(-) diff --git a/McZapkie/MOVER.h b/McZapkie/MOVER.h index c9c3bb04..ea0c9d52 100644 --- a/McZapkie/MOVER.h +++ b/McZapkie/MOVER.h @@ -122,7 +122,18 @@ static int const dtrain_loaddestroyed = 32;/*dla wagonow*/ static int const dtrain_axle = 64; static int const dtrain_out = 128; /*wykolejenie*/ static int const dtrain_pantograph = 256; /*polamanie pantografu*/ - /*wagi prawdopodobienstwa dla funkcji FuzzyLogic*/ + +/*przyczyny wykolejenia*/ +enum DerailReason { + NONE = 0, + END_OF_TRACK = 1, // Ra: powód wykolejenia: brak szyn + TOO_HIGH_SPEED = 2, // Ra: powód wykolejenia: przewrócony na łuku + GAUGE_MISMATCH = 3, // Ra: powód wykolejenia: za szeroki tor + WRONG_TRACK_TYPE = 4, // Ra: powód wykolejenia: nieodpowiednia trajektoria + COLLISION = 5, // powód wykolejenia: zderzenie z innym pojazdem +}; + +/*wagi prawdopodobienstwa dla funkcji FuzzyLogic*/ #define p_elengproblem (1e-02) #define p_elengdamage (1e-01) #define p_coupldmg (2e-03) @@ -1590,7 +1601,6 @@ class TMoverParameters int DamageFlag = 0; // kombinacja bitowa stalych dtrain_* } int EngDmgFlag = 0; // kombinacja bitowa stalych usterek} - int DerailReason = 0; // przyczyna wykolejenia // EndSignalsFlag: byte; {ABu 060205: zmiany - koncowki: 1/16 - swiatla prz/tyl, 2/31 - blachy prz/tyl} // HeadSignalsFlag: byte; {ABu 060205: zmiany - swiatla: 1/2/4 - przod, 16/32/63 - tyl} @@ -1832,7 +1842,7 @@ public: int DettachStatus(int ConnectNo); bool Dettach(int ConnectNo); void damage_coupler( int const End ); - void derail( int const Reason ); + void Derail(DerailReason Reason); bool DirectionForward(); bool DirectionBackward( void );/*! kierunek ruchu*/ bool EIMDirectionChangeAllow( void ) const; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index ca62fb72..6b221d75 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -1252,10 +1252,10 @@ void TMoverParameters::CollisionDetect(int const End, double const dt) } if( velocitydifference > safevelocitylimit * ( TotalMass / othervehicle->TotalMass ) ) { - derail( 5 ); + Derail(COLLISION); } if( velocitydifference > safevelocitylimit * ( othervehicle->TotalMass / TotalMass ) ) { - othervehicle->derail( 5 ); + othervehicle->Derail(COLLISION); } } } @@ -1318,24 +1318,31 @@ TMoverParameters::damage_coupler( int const End ) { WriteLog( "Bad driving: " + Name + " broke a coupler" ); } -void -TMoverParameters::derail( int const Reason ) { - +void TMoverParameters::Derail( DerailReason const Reason ) { if( SetFlag( DamageFlag, dtrain_out ) ) { - - DerailReason = Reason; // TODO: enum derail causes EventFlag = true; MainSwitch( false, range_t::local ); AccS *= 0.65; V *= 0.65; + RunningShape.R = 0; 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" ); + // Print a message in the log. + if (Reason == END_OF_TRACK) + ErrorLog("Bad driving: " + Name + " derailed due to end of track"); + else if (Reason == TOO_HIGH_SPEED) + ErrorLog("Bad driving: " + Name + " derailed due to too high speed"); + else if (Reason == GAUGE_MISMATCH) + ErrorLog("Bad dynamic: " + Name + " derailed due to track width"); // błąd w scenerii + else if (Reason == WRONG_TRACK_TYPE) + ErrorLog("Bad dynamic: " + Name + " derailed due to wrong track type"); // błąd w scenerii + else if (Reason == COLLISION) + WriteLog("Bad driving: " + Name + " derailed"); // This reason also generates its own message in `TMoverParameters::CollisionDetect()` } } @@ -1436,42 +1443,17 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap // wykolejanie na luku oraz z braku szyn if (TestFlag(CategoryFlag, 1)) { - if (FuzzyLogic((AccN / g) * (1.0 + 0.1 * (Track.DamageFlag && dtrack_freerail)), - TrackW / Dim.H, 1) || - TestFlag(Track.DamageFlag, dtrack_norail)) - if (SetFlag(DamageFlag, dtrain_out)) - { - EventFlag = true; - MainSwitch( false, range_t::local ); - RunningShape.R = 0; - if (TestFlag(Track.DamageFlag, dtrack_norail)) - DerailReason = 1; // Ra: powód wykolejenia: brak szyn - else - DerailReason = 2; // Ra: powód wykolejenia: przewrócony na łuku - } + if (TestFlag(Track.DamageFlag, dtrack_norail)) + Derail(END_OF_TRACK); + if (FuzzyLogic((AccN / g) * (1.0 + 0.1 * (Track.DamageFlag & dtrack_freerail)), TrackW / Dim.H, 1)) + Derail(TOO_HIGH_SPEED); // wykolejanie na poszerzeniu toru if (FuzzyLogic(abs(Track.Width - TrackW), TrackW / 10.0, 1)) - if (SetFlag(DamageFlag, dtrain_out)) - { - EventFlag = true; - MainSwitch( false, range_t::local ); - RunningShape.R = 0; - DerailReason = 3; // Ra: powód wykolejenia: za szeroki tor - } + Derail(GAUGE_MISMATCH); } // wykolejanie wkutek niezgodnosci kategorii toru i pojazdu if (!TestFlag(RunningTrack.CategoryFlag, CategoryFlag)) - if (SetFlag(DamageFlag, dtrain_out)) - { - EventFlag = true; - MainSwitch( false, range_t::local ); - DerailReason = 4; // Ra: powód wykolejenia: nieodpowiednia trajektoria - } - if( ( true == TestFlag( DamageFlag, dtrain_out ) ) - && ( Vel < 1.0 ) ) { - V = 0.0; - AccS = 0.0; - } + Derail(WRONG_TRACK_TYPE); // dL:=(V+AccS*dt/2)*dt; // przyrost dlugosci czyli przesuniecie diff --git a/vehicle/DynObj.cpp b/vehicle/DynObj.cpp index 0af7d324..8f4a3db5 100644 --- a/vehicle/DynObj.cpp +++ b/vehicle/DynObj.cpp @@ -4265,27 +4265,6 @@ bool TDynamicObject::Update(double dt, double dt1) MoverParameters->InactiveCabPantsCheck = false; } - - if (MoverParameters->DerailReason > 0) - { - switch (MoverParameters->DerailReason) - { - case 1: - ErrorLog("Bad driving: " + asName + " derailed due to end of track"); - break; - case 2: - ErrorLog("Bad driving: " + asName + " derailed due to too high speed"); - break; - case 3: - ErrorLog("Bad dynamic: " + asName + " derailed due to track width"); - break; // błąd w scenerii - case 4: - ErrorLog("Bad dynamic: " + asName + " derailed due to wrong track type"); - break; // błąd w scenerii - } - MoverParameters->DerailReason = 0; //żeby tylko raz - } - if( MoverParameters->LoadStatus ) { LoadUpdate(); // zmiana modelu ładunku }