16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 20:59:19 +02:00

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`.
This commit is contained in:
jakubg1
2026-04-04 02:05:49 +02:00
parent 4b847e79b9
commit 8c38d2c7e9
3 changed files with 34 additions and 63 deletions

View File

@@ -122,6 +122,17 @@ static int const dtrain_loaddestroyed = 32;/*dla wagonow*/
static int const dtrain_axle = 64; static int const dtrain_axle = 64;
static int const dtrain_out = 128; /*wykolejenie*/ static int const dtrain_out = 128; /*wykolejenie*/
static int const dtrain_pantograph = 256; /*polamanie pantografu*/ static int const dtrain_pantograph = 256; /*polamanie pantografu*/
/*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*/ /*wagi prawdopodobienstwa dla funkcji FuzzyLogic*/
#define p_elengproblem (1e-02) #define p_elengproblem (1e-02)
#define p_elengdamage (1e-01) #define p_elengdamage (1e-01)
@@ -1590,7 +1601,6 @@ class TMoverParameters
int DamageFlag = 0; // kombinacja bitowa stalych dtrain_* } int DamageFlag = 0; // kombinacja bitowa stalych dtrain_* }
int EngDmgFlag = 0; // kombinacja bitowa stalych usterek} 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} // 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} // HeadSignalsFlag: byte; {ABu 060205: zmiany - swiatla: 1/2/4 - przod, 16/32/63 - tyl}
@@ -1832,7 +1842,7 @@ public:
int DettachStatus(int ConnectNo); int DettachStatus(int ConnectNo);
bool Dettach(int ConnectNo); bool Dettach(int ConnectNo);
void damage_coupler( int const End ); void damage_coupler( int const End );
void derail( int const Reason ); void Derail(DerailReason Reason);
bool DirectionForward(); bool DirectionForward();
bool DirectionBackward( void );/*! kierunek ruchu*/ bool DirectionBackward( void );/*! kierunek ruchu*/
bool EIMDirectionChangeAllow( void ) const; bool EIMDirectionChangeAllow( void ) const;

View File

@@ -1252,10 +1252,10 @@ void TMoverParameters::CollisionDetect(int const End, double const dt)
} }
if( velocitydifference > safevelocitylimit * ( TotalMass / othervehicle->TotalMass ) ) { if( velocitydifference > safevelocitylimit * ( TotalMass / othervehicle->TotalMass ) ) {
derail( 5 ); Derail(COLLISION);
} }
if( velocitydifference > safevelocitylimit * ( othervehicle->TotalMass / TotalMass ) ) { 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" ); WriteLog( "Bad driving: " + Name + " broke a coupler" );
} }
void void TMoverParameters::Derail( DerailReason const Reason ) {
TMoverParameters::derail( int const Reason ) {
if( SetFlag( DamageFlag, dtrain_out ) ) { if( SetFlag( DamageFlag, dtrain_out ) ) {
DerailReason = Reason; // TODO: enum derail causes
EventFlag = true; EventFlag = true;
MainSwitch( false, range_t::local ); MainSwitch( false, range_t::local );
AccS *= 0.65; AccS *= 0.65;
V *= 0.65; V *= 0.65;
RunningShape.R = 0;
if( Vel < 5.0 ) { if( Vel < 5.0 ) {
// HACK: prevent permanent axle spin in static vehicle after a collision // HACK: prevent permanent axle spin in static vehicle after a collision
nrot = 0.0; nrot = 0.0;
SlippingWheels = false; 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 // wykolejanie na luku oraz z braku szyn
if (TestFlag(CategoryFlag, 1)) 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)) if (TestFlag(Track.DamageFlag, dtrack_norail))
DerailReason = 1; // Ra: powód wykolejenia: brak szyn Derail(END_OF_TRACK);
else if (FuzzyLogic((AccN / g) * (1.0 + 0.1 * (Track.DamageFlag & dtrack_freerail)), TrackW / Dim.H, 1))
DerailReason = 2; // Ra: powód wykolejenia: przewrócony na łuku Derail(TOO_HIGH_SPEED);
}
// wykolejanie na poszerzeniu toru // wykolejanie na poszerzeniu toru
if (FuzzyLogic(abs(Track.Width - TrackW), TrackW / 10.0, 1)) if (FuzzyLogic(abs(Track.Width - TrackW), TrackW / 10.0, 1))
if (SetFlag(DamageFlag, dtrain_out)) Derail(GAUGE_MISMATCH);
{
EventFlag = true;
MainSwitch( false, range_t::local );
RunningShape.R = 0;
DerailReason = 3; // Ra: powód wykolejenia: za szeroki tor
}
} }
// wykolejanie wkutek niezgodnosci kategorii toru i pojazdu // wykolejanie wkutek niezgodnosci kategorii toru i pojazdu
if (!TestFlag(RunningTrack.CategoryFlag, CategoryFlag)) if (!TestFlag(RunningTrack.CategoryFlag, CategoryFlag))
if (SetFlag(DamageFlag, dtrain_out)) Derail(WRONG_TRACK_TYPE);
{
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;
}
// dL:=(V+AccS*dt/2)*dt; // dL:=(V+AccS*dt/2)*dt;
// przyrost dlugosci czyli przesuniecie // przyrost dlugosci czyli przesuniecie

View File

@@ -4265,27 +4265,6 @@ bool TDynamicObject::Update(double dt, double dt1)
MoverParameters->InactiveCabPantsCheck = false; 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 ) { if( MoverParameters->LoadStatus ) {
LoadUpdate(); // zmiana modelu ładunku LoadUpdate(); // zmiana modelu ładunku
} }