From 4aeb98ecbebbb5c7da399f1336b25eddc031e4fe Mon Sep 17 00:00:00 2001 From: tmj-fstate Date: Fri, 17 Aug 2018 01:17:22 +0200 Subject: [PATCH] interior lighting power source lookup enhancement, track event activation filtering, switch geometry normal fix, material parsing enhancements, AI acceleration and braking logic tweaks, AI car route scanning accuracy fix, AI braking delay fix --- Driver.cpp | 245 +++++++++++++++++++++++++-------------------- Driver.h | 18 +++- DynObj.cpp | 60 ----------- McZapkie/Mover.cpp | 183 ++++++++++----------------------- Track.cpp | 19 ++-- Train.cpp | 36 ++++--- TrkFoll.cpp | 12 ++- material.cpp | 6 +- 8 files changed, 247 insertions(+), 332 deletions(-) diff --git a/Driver.cpp b/Driver.cpp index 6a80d78c..d99c45ba 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -479,9 +479,17 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) // jeśli w kierunku Point2 toru fTrackLength = pTrack->Length() - fTrackLength; // przeskanowana zostanie odległość do Point2 } - fTrackLength -= pVehicle->tracing_offset(); - fCurrentDistance = -fLength - fTrackLength; // aktualna odległość ma być ujemna gdyż jesteśmy na końcu składu - fLastVel = -1.0; // pTrack->VelocityGet(); // aktualna prędkość // changed to -1 to recognize speed limit, if any + // account for the fact tracing begins from active axle, not the actual front of the vehicle + // NOTE: position of the couplers is modified by track offset, but the axles ain't, so we need to account for this as well + fTrackLength -= ( + pVehicle->AxlePositionGet() + - pVehicle->RearPosition() + + pVehicle->VectorLeft() * pVehicle->MoverParameters->OffsetTrackH ) + .Length(); + // aktualna odległość ma być ujemna gdyż jesteśmy na końcu składu + fCurrentDistance = -fLength - fTrackLength; + // aktualna prędkość // changed to -1 to recognize speed limit, if any + fLastVel = -1.0; sSpeedTable.clear(); iLast = -1; tLast = nullptr; //żaden nie sprawdzony @@ -1429,13 +1437,13 @@ TController::braking_distance_multiplier( float const Targetvelocity ) const { return interpolate( 2.f, 1.f, static_cast( mvOccupied->Vel / 40.0 ) ); } // HACK: cargo trains or trains going downhill with high braking threshold need more distance to come to a full stop - if( ( fBrake_a0[ 0 ] > 0.2 ) - && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ) - || ( fAccGravity > 0.025 ) ) { + if( ( fBrake_a0[ 1 ] > 0.2 ) + && ( ( true == IsCargoTrain ) + || ( fAccGravity > 0.025 ) ) ) { return interpolate( 1.f, 2.f, clamp( - ( fBrake_a0[ 0 ] - 0.2 ) / 0.2, + ( fBrake_a0[ 1 ] - 0.2 ) / 0.2, 0.0, 1.0 ) ); } @@ -1868,59 +1876,71 @@ void TController::AutoRewident() } d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) } - //teraz zerujemy tabelkę opóźnienia hamowania - double velstep = (mvOccupied->Vmax*0.5) / BrakeAccTableSize; - for (int i = 0; i < BrakeAccTableSize; i++) + //ustawianie trybu pracy zadajnika hamulca, wystarczy raz po inicjalizacji AI + for( int i = 1; i <= 8; i *= 2 ) { + if( ( mvOccupied->BrakeOpModes & i ) > 0 ) { + mvOccupied->BrakeOpModeFlag = i; + } + } + // teraz zerujemy tabelkę opóźnienia hamowania + for (int i = 0; i < BrakeAccTableSize; ++i) { fBrake_a0[i+1] = 0; fBrake_a1[i+1] = 0; } // 4. Przeliczanie siły hamowania + double const velstep = ( mvOccupied->Vmax*0.5 ) / BrakeAccTableSize; d = pVehicles[0]; // pojazd na czele składu - // HACK: calculated brake thresholds for cars are so high they prevent the AI from effectively braking - // thus we artificially reduce them until a better solution for the problem is found - auto const braketablescale { ( - d->MoverParameters->CategoryFlag == 2 ? - 0.6 : - 1.0 ) }; while (d) { for( int i = 0; i < BrakeAccTableSize; ++i ) { - fBrake_a0[ i + 1 ] += braketablescale * d->MoverParameters->BrakeForceR( 0.25, velstep*( 1 + 2 * i ) ); - fBrake_a1[ i + 1 ] += braketablescale * d->MoverParameters->BrakeForceR( 1.00, velstep*( 1 + 2 * i ) ); + fBrake_a0[ i + 1 ] += d->MoverParameters->BrakeForceR( 0.25, velstep*( 1 + 2 * i ) ); + fBrake_a1[ i + 1 ] += d->MoverParameters->BrakeForceR( 1.00, velstep*( 1 + 2 * i ) ); } d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) } - for (int i = 0; i < BrakeAccTableSize; i++) + for (int i = 0; i < BrakeAccTableSize; ++i) { fBrake_a1[i+1] -= fBrake_a0[i+1]; fBrake_a0[i+1] /= fMass; fBrake_a0[i + 1] += 0.001*velstep*(1 + 2 * i); fBrake_a1[i+1] /= (12*fMass); } + + IsCargoTrain = ( mvOccupied->CategoryFlag == 1 ) && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ); + IsHeavyCargoTrain = ( true == IsCargoTrain ) && ( fBrake_a0[ 1 ] > 0.4 ); + + BrakingInitialLevel = ( + IsHeavyCargoTrain ? 1.25 : + IsCargoTrain ? 1.25 : + 1.00 ); + + BrakingLevelIncrease = ( + IsHeavyCargoTrain ? 0.25 : + IsCargoTrain ? 0.25 : + 0.25 ); + if( mvOccupied->TrainType == dt_EZT ) { - fAccThreshold = std::max(-fBrake_a0[BrakeAccTableSize] - 8 * fBrake_a1[BrakeAccTableSize], -0.55); + fAccThreshold = std::max( -0.55, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] ); fBrakeReaction = 0.25; } else if( mvOccupied->TrainType == dt_DMU ) { - fAccThreshold = std::max( -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ], -0.45 ); + fAccThreshold = std::max( -0.45, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] ); fBrakeReaction = 0.25; } - else if (ustaw > 16) - { - fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 4 * fBrake_a1[BrakeAccTableSize]; + else if (ustaw > 16) { + fAccThreshold = -fBrake_a0[ BrakeAccTableSize ] - 4 * fBrake_a1[ BrakeAccTableSize ]; fBrakeReaction = 1.00 + fLength*0.004; } - else - { - fAccThreshold = -fBrake_a0[BrakeAccTableSize] - 1 * fBrake_a1[BrakeAccTableSize]; + else { + fAccThreshold = -fBrake_a0[ BrakeAccTableSize ] - 1 * fBrake_a1[ BrakeAccTableSize ]; fBrakeReaction = 1.00 + fLength*0.005; } - for (int i = 1; i <= 8; i *= 2) //ustawianie trybu pracy zadajnika hamulca, wystarczy raz po inicjalizacji AI - { - if ((mvOccupied->BrakeOpModes & i) > 0) { - mvOccupied->BrakeOpModeFlag = i; - } - } +/* + if( IsHeavyCargoTrain ) { + // HACK: heavy cargo trains don't activate brakes early enough + fAccThreshold = std::max( -0.2, fAccThreshold ); + } +*/ } double TController::ESMVelocity(bool Main) @@ -2418,7 +2438,10 @@ bool TController::PrepareEngine() mvControlling->IncMainCtrl( 1 ); } } - mvControlling->MainSwitch(true); + if( ( mvControlling->EnginePowerSource.SourceType != TPowerSource::CurrentCollector ) + || ( std::max( mvControlling->GetTrainsetVoltage(), std::abs( mvControlling->RunningTraction.TractionVoltage ) ) > mvControlling->EnginePowerSource.CollectorParameters.MinV ) ) { + mvControlling->MainSwitch( true ); + } /* if (mvControlling->EngineType == DieselEngine) { // Ra 2014-06: dla SN61 trzeba wrzucić pierwszą pozycję - nie wiem, czy tutaj... @@ -2621,7 +2644,9 @@ bool TController::IncBrake() d = pVehicles[0]; // pojazd na czele składu while (d) { // przeliczanie dodatkowego potrzebnego spadku ciśnienia - pos_corr+=(d->MoverParameters->Hamulec->GetCRP() - 5.0)*d->MoverParameters->TotalMass; + if( ( d->MoverParameters->Hamulec->GetBrakeStatus() & b_dmg ) == 0 ) { + pos_corr += ( d->MoverParameters->Hamulec->GetCRP() - 5.0 ) * d->MoverParameters->TotalMass; + } d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła) } pos_corr = pos_corr / fMass * 2.5; @@ -2636,10 +2661,7 @@ bool TController::IncBrake() if( deltaAcc > fBrake_a1[0]) { if( mvOccupied->BrakeCtrlPosR < 0.1 ) { - OK = mvOccupied->BrakeLevelAdd( ( - mvOccupied->BrakeDelayFlag > bdelay_G ? - 1.0 : - 1.25 ) ); + OK = mvOccupied->BrakeLevelAdd( BrakingInitialLevel ); /* // HACK: stronger braking to overcome SA134 engine behaviour if( ( mvOccupied->TrainType == dt_DMU ) @@ -2654,10 +2676,11 @@ bool TController::IncBrake() } else { - OK = mvOccupied->BrakeLevelAdd( 0.25 ); - if( ( deltaAcc > 5 * fBrake_a1[ 0 ] ) - && ( mvOccupied->BrakeCtrlPosR <= 3.0 ) ) { - mvOccupied->BrakeLevelAdd( 0.75 ); + OK = mvOccupied->BrakeLevelAdd( BrakingLevelIncrease ); + // brake harder if the acceleration is much higher than desired + if( ( deltaAcc > 2 * fBrake_a1[ 0 ] ) + && ( mvOccupied->BrakeCtrlPosR + BrakingLevelIncrease <= 5.0 ) ) { + mvOccupied->BrakeLevelAdd( BrakingLevelIncrease ); } } } @@ -2793,36 +2816,42 @@ bool TController::IncSpeed() // na pozycji 0 przejdzie, a na pozostałych będzie czekać, aż się załączą liniowe (zgaśnie DelayCtrlFlag) if (Ready || (iDrivigFlags & movePress)) { // use series mode: - // to build up speed to 30/40 km/h for passenger/cargo train (10 km/h less if going uphill) // if high threshold is set for motor overload relay, - // if the power station is heavily burdened + // if the power station is heavily burdened, + // if it generates enough traction force + // to build up speed to 30/40 km/h for passenger/cargo train (10 km/h less if going uphill) + auto const sufficienttractionforce { std::abs( mvControlling->Ft ) > ( IsHeavyCargoTrain ? 125 : 100 ) * 1000.0 }; auto const useseriesmodevoltage { 0.80 * mvControlling->EnginePowerSource.CollectorParameters.MaxV }; + 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 useseriesmode = ( - ( mvOccupied->Vel <= ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ? 35 : 25 ) + ( mvControlling->ScndCtrlPos == 0 ? 0 : 5 ) - ( ( fAccGravity < -0.025 ) ? 10 : 0 ) ) - || ( mvControlling->Imax > mvControlling->ImaxLo ) - || ( fVoltage < useseriesmodevoltage ) ); + ( mvControlling->Imax > mvControlling->ImaxLo ) + || ( fVoltage < useseriesmodevoltage ) + || ( ( true == sufficienttractionforce ) + && ( mvOccupied->Vel <= ( IsCargoTrain ? 35 : 25 ) + ( seriesmodefieldshunting ? 5 : 0 ) - ( ( fAccGravity < -0.025 ) ? 10 : 0 ) ) ) ); // when not in series mode use the first available parallel mode configuration until 50/60 km/h for passenger/cargo train // (if there's only one parallel mode configuration it'll be used regardless of current speed) - auto const scndctrl = ( + auto const usefieldshunting = ( ( mvControlling->StLinFlag ) && ( mvControlling->RList[ mvControlling->MainCtrlPos ].R < 0.01 ) && ( useseriesmode ? mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 : - ( ( mvOccupied->Vel <= ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ? 55 : 45 ) + ( mvControlling->ScndCtrlPos == 0 ? 0 : 5 ) ) ? + ( ( true == sufficienttractionforce ) + && ( mvOccupied->Vel <= ( IsCargoTrain ? 55 : 45 ) + ( parallelmodefieldshunting ? 5 : 0 ) ) ? mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 : mvControlling->MainCtrlPos == mvControlling->MainCtrlPosNo ) ) ); double Vs = 99999; - if( scndctrl ? + if( usefieldshunting ? ( mvControlling->ScndCtrlPos < mvControlling->ScndCtrlPosNo ) : ( mvControlling->MainCtrlPos < mvControlling->MainCtrlPosNo ) ) { - Vs = ESMVelocity( !scndctrl ); + Vs = ESMVelocity( !usefieldshunting ); } if( ( std::abs( mvControlling->Im ) < ( fReady < 0.4 ? mvControlling->Imin : mvControlling->IminLo ) ) || ( mvControlling->Vel > Vs ) ) { // Ra: wywalał nadmiarowy, bo Im może być ujemne; jak nie odhamowany, to nie przesadzać z prądem - if( scndctrl ) { + if( usefieldshunting ) { // to dać bocznik // engage the shuntfield only if there's sufficient power margin to draw from OK = ( @@ -3787,12 +3816,13 @@ TController::UpdateSituation(double dt) { // Ra: odluźnianie przeładowanych lokomotyw, ciągniętych na zimno - prowizorka... if (AIControllFlag) // skład jak dotąd był wyluzowany { - if (mvOccupied->BrakeCtrlPos == 0) // jest pozycja jazdy - if ((p->MoverParameters->PipePress - 5.0) > - -0.1) // jeśli ciśnienie jak dla jazdy - if (p->MoverParameters->Hamulec->GetCRP() > - p->MoverParameters->PipePress + 0.12) // za dużo w zbiorniku - p->MoverParameters->BrakeReleaser(1); // indywidualne luzowanko + if( ( mvOccupied->BrakeCtrlPos == 0 ) // jest pozycja jazdy + && ( ( p->MoverParameters->Hamulec->GetBrakeStatus() & b_dmg ) == 0 ) // brake isn't broken + && ( p->MoverParameters->PipePress - 5.0 > -0.1 ) // jeśli ciśnienie jak dla jazdy + && ( p->MoverParameters->Hamulec->GetCRP() > p->MoverParameters->PipePress + 0.12 ) ) { // za dużo w zbiorniku + // indywidualne luzowanko + p->MoverParameters->BrakeReleaser( 1 ); + } if (p->MoverParameters->Power > 0.01) // jeśli ma silnik if (p->MoverParameters->FuseFlag) // wywalony nadmiarowy Need_TryAgain = true; // reset jak przy wywaleniu nadmiarowego @@ -4355,34 +4385,14 @@ TController::UpdateSituation(double dt) { } case Shunt: { // na jaką odleglość i z jaką predkością ma podjechać -/* - fMinProximityDist = 5.0; - fMaxProximityDist = 10.0; //[m] - - if( pVehicles[ 0 ] != pVehicles[ 1 ] ) { - // for larger consists increase margins to account for slower braking etc - // NOTE: this will affect also multi-unit vehicles TBD: is this what we want? - fMinProximityDist *= 2.0; - fMaxProximityDist *= 2.0; - if( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ) { - // additional safety margin for cargo consists - fMinProximityDist *= 2.0; - fMaxProximityDist *= 2.0; - if( fBrake_a0[ 0 ] >= 0.35 ) { - // cargo trains with high braking threshold may require even larger safety margin - fMaxProximityDist += 20.0; - } - } - } -*/ + // TODO: test if we can use the distances calculation from obey_train fMinProximityDist = std::min( 5 + iVehicles, 25 ); fMaxProximityDist = std::min( 10 + iVehicles, 50 ); - if( ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ) - && ( fBrake_a0[ 0 ] >= 0.35 ) ) { - // cargo trains with high braking threshold may require even larger safety margin +/* + if( IsHeavyCargoTrain ) { fMaxProximityDist *= 1.5; } - +*/ fVelPlus = 2.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania // margines prędkości powodujący załączenie napędu // były problemy z jazdą np. 3km/h podczas ładowania wagonów @@ -4393,11 +4403,25 @@ TController::UpdateSituation(double dt) { // na jaka odleglosc i z jaka predkoscia ma podjechac do przeszkody if( mvOccupied->CategoryFlag & 1 ) { // jeśli pociąg - fMinProximityDist = 15.0; - fMaxProximityDist = - ( mvOccupied->Vel > 0.0 ) ? - 25.0 : - 50.0; //[m] jak stanie za daleko, to niech nie dociąga paru metrów + fMinProximityDist = clamp( 5 + iVehicles, 10, 15 ); + fMaxProximityDist = clamp( 10 + iVehicles, 15, 40 ); + + if( IsCargoTrain ) { + // increase distances for cargo trains to take into account slower reaction to brakes + fMinProximityDist += 10.0; + fMaxProximityDist += 10.0; +/* + if( IsHeavyCargoTrain ) { + // cargo trains with high braking threshold may require even larger safety margin + fMaxProximityDist += 20.0; + } +*/ + } + if( mvOccupied->Vel < 0.1 ) { + // jak stanie za daleko, to niech nie dociąga paru metrów + fMaxProximityDist = 50.0; + } + if( iDrivigFlags & moveLate ) { // jeśli spóźniony, to gna fVelMinus = 1.0; @@ -4412,20 +4436,11 @@ TController::UpdateSituation(double dt) { // bottom margin raised to 2 km/h to give the AI more leeway at low speed limits fVelPlus = clamp( std::ceil( 0.05 * VelDesired ), 2.0, 5.0 ); } - if( mvOccupied->BrakeDelayFlag == bdelay_G ) { - // increase distances for cargo trains to take into account slower reaction to brakes - fMinProximityDist += 10.0; - fMaxProximityDist += 15.0; - if( fBrake_a0[ 0 ] >= 0.35 ) { - // cargo trains with high braking threshold may require even larger safety margin - fMaxProximityDist += 20.0; - } - } } else { // samochod (sokista też) - fMinProximityDist = std::max( 3.0, mvOccupied->Vel * 0.2 ); - fMaxProximityDist = std::max( 9.0, mvOccupied->Vel * 0.375 ); //[m] + fMinProximityDist = std::max( 3.5, mvOccupied->Vel * 0.2 ); + fMaxProximityDist = std::max( 9.5, mvOccupied->Vel * 0.375 ); //[m] // margines prędkości powodujący załączenie napędu fVelMinus = 2.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania @@ -4701,14 +4716,15 @@ TController::UpdateSituation(double dt) { fMinProximityDist : // cars can bunch up tighter fMaxProximityDist ) ); // other vehicle types less so */ - ActualProximityDist = std::min( - ActualProximityDist, - vehicle->fTrackBlock ); double k = coupler->Connected->Vel; // prędkość pojazdu z przodu (zakładając, // że jedzie w tę samą stronę!!!) - if( k - vel < 10 ) { + if( k - vel < 5 ) { // porównanie modułów prędkości [km/h] // zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej + ActualProximityDist = std::min( + ActualProximityDist, + vehicle->fTrackBlock ); + 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 @@ -4939,13 +4955,17 @@ TController::UpdateSituation(double dt) { } else { // outside of max safe range + AccDesired = AccPreferred; if( vel > min_speed( 10.0, VelDesired ) ) { // allow to coast at reasonably low speed + auto const brakingdistance { fBrakeDist * braking_distance_multiplier( VelNext ) }; auto const slowdowndistance { ( - ( OrderCurrentGet() & Connect ) == 0 ? - 100.0 : - 25.0 ) }; - if( ( std::max( slowdowndistance, fMaxProximityDist ) + fBrakeDist * braking_distance_multiplier( VelNext ) ) >= ( ActualProximityDist - fMaxProximityDist ) ) { + mvOccupied->CategoryFlag == 2 ? // cars can stop on a dime, for bigger vehicles we enforce some minimal braking distance + brakingdistance : + std::max( + ( ( OrderCurrentGet() & Connect ) == 0 ? 100.0 : 25.0 ), + brakingdistance ) ) }; + if( ( brakingdistance + std::max( slowdowndistance, fMaxProximityDist ) ) >= ( ActualProximityDist - fMaxProximityDist ) ) { // don't slow down prematurely; as long as we have room to come to a full stop at a safe distance, we're good // ensure some minimal coasting speed, otherwise a vehicle entering this zone at very low speed will be crawling forever auto const brakingpointoffset = VelNext * braking_distance_multiplier( VelNext ); @@ -5060,8 +5080,8 @@ TController::UpdateSituation(double dt) { // if it looks like we'll exceed maximum speed start thinking about slight slowing down AccDesired = std::min( AccDesired, -0.25 ); // HACK: for cargo trains with high braking threshold ensure we cross that threshold - if( ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ) - && ( fBrake_a0[ 0 ] > 0.2 ) ) { + if( ( true == IsCargoTrain ) + && ( fBrake_a0[ 0 ] > 0.2 ) ) { AccDesired -= clamp( fBrake_a0[ 0 ] - 0.2, 0.0, 0.15 ); } } @@ -5119,7 +5139,10 @@ TController::UpdateSituation(double dt) { // last step sanity check, until the whole calculation is straightened out AccDesired = std::min( AccDesired, AccPreferred ); - AccDesired = clamp( AccDesired, -0.9, 0.9 ); + AccDesired = clamp( + AccDesired, + ( mvControlling->CategoryFlag == 2 ? -2.0 : -0.9 ), + ( mvControlling->CategoryFlag == 2 ? 2.0 : 0.9 ) ); if (AIControllFlag) { // część wykonawcza tylko dla AI, dla człowieka jedynie napisy @@ -5211,7 +5234,7 @@ TController::UpdateSituation(double dt) { && ( BrakeChargingCooldown >= 0.0 ) ) { if( ( iDrivigFlags & moveOerlikons ) - || ( mvOccupied->BrakeDelayFlag & bdelay_G ) ) { + || ( true == IsCargoTrain ) ) { // napełnianie w Oerlikonie mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) ); // don't charge the brakes too often, or we risk overcharging diff --git a/Driver.h b/Driver.h index 581ba9b4..e7a05617 100644 --- a/Driver.h +++ b/Driver.h @@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/. #include "Classes.h" #include "mczapkie/mover.h" #include "sound.h" +#include "dynobj.h" enum TOrders { // rozkazy dla AI @@ -208,8 +209,15 @@ public: double fBrakeReaction = 1.0; //opóźnienie zadziałania hamulca - czas w s / (km/h) double fAccThreshold = 0.0; // próg opóźnienia dla zadziałania hamulca double AbsAccS_pub = 0.0; // próg opóźnienia dla zadziałania hamulca - double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca - double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // próg opóźnienia dla zadziałania hamulca + // dla fBrake_aX: + // indeks [0] - wartości odpowiednie dla aktualnej prędkości + // a potem jest 20 wartości dla różnych prędkości zmieniających się co 5 % Vmax pojazdu obsadzonego + double fBrake_a0[BrakeAccTableSize+1] = { 0.0 }; // opóźnienia hamowania przy ustawieniu zaworu maszynisty w pozycji 1.0 + double fBrake_a1[BrakeAccTableSize+1] = { 0.0 }; // przyrost opóźnienia hamowania po przestawieniu zaworu maszynisty o 0,25 pozycji + double BrakingInitialLevel{ 1.0 }; + double BrakingLevelIncrease{ 0.25 }; + bool IsCargoTrain{ false }; + bool IsHeavyCargoTrain{ false }; double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca @@ -354,7 +362,7 @@ private: std::vector CheckTrackEvent(TTrack *Track, double const fDirection ) const; bool TableAddNew(); bool TableNotFound(TEvent const *Event) const; - void TableTraceRoute(double fDistance, TDynamicObject *pVehicle = nullptr); + void TableTraceRoute(double fDistance, TDynamicObject *pVehicle); void TableCheck(double fDistance); TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc); // modifies brake distance for low target speeds, to ease braking rate in such situations @@ -412,4 +420,8 @@ private: std::string OwnerName() const; TMoverParameters const *Controlling() const { return mvControlling; } + int Direction() const { + return iDirection; } + TDynamicObject const *Vehicle() const { + return pVehicle; } }; diff --git a/DynObj.cpp b/DynObj.cpp index c019cd46..2cd111c3 100644 --- a/DynObj.cpp +++ b/DynObj.cpp @@ -2772,66 +2772,6 @@ bool TDynamicObject::Update(double dt, double dt1) if (!bEnabled) return false; // a normalnie powinny mieć bEnabled==false - // McZapkie-260202 - if ((MoverParameters->EnginePowerSource.SourceType == TPowerSource::CurrentCollector) && - (MoverParameters->Power > 1.0)) // aby rozrządczy nie opuszczał silnikowemu -/* - if ((MechInside) || (MoverParameters->TrainType == dt_EZT)) - { -*/ - // if - // ((!MoverParameters->PantCompFlag)&&(MoverParameters->CompressedVolume>=2.8)) - // MoverParameters->PantVolume=MoverParameters->CompressedVolume; - - if( MoverParameters->PantPress < MoverParameters->EnginePowerSource.CollectorParameters.MinPress ) { - // 3.5 wg http://www.transportszynowy.pl/eu06-07pneumat.php - if( true == MoverParameters->PantPressSwitchActive ) { - // opuszczenie pantografów przy niskim ciśnieniu -/* - // NOTE: disabled, the pantographs drop by themseleves when the pantograph tank pressure gets low enough - MoverParameters->PantFront( false, ( MoverParameters->TrainType == dt_EZT ? range::unit : range::local ) ); - MoverParameters->PantRear( false, ( MoverParameters->TrainType == dt_EZT ? range::unit : range::local ) ); -*/ - if( MoverParameters->TrainType != dt_EZT ) { - // pressure switch safety measure -- open the line breaker, unless there's alternate source of traction voltage - if( MoverParameters->GetTrainsetVoltage() < 0.5 * MoverParameters->EnginePowerSource.MaxVoltage ) { - // TODO: check whether line breaker should be open EMU-wide - MoverParameters->MainSwitch( false, ( MoverParameters->TrainType == dt_EZT ? range_t::unit : range_t::local ) ); - } - } - else { - // specialized variant for EMU -- pwr system disables converter and heating, - // and prevents their activation until pressure switch is set again - MoverParameters->PantPressLockActive = true; - // TODO: separate 'heating allowed' from actual heating flag, so we can disable it here without messing up heating toggle - MoverParameters->ConverterSwitch( false, range_t::unit ); - } - // mark the pressure switch as spent - MoverParameters->PantPressSwitchActive = false; - } - } - else { - if( MoverParameters->PantPress >= 4.6 ) { - // NOTE: we require active low power source to prime the pressure switch - // this is a work-around for potential isssues caused by the switch activating on otherwise idle vehicles, but should check whether it's accurate - if( ( true == MoverParameters->Battery ) - || ( true == MoverParameters->ConverterFlag ) ) { - // prime the pressure switch - MoverParameters->PantPressSwitchActive = true; - // turn off the subsystems lock - MoverParameters->PantPressLockActive = false; - } - - if( MoverParameters->PantPress >= 4.8 ) { - // Winger - automatyczne wylaczanie malej sprezarki - // TODO: governor lock, disables usage until pressure drop below 3.8 (should really make compressor object we could reuse) - MoverParameters->PantCompFlag = false; - } - } - } -/* - } // Ra: do Mover to trzeba przenieść, żeby AI też mogło sobie podpompować -*/ double dDOMoveLen; TLocation l; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 25133abb..1fb943dd 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -733,8 +733,9 @@ void TMoverParameters::UpdatePantVolume(double dt) // Ra 2014-07: kurek trójdrogowy łączy spr.pom. z pantografami i wyłącznikiem ciśnieniowym WS // Ra 2014-07: zbiornika rozrządu nie pompuje się tu, tylko pantografy; potem można zamknąć // WS i odpalić resztę - if ((TrainType == dt_EZT) ? (PantPress < ScndPipePress) : - bPantKurek3) // kurek zamyka połączenie z ZG + if ((TrainType == dt_EZT) ? + (PantPress < ScndPipePress) : + bPantKurek3) // kurek zamyka połączenie z ZG { // zbiornik pantografu połączony ze zbiornikiem głównym - małą sprężarką się tego nie napompuje // Ra 2013-12: Niebugocław mówi, że w EZT nie ma potrzeby odcinać kurkiem PantPress = ScndPipePress; @@ -758,33 +759,48 @@ void TMoverParameters::UpdatePantVolume(double dt) } if( !PantCompFlag && ( PantVolume > 0.1 ) ) PantVolume -= dt * 0.0003 * std::max( 1.0, PantPress * 0.5 ); // nieszczelności: 0.0003=0.3l/s -/* - // NOTE: disabled as this is redundant with check done in dynobj.update() - // TODO: determine if this isn't a mistake -- - // though unlikely it's possible this is emulation of a different circuit than the pantograph pressure switch, with similar function? - // TBD, TODO: alternatively, move the dynobj.update() subroutine here, as it doesn't touch elements outside of the mover object - if( Mains ) { - // nie wchodzić w funkcję bez potrzeby - if( EngineType == ElectricSeriesMotor ) { - // nie dotyczy... czego właściwie? - if( ( true == PantPressSwitchActive ) - && ( PantPress < EnginePowerSource.CollectorParameters.MinPress ) ) { - // wywalenie szybkiego z powodu niskiego ciśnienia - if( GetTrainsetVoltage() < 0.5 * EnginePowerSource.MaxVoltage ) { - // to jest trochę proteza; zasilanie członu może być przez sprzęg WN - if( MainSwitch( false, ( TrainType == dt_EZT ? range::unit : range::local ) ) ) { - EventFlag = true; - } + + if( PantPress < EnginePowerSource.CollectorParameters.MinPress ) { + // 3.5 wg http://www.transportszynowy.pl/eu06-07pneumat.php + if( true == PantPressSwitchActive ) { + // opuszczenie pantografów przy niskim ciśnieniu + if( TrainType != dt_EZT ) { + // pressure switch safety measure -- open the line breaker, unless there's alternate source of traction voltage + if( GetTrainsetVoltage() < EnginePowerSource.CollectorParameters.MinV ) { + // TODO: check whether line breaker should be open EMU-wide + MainSwitch( false, ( TrainType == dt_EZT ? range_t::unit : range_t::local ) ); } + } + else { + // specialized variant for EMU -- pwr system disables converter and heating, + // and prevents their activation until pressure switch is set again + PantPressLockActive = true; + // TODO: separate 'heating allowed' from actual heating flag, so we can disable it here without messing up heating toggle + ConverterSwitch( false, range_t::unit ); + } + // mark the pressure switch as spent + PantPressSwitchActive = false; + } + } + else { + if( PantPress >= 4.6 ) { + // NOTE: we require active low power source to prime the pressure switch + // this is a work-around for potential isssues caused by the switch activating on otherwise idle vehicles, but should check whether it's accurate + if( ( true == Battery ) + || ( true == ConverterFlag ) ) { + // prime the pressure switch + PantPressSwitchActive = true; + // turn off the subsystems lock + PantPressLockActive = false; + } - // NOTE: disabled, the flag gets set in dynobj.update() when the pantograph actually drops - // mark the pressure switch as spent, regardless whether line breaker actually opened - PantPressSwitchActive = false; - + if( PantPress >= 4.8 ) { + // Winger - automatyczne wylaczanie malej sprezarki + // TODO: governor lock, disables usage until pressure drop below 3.8 (should really make compressor object we could reuse) + PantCompFlag = false; } } } -*/ /* // NOTE: pantograph tank pressure sharing experimentally disabled for more accurate simulation if (TrainType != dt_EZT) // w EN57 pompuje się tylko w silnikowym @@ -1351,9 +1367,6 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap } // liczone dL, predkosc i przyspieszenie - if (Power > 1.0) // w rozrządczym nie (jest błąd w FIZ!) - Ra 2014-07: teraz we wszystkich - UpdatePantVolume(dt); // Ra 2014-07: obsługa zbiornika rozrządu oraz pantografów - auto const d { ( EngineType == TEngineType::WheelsDriven ? dL * CabNo : // na chwile dla testu @@ -1364,6 +1377,7 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap // koniec procedury, tu nastepuja dodatkowe procedury pomocnicze compute_movement_( dt ); + // security system if (!DebugModeFlag) SecuritySystemCheck(dt1); @@ -1430,9 +1444,6 @@ double TMoverParameters::FastComputeMovement(double dt, const TTrackShape &Shape if (Couplers[b].CheckCollision) CollisionDetect(b, dt); // zmienia niejawnie AccS, V !!! } // liczone dL, predkosc i przyspieszenie - // QQQ - if (Power > 1.0) // w rozrządczym nie (jest błąd w FIZ!) - UpdatePantVolume(dt); // Ra 2014-07: obsługa zbiornika rozrządu oraz pantografów auto const d { ( EngineType == TEngineType::WheelsDriven ? @@ -1482,6 +1493,11 @@ void TMoverParameters::compute_movement_( double const Deltatime ) { // sprężarka musi mieć jakąś niezerową wydajność żeby rozważać jej załączenie i pracę CompressorCheck( Deltatime ); } + if( Power > 1.0 ) { + // w rozrządczym nie (jest błąd w FIZ!) - Ra 2014-07: teraz we wszystkich + UpdatePantVolume( Deltatime ); // Ra 2014-07: obsługa zbiornika rozrządu oraz pantografów + } + UpdateBrakePressure(Deltatime); UpdatePipePressure(Deltatime); UpdateBatteryVoltage(Deltatime); @@ -2695,61 +2711,21 @@ bool TMoverParameters::IncBrakeLevelOld(void) { bool IBLO = false; - if ((BrakeCtrlPosNo > 0) /*and (LocalBrakePos=0)*/) + if (BrakeCtrlPosNo > 0) { if (BrakeCtrlPos < BrakeCtrlPosNo) { - BrakeCtrlPos++; - // BrakeCtrlPosR = BrakeCtrlPos; - - // youBy: wywalilem to, jak jest EP, to sa przenoszone sygnaly nt. co ma robic, a nie - // poszczegolne pozycje; - // wystarczy spojrzec na Knorra i Oerlikona EP w EN57; mogly ze soba - // wspolapracowac - //{ - // if (BrakeSystem==ElectroPneumatic) - // if (BrakePressureActual.BrakeType==ElectroPneumatic) - // { - // BrakeStatus = ord(BrakeCtrlPos > 0); - // SendCtrlToNext("BrakeCtrl", BrakeCtrlPos, CabNo); - // } - // else SendCtrlToNext("BrakeCtrl", -2, CabNo); - // else - // if (!TestFlag(BrakeStatus,b_dmg)) - // BrakeStatus = b_on;} - + ++BrakeCtrlPos; // youBy: EP po nowemu - IBLO = true; if ((BrakePressureActual.PipePressureVal < 0) && (BrakePressureTable[BrakeCtrlPos - 1].PipePressureVal > 0)) LimPipePress = PipePress; - - //ten kawałek jest bez sensu gdyż nic nie robił. Zakomntowałem. GF 20161124 - //if (BrakeSystem == ElectroPneumatic) - // if (BrakeSubsystem != ss_K) - // { - // if ((BrakeCtrlPos * BrakeCtrlPos) == 1) - // { - // // SendCtrlToNext('Brake',BrakeCtrlPos,CabNo); - // // SetFlag(BrakeStatus,b_epused); - // } - // else - // { - // // SendCtrlToNext('Brake',0,CabNo); - // // SetFlag(BrakeStatus,-b_epused); - // } - // } } - else - { + else { IBLO = false; - // if (BrakeSystem == Pneumatic) - // EmergencyBrakeSwitch(true); } } - else - IBLO = false; return IBLO; } @@ -2762,69 +2738,20 @@ bool TMoverParameters::DecBrakeLevelOld(void) { bool DBLO = false; - if ((BrakeCtrlPosNo > 0) /*&& (LocalBrakePos == 0)*/) + if (BrakeCtrlPosNo > 0) { - if (BrakeCtrlPos > -1 - int(BrakeHandle == TBrakeHandle::FV4a)) + if (BrakeCtrlPos > ( ( BrakeHandle == TBrakeHandle::FV4a ) ? -2 : -1 ) ) { - BrakeCtrlPos--; - // BrakeCtrlPosR:=BrakeCtrlPos; - //if (EmergencyBrakeFlag) - //{ - // EmergencyBrakeFlag = false; //!!! - // SendCtrlToNext("Emergency_brake", 0, CabNo); - //} - - // youBy: wywalilem to, jak jest EP, to sa przenoszone sygnaly nt. co ma robic, a nie - // poszczegolne pozycje; - // wystarczy spojrzec na Knorra i Oerlikona EP w EN57; mogly ze soba - // wspolapracowac - /* - if (BrakeSystem == ElectroPneumatic) - if (BrakePressureActual.BrakeType == ElectroPneumatic) - { - // BrakeStatus =ord(BrakeCtrlPos > 0); - SendCtrlToNext("BrakeCtrl",BrakeCtrlPos,CabNo); - } - else SendCtrlToNext('BrakeCtrl',-2,CabNo); - // else} - // if (not TestFlag(BrakeStatus,b_dmg) and (not - TestFlag(BrakeStatus,b_release))) then - // BrakeStatus:=b_off; {luzowanie jesli dziala oraz nie byl wlaczony - odluzniacz - */ - + --BrakeCtrlPos; // youBy: EP po nowemu DBLO = true; - // if ((BrakePressureTable[BrakeCtrlPos].PipePressureVal<0.0) && - // (BrakePressureTable[BrakeCtrlPos+1].PipePressureVal > 0)) - // LimPipePress:=PipePress; - - // to nic nie robi. Zakomentowałem. GF 20161124 - //if (BrakeSystem == ElectroPneumatic) - // if (BrakeSubsystem != ss_K) - // { - // if ((BrakeCtrlPos * BrakeCtrlPos) == 1) - // { - // // SendCtrlToNext("Brake", BrakeCtrlPos, CabNo); - // // SetFlag(BrakeStatus, b_epused); - // } - // else - // { - // // SendCtrlToNext("Brake", 0, CabNo); - // // SetFlag(BrakeStatus, -b_epused); - // } - // } - // for b:=0 to 1 do {poprawic to!} - // with Couplers[b] do - // if CouplingFlag and ctrain_controll=ctrain_controll then - // Connected^.BrakeCtrlPos:=BrakeCtrlPos; - // +// if ((BrakePressureTable[BrakeCtrlPos].PipePressureVal<0.0) && +// (BrakePressureTable[BrakeCtrlPos+1].PipePressureVal > 0)) +// LimPipePress=PipePress; } else DBLO = false; } - else - DBLO = false; return DBLO; } diff --git a/Track.cpp b/Track.cpp index 497ddfb2..09663ef7 100644 --- a/Track.cpp +++ b/Track.cpp @@ -1409,7 +1409,10 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) { case tt_Switch: // dla zwrotnicy dwa razy szyny if( m_material1 || m_material2 ) { // iglice liczone tylko dla zwrotnic - gfx::basic_vertex rpts3[24], rpts4[24]; + gfx::basic_vertex + rpts3[24], + rpts4[24]; + glm::vec3 const flipxvalue { -1, 1, 1 }; for( int i = 0; i < 12; ++i ) { rpts3[ i ] = { @@ -1428,17 +1431,17 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) { { ( -fHTW - iglica[ i ].position.x ) * cos1 + iglica[ i ].position.y * sin1, -( -fHTW - iglica[ i ].position.x ) * sin1 + iglica[ i ].position.y * cos1, 0.f}, - {iglica[ i ].normal}, + {iglica[ i ].normal * flipxvalue}, {iglica[ i ].texture.x, 0.f} }; rpts4[ 23 - i ] = { { ( -fHTW2 - szyna[ i ].position.x ) * cos2 + szyna[ i ].position.y * sin2, -( -fHTW2 - szyna[ i ].position.x ) * sin2 + iglica[ i ].position.y * cos2, 0.f}, - {szyna[ i ].normal}, + {szyna[ i ].normal * flipxvalue}, {szyna[ i ].texture.x, 0.f} }; } // TODO, TBD: change all track geometry to triangles, to allow packing data in less, larger buffers - auto const bladelength { 2 * Global.SplineFidelity }; + auto const bladelength { static_cast( std::ceil( SwitchExtension->Segments[ 0 ]->RaSegCount() * 0.65 ) ) }; if (SwitchExtension->RightSwitch) { // nowa wersja z SPKS, ale odwrotnie lewa/prawa gfx::vertex_array vertices; @@ -2464,6 +2467,7 @@ TTrack * TTrack::RaAnimate() gfx::basic_vertex rpts3[ 24 ], rpts4[ 24 ]; + glm::vec3 const flipxvalue { -1, 1, 1 }; for (int i = 0; i < 12; ++i) { rpts3[ i ] = { @@ -2482,19 +2486,18 @@ TTrack * TTrack::RaAnimate() {+( -fHTW - iglica[ i ].position.x ) * cos1 + iglica[ i ].position.y * sin1, -( -fHTW - iglica[ i ].position.x ) * sin1 + iglica[ i ].position.y * cos1, 0.f}, - {iglica[ i ].normal}, + {iglica[ i ].normal * flipxvalue}, {iglica[ i ].texture.x, 0.f} }; rpts4[ 23 - i ] = { { ( -fHTW2 - szyna[ i ].position.x ) * cos2 + szyna[ i ].position.y * sin2, -( -fHTW2 - szyna[ i ].position.x ) * sin2 + iglica[ i ].position.y * cos2, 0.f}, - {szyna[ i ].normal}, + {szyna[ i ].normal * flipxvalue}, {szyna[ i ].texture.x, 0.f} }; } gfx::vertex_array vertices; - - auto const bladelength { 2 * Global.SplineFidelity }; + auto const bladelength { static_cast( std::ceil( SwitchExtension->Segments[ 0 ]->RaSegCount() * 0.65 ) ) }; if (SwitchExtension->RightSwitch) { // nowa wersja z SPKS, ale odwrotnie lewa/prawa if( m_material1 ) { diff --git a/Train.cpp b/Train.cpp index 310ca4f3..0009c254 100644 --- a/Train.cpp +++ b/Train.cpp @@ -4832,8 +4832,8 @@ bool TTrain::Update( double const Deltatime ) // hunter-080812: wyrzucanie szybkiego na elektrykach gdy nie ma napiecia przy dowolnym ustawieniu kierunkowego // Ra: to już jest w T_MoverParameters::TractionForce(), ale zależy od kierunku if( ( mvControlled->Mains ) - && ( mvControlled->EngineType == TEngineType::ElectricSeriesMotor ) ) { - if( std::max( mvControlled->GetTrainsetVoltage(), std::fabs( mvControlled->RunningTraction.TractionVoltage ) ) < 0.5 * mvControlled->EnginePowerSource.MaxVoltage ) { + && ( mvControlled->EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) ) { + if( std::max( mvControlled->GetTrainsetVoltage(), std::abs( mvControlled->RunningTraction.TractionVoltage ) ) < 0.5 * mvControlled->EnginePowerSource.MaxVoltage ) { // TODO: check whether it should affect entire consist for EMU // TODO: check whether it should happen if there's power supplied alternatively through hvcouplers // TODO: potentially move this to the mover module, as there isn't much reason to have this dependent on the operator presence @@ -5627,24 +5627,28 @@ bool TTrain::Update( double const Deltatime ) } case 1: { //światło wewnętrzne przygaszone (255 216 176) - if( mvOccupied->ConverterFlag == true ) { - // jasnosc dla zalaczonej przetwornicy - DynamicObject->InteriorLightLevel = 0.4f; - } - else { - DynamicObject->InteriorLightLevel = 0.2f; - } + auto const converteractive { ( + ( mvOccupied->ConverterFlag ) + || ( ( ( mvOccupied->Couplers[ side::front ].CouplingFlag & coupling::permanent ) != 0 ) && mvOccupied->Couplers[ side::front ].Connected->ConverterFlag ) + || ( ( ( mvOccupied->Couplers[ side::rear ].CouplingFlag & coupling::permanent ) != 0 ) && mvOccupied->Couplers[ side::rear ].Connected->ConverterFlag ) ) }; + + DynamicObject->InteriorLightLevel = ( + converteractive ? + 0.4f : + 0.2f ); break; } case 2: { //światło wewnętrzne zapalone (255 216 176) - if( mvOccupied->ConverterFlag == true ) { - // jasnosc dla zalaczonej przetwornicy - DynamicObject->InteriorLightLevel = 1.0f; - } - else { - DynamicObject->InteriorLightLevel = 0.5f; - } + auto const converteractive { ( + ( mvOccupied->ConverterFlag ) + || ( ( ( mvOccupied->Couplers[ side::front ].CouplingFlag & coupling::permanent ) != 0 ) && mvOccupied->Couplers[ side::front ].Connected->ConverterFlag ) + || ( ( ( mvOccupied->Couplers[ side::rear ].CouplingFlag & coupling::permanent ) != 0 ) && mvOccupied->Couplers[ side::rear ].Connected->ConverterFlag ) ) }; + + DynamicObject->InteriorLightLevel = ( + converteractive ? + 1.0f : + 0.5f ); break; } } diff --git a/TrkFoll.cpp b/TrkFoll.cpp index b1bfab6c..0d828768 100644 --- a/TrkFoll.cpp +++ b/TrkFoll.cpp @@ -95,6 +95,11 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary) { // przesuwanie wózka po torach o odległość (fDistance), z wyzwoleniem eventów // bPrimary=true - jest pierwszą osią w pojeździe, czyli generuje eventy i przepisuje pojazd // Ra: zwraca false, jeśli pojazd ma być usunięty + auto const ismoving { ( std::abs( fDistance ) > 0.01 ) && ( Owner->GetVelocity() > 0.01 ) }; + int const eventfilter { ( + ( ( true == ismoving ) && ( Owner->ctOwner != nullptr ) ) ? + Owner->ctOwner->Direction() * ( Owner->ctOwner->Vehicle()->DirectionGet() == Owner->DirectionGet() ? 1 : -1 ) * ( fDirection > 0 ? 1 : -1 ) : + 0 ) }; fDistance *= fDirection; // dystans mnożnony przez kierunek double s; // roboczy dystans double dir; // zapamiętany kierunek do sprawdzenia, czy się zmienił @@ -105,8 +110,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary) // TODO: refactor following block as track method if( pCurrentTrack->m_events ) { // sumaryczna informacja o eventach // omijamy cały ten blok, gdy tor nie ma on żadnych eventów (większość nie ma) - if( ( std::abs( fDistance ) < 0.01 ) - && ( Owner->GetVelocity() < 0.01 ) ) { + if( false == ismoving ) { //McZapkie-140602: wyzwalanie zdarzenia gdy pojazd stoi if( ( Owner->Mechanik != nullptr ) && ( Owner->Mechanik->Primary() ) ) { @@ -115,7 +119,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary) } pCurrentTrack->QueueEvents( pCurrentTrack->m_events0all, Owner ); } - else if (fDistance < 0) { + else if( (fDistance < 0) && ( eventfilter < 0 ) ) { // event1, eventall1 if( SetFlag( iEventFlag, -1 ) ) { // zawsze zeruje flagę sprawdzenia, jak mechanik dosiądzie, to się nie wykona @@ -135,7 +139,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary) } } } - else if (fDistance > 0) { + else if( ( fDistance > 0 ) && ( eventfilter > 0 ) ) { // event2, eventall2 if( SetFlag( iEventFlag, -2 ) ) { // zawsze ustawia flagę sprawdzenia, jak mechanik dosiądzie, to się nie wykona diff --git a/material.cpp b/material.cpp index 0cfad9d4..f11b97a1 100644 --- a/material.cpp +++ b/material.cpp @@ -55,14 +55,16 @@ opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool c ; // all work is done in the header } } - else if( key == "texture1:" ) { + else if( ( key == "texture1:" ) + || ( key == "texture_diffuse:" ) ) { if( ( texture1 == null_handle ) || ( Priority > priority1 ) ) { texture1 = GfxRenderer.Fetch_Texture( value, Loadnow ); priority1 = Priority; } } - else if( key == "texture2:" ) { + else if( ( key == "texture2:" ) + || ( key == "texture_normalmap:" ) ) { if( ( texture2 == null_handle ) || ( Priority > priority2 ) ) { texture2 = GfxRenderer.Fetch_Texture( value, Loadnow );