diff --git a/Driver.cpp b/Driver.cpp index e3201111..2f81de54 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -456,7 +456,7 @@ bool TController::TableAddNew() return true; // false gdy się nałoży }; -bool TController::TableNotFound(basic_event const *Event) const +bool TController::TableNotFound(basic_event const *Event, double const Distance ) const { // sprawdzenie, czy nie został już dodany do tabelki (np. podwójne W4 robi problemy) auto lookup = std::find_if( @@ -471,7 +471,11 @@ bool TController::TableNotFound(basic_event const *Event) const WriteLog( "Speed table for " + OwnerName() + " already contains event " + lookup->evEvent->m_name ); } - return lookup == sSpeedTable.end(); + // ignore duplicates which seem to be reasonably apart from each other, on account of looping tracks + // NOTE: since supplied distance is only rough approximation of distance to the event, we're using large safety margin + return ( + ( lookup == sSpeedTable.end() ) + || ( Distance - lookup->fDist > 100.0 ) ); }; void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) @@ -575,7 +579,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) for( auto *pEvent : events ) { if( pEvent != nullptr ) // jeśli jest semafor na tym torze { // trzeba sprawdzić tabelkę, bo dodawanie drugi raz tego samego przystanku nie jest korzystne - if (TableNotFound(pEvent)) // jeśli nie ma + if (TableNotFound(pEvent, fCurrentDistance)) // jeśli nie ma { TableAddNew(); // zawsze jest true @@ -2368,6 +2372,10 @@ double TController::BrakeAccFactor() const || ( mvOccupied->Vel > VelDesired + fVelPlus ) ) ) { Factor += ( fBrakeReaction * ( /*mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.5 ? 1.5 : 1 ) ) * mvOccupied->Vel / ( std::max( 0.0, ActualProximityDist ) + 1 ) * ( ( AccDesired - AbsAccS_pub ) / fAccThreshold ); } +/* + if (mvOccupied->TrainType == dt_DMU && mvOccupied->Vel > 40 && VelNext<40) + Factor *= 1 + ( (1600 - VelNext * VelNext) / (mvOccupied->Vel * mvOccupied->Vel) ); +*/ return Factor; } @@ -2984,6 +2992,7 @@ bool TController::IncSpeed() // 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 sufficientacceleration { AbsAccS_pub >= ( IsHeavyCargoTrain ? 0.02 : 0.04 ) }; 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 { @@ -2995,6 +3004,7 @@ bool TController::IncSpeed() ( mvControlling->Imax > mvControlling->ImaxLo ) || ( fVoltage < useseriesmodevoltage ) || ( ( true == sufficienttractionforce ) + && ( true == sufficientacceleration ) && ( 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) @@ -3004,6 +3014,7 @@ bool TController::IncSpeed() && ( useseriesmode ? mvControlling->RList[ mvControlling->MainCtrlPos ].Bn == 1 : ( ( true == sufficienttractionforce ) + && ( true == sufficientacceleration ) && ( mvOccupied->Vel <= ( IsCargoTrain ? 55 : 45 ) + ( parallelmodefieldshunting ? 5 : 0 ) ) ? mvControlling->RList[ mvControlling->MainCtrlPos ].Bn > 1 : mvControlling->MainCtrlPos == mvControlling->MainCtrlPosNo ) ) ); diff --git a/Driver.h b/Driver.h index d75de7d1..4abade2c 100644 --- a/Driver.h +++ b/Driver.h @@ -363,7 +363,7 @@ private: // Ra: metody obsługujące skanowanie toru std::vector CheckTrackEvent( TTrack *Track, double const fDirection ) const; bool TableAddNew(); - bool TableNotFound( basic_event const *Event ) const; + bool TableNotFound( basic_event const *Event, double const Distance ) const; void TableTraceRoute( double fDistance, TDynamicObject *pVehicle ); void TableCheck( double fDistance ); TCommandType TableUpdate( double &fVelDes, double &fDist, double &fNext, double &fAcc ); diff --git a/Globals.cpp b/Globals.cpp index 41ebbc35..562b6b2c 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -127,7 +127,13 @@ global_settings::ConfigParse(cParser &Parser) { // selected device for audio renderer Parser.getTokens(); Parser >> AudioVolume; - AudioVolume = clamp( AudioVolume, 0.0f, 2.f ); + AudioVolume = clamp( AudioVolume, 0.f, 2.f ); + } + else if( token == "sound.volume.radio" ) { + // selected device for audio renderer + Parser.getTokens(); + Parser >> RadioVolume; + RadioVolume = clamp( RadioVolume, 0.f, 1.f ); } // else if (str==AnsiString("renderalpha")) //McZapkie-1312302 - dwuprzebiegowe renderowanie // bRenderAlpha=(GetNextSymbol().LowerCase()==AnsiString("yes")); diff --git a/Globals.h b/Globals.h index 2b1f9dd8..9348b9d1 100644 --- a/Globals.h +++ b/Globals.h @@ -133,7 +133,8 @@ struct global_settings { double fFpsMax{ 65.0 }; // górna granica FPS, przy której promień scenerii będzie zwiększany // audio bool bSoundEnabled{ true }; - float AudioVolume{ 1.25f }; + float AudioVolume{ 1.f }; + float RadioVolume{ 0.75f }; std::string AudioRenderer; // input float fMouseXScale{ 1.5f }; diff --git a/McZapkie/Mover.cpp b/McZapkie/Mover.cpp index 3aaa4d88..15f84897 100644 --- a/McZapkie/Mover.cpp +++ b/McZapkie/Mover.cpp @@ -3891,7 +3891,18 @@ void TMoverParameters::ComputeConstans(void) } Ff = TotalMassxg * (BearingF + RollF * V * V / 10.0) / 1000.0; // dorobic liczenie temperatury lozyska! - FrictConst1 = ((TotalMassxg * RollF) / 10000.0) + (Cx * Dim.W * Dim.H); + FrictConst1 = ( TotalMassxg * RollF ) / 10000.0; + // drag calculation + { + // NOTE: draft effect of previous vehicle is simplified and doesn't have much to do with reality + auto const *previousvehicle { Couplers[ ( V >= 0.0 ? end::front : end::rear ) ].Connected }; + auto dragarea { Dim.W * Dim.H }; + if( previousvehicle ) { + dragarea = std::max( 0.0, dragarea - ( 0.85 * previousvehicle->Dim.W * previousvehicle->Dim.H ) ); + } + FrictConst1 += Cx * dragarea; + } + Curvature = abs(RunningShape.R); // zero oznacza nieskończony promień if (Curvature > 0.0) Curvature = 1.0 / Curvature; diff --git a/McZapkie/hamulce.cpp b/McZapkie/hamulce.cpp index 7efb0994..c6c33e34 100644 --- a/McZapkie/hamulce.cpp +++ b/McZapkie/hamulce.cpp @@ -2773,6 +2773,8 @@ double TMHZ_K5P::GetPF(double i_bcp, double PP, double HP, double dt, double ep) void TMHZ_K5P::Init(double Press) { CP = Press; + Time = true; + TimeEP = true; } void TMHZ_K5P::SetReductor(double nAdj) diff --git a/Train.cpp b/Train.cpp index eb0c4d74..0555adac 100644 --- a/Train.cpp +++ b/Train.cpp @@ -6537,7 +6537,7 @@ void TTrain::update_sounds_radio() { auto const volume { ( true == radioenabled ) && ( message.first == iRadioChannel ) ? - 1.0 : + Global.RadioVolume : 0.0 }; message.second->gain( volume ); } diff --git a/version.h b/version.h index 8f8c33cb..62cba964 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 19 -#define VERSION_MINOR 411 +#define VERSION_MINOR 419 #define VERSION_REVISION 0