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

minor bug fixes

This commit is contained in:
tmj-fstate
2021-03-04 23:36:36 +01:00
parent 517c9c89f8
commit 4aff092167
9 changed files with 241 additions and 189 deletions

View File

@@ -37,8 +37,6 @@ http://mozilla.org/MPL/2.0/.
#define LOGBACKSCAN 0 #define LOGBACKSCAN 0
#define LOGPRESS 0 #define LOGPRESS 0
auto const EU07_AI_NOACCELERATION = -0.05;
// finds point of specified track nearest to specified event. returns: distance to that point from the specified end of the track // finds point of specified track nearest to specified event. returns: distance to that point from the specified end of the track
// TODO: move this to file with all generic routines, too easy to forget it's here and it may come useful // TODO: move this to file with all generic routines, too easy to forget it's here and it may come useful
double double
@@ -1660,7 +1658,7 @@ TController::braking_distance_multiplier( float const Targetvelocity ) const {
if( Targetvelocity > 65.f ) { return 1.f * frictionmultiplier; } if( Targetvelocity > 65.f ) { return 1.f * frictionmultiplier; }
if( Targetvelocity < 5.f ) { if( Targetvelocity < 5.f ) {
// HACK: engaged automatic transmission means extra/earlier braking effort is needed for the last leg before full stop // HACK: engaged automatic transmission means extra/earlier braking effort is needed for the last leg before full stop
if( ( mvOccupied->TrainType == dt_DMU ) if( ( is_dmu() )
&& ( mvOccupied->Vel < 40.0 ) && ( mvOccupied->Vel < 40.0 )
&& ( Targetvelocity == 0.f ) ) { && ( Targetvelocity == 0.f ) ) {
auto const multiplier { clamp( 1.f + iVehicles * 0.5f, 2.f, 4.f ) }; auto const multiplier { clamp( 1.f + iVehicles * 0.5f, 2.f, 4.f ) };
@@ -1814,8 +1812,8 @@ TController::TController(bool AI, TDynamicObject *NewControll, bool InitPsyche,
// fAccThreshold może podlegać uczeniu się - hamowanie powinno być rejestrowane, a potem analizowane // fAccThreshold może podlegać uczeniu się - hamowanie powinno być rejestrowane, a potem analizowane
// próg opóźnienia dla zadziałania hamulca // próg opóźnienia dla zadziałania hamulca
fAccThreshold = ( fAccThreshold = (
mvOccupied->TrainType == dt_EZT ? -0.55 : is_emu() ? -0.55 :
mvOccupied->TrainType == dt_DMU ? -0.45 : is_dmu() ? -0.45 :
-0.2 ); -0.2 );
/* /*
// HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors // HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors
@@ -2181,11 +2179,11 @@ void TController::AutoRewident()
if( OrderCurrentGet() & ( Shunt | Loose_shunt ) ) { if( OrderCurrentGet() & ( Shunt | Loose_shunt ) ) {
// for uniform behaviour and compatibility with older scenarios set default acceleration table values for shunting // for uniform behaviour and compatibility with older scenarios set default acceleration table values for shunting
fAccThreshold = ( fAccThreshold = (
mvOccupied->TrainType == dt_EZT ? -0.55 : is_emu() ? -0.55 :
mvOccupied->TrainType == dt_DMU ? -0.45 : is_dmu() ? -0.45 :
-0.2 ); -0.2 );
// HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors // HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors
if( ( mvOccupied->TrainType == dt_EZT ) if( ( is_emu() )
&& ( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) ) { && ( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) ) {
fAccThreshold += 0.10; fAccThreshold += 0.10;
} }
@@ -2211,8 +2209,8 @@ void TController::AutoRewident()
fBrake_a1[i+1] /= (12*fMass); fBrake_a1[i+1] /= (12*fMass);
} }
IsPassengerTrain = ( mvOccupied->CategoryFlag == 1 ) && ( mvOccupied->TrainType != dt_EZT ) && ( mvOccupied->TrainType != dt_DMU ) && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) == 0 ); IsPassengerTrain = ( is_train() ) && ( false == is_emu() ) && ( false == is_dmu() ) && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) == 0 );
IsCargoTrain = ( mvOccupied->CategoryFlag == 1 ) && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 ); IsCargoTrain = ( is_train() ) && ( ( mvOccupied->BrakeDelayFlag & bdelay_G ) != 0 );
IsHeavyCargoTrain = ( true == IsCargoTrain ) && ( fBrake_a0[ 1 ] > 0.4 ) && ( iVehicles - ControlledEnginesCount > 0 ) && ( fMass / iVehicles > 50000 ); IsHeavyCargoTrain = ( true == IsCargoTrain ) && ( fBrake_a0[ 1 ] > 0.4 ) && ( iVehicles - ControlledEnginesCount > 0 ) && ( fMass / iVehicles > 50000 );
BrakingInitialLevel = ( BrakingInitialLevel = (
@@ -2225,7 +2223,7 @@ void TController::AutoRewident()
IsCargoTrain ? 0.25 : IsCargoTrain ? 0.25 :
0.25 ); 0.25 );
if( mvOccupied->TrainType == dt_EZT ) { if( is_emu() ) {
if( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) { if( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) {
// HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors // HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors
fNominalAccThreshold = std::max( -0.60, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] ); fNominalAccThreshold = std::max( -0.60, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
@@ -2235,7 +2233,7 @@ void TController::AutoRewident()
} }
fBrakeReaction = 0.25; fBrakeReaction = 0.25;
} }
else if( mvOccupied->TrainType == dt_DMU ) { else if( is_dmu() ) {
fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] ); fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
fBrakeReaction = 0.25; fBrakeReaction = 0.25;
} }
@@ -2421,6 +2419,7 @@ bool TController::CheckVehicles(TOrders user)
if( mvOccupied->LightsPosNo > 0 ) { if( mvOccupied->LightsPosNo > 0 ) {
pVehicle->SetLights(); pVehicle->SetLights();
} }
if( iEngineActive ) {
// potentially adjust light state // potentially adjust light state
control_lights(); control_lights();
// custom ai action for disconnect mode: switch off lights on disconnected vehicle(s) // custom ai action for disconnect mode: switch off lights on disconnected vehicle(s)
@@ -2443,7 +2442,7 @@ bool TController::CheckVehicles(TOrders user)
{ {
// HACK: to account for su-45/46 shortcomings diesel-powered engines only activate heating in cold conditions // HACK: to account for su-45/46 shortcomings diesel-powered engines only activate heating in cold conditions
// TODO: take instead into account presence of converters in attached cars, once said presence is possible to specify // TODO: take instead into account presence of converters in attached cars, once said presence is possible to specify
auto const isheatingneeded { ( auto const isheatingneeded{ (
IsCargoTrain ? false : IsCargoTrain ? false :
has_diesel_engine() ? ( Global.AirTemperature < 10 ) : has_diesel_engine() ? ( Global.AirTemperature < 10 ) :
true ) }; true ) };
@@ -2454,6 +2453,7 @@ bool TController::CheckVehicles(TOrders user)
locale::string::driver_hint_consistheatingoff ); locale::string::driver_hint_consistheatingoff );
} }
} }
}
if( OrderCurrentGet() & ( Shunt | Loose_shunt | Obey_train | Bank ) ) { if( OrderCurrentGet() & ( Shunt | Loose_shunt | Obey_train | Bank ) ) {
// nastawianie hamulca do jazdy pociągowej // nastawianie hamulca do jazdy pociągowej
AutoRewident(); AutoRewident();
@@ -2469,8 +2469,8 @@ bool TController::CheckVehicles(TOrders user)
} }
// Ra 2014-09: tymczasowo prymitywne ustawienie warunku pod kątem SN61 // Ra 2014-09: tymczasowo prymitywne ustawienie warunku pod kątem SN61
if( ( mvOccupied->TrainType == dt_EZT ) if( ( is_emu() )
|| ( mvOccupied->TrainType == dt_DMU ) || ( is_dmu() )
|| ( iVehicles == 1 ) ) { || ( iVehicles == 1 ) ) {
// zmiana czoła przez zmianę kabiny // zmiana czoła przez zmianę kabiny
iDrivigFlags |= movePushPull; iDrivigFlags |= movePushPull;
@@ -2539,7 +2539,7 @@ int TController::OrderDirectionChange(int newdir, TMoverParameters *Vehicle)
IncBrake(); // niech hamuje IncBrake(); // niech hamuje
if (Vehicle->DirActive == testd * Vehicle->CabActive) if (Vehicle->DirActive == testd * Vehicle->CabActive)
VelforDriver = -1; // można jechać, bo kierunek jest zgodny z żądanym VelforDriver = -1; // można jechać, bo kierunek jest zgodny z żądanym
if (Vehicle->TrainType == dt_EZT) if (is_emu())
if (Vehicle->DirActive > 0) if (Vehicle->DirActive > 0)
// if () //tylko jeśli jazda pociągowa (tego nie wiemy w momencie odpalania silnika) // if () //tylko jeśli jazda pociągowa (tego nie wiemy w momencie odpalania silnika)
Vehicle->DirectionForward(); // Ra: z przekazaniem do silnikowego Vehicle->DirectionForward(); // Ra: z przekazaniem do silnikowego
@@ -2642,7 +2642,13 @@ bool TController::PrepareEngine()
if( ( mvPantographUnit->EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) if( ( mvPantographUnit->EnginePowerSource.SourceType == TPowerSource::CurrentCollector )
&& ( mvPantographUnit->EnginePowerSource.CollectorParameters.CollectorsNo > 0 ) ) { && ( mvPantographUnit->EnginePowerSource.CollectorParameters.CollectorsNo > 0 ) ) {
// if our pantograph unit isn't a pantograph-devoid fallback // if our pantograph unit isn't a pantograph-devoid fallback
if (mvPantographUnit->PantPress < 4.2) { auto const sufficientpantographpressure { (
is_emu() ?
2.5 : // Ra 2013-12: Niebugocław mówi, że w EZT podnoszą się przy 2.5
3.5 )
+ 0.1 }; // leeway margin
if (mvPantographUnit->PantPress < sufficientpantographpressure) {
// załączenie małej sprężarki // załączenie małej sprężarki
if( false == mvPantographUnit->PantAutoValve ) { if( false == mvPantographUnit->PantAutoValve ) {
// odłączenie zbiornika głównego, bo z nim nie da rady napompować // odłączenie zbiornika głównego, bo z nim nie da rady napompować
@@ -2715,10 +2721,6 @@ bool TController::PrepareEngine()
cue_action( locale::string::driver_hint_rearmotorblowerson ); cue_action( locale::string::driver_hint_rearmotorblowerson );
} }
} }
// set up train brake
if( mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos( bh_RP ) ) {
cue_action( locale::string::driver_hint_trainbrakerelease );
}
// sync virtual brake state with the 'real' one // sync virtual brake state with the 'real' one
if( mvOccupied->BrakeHandle != TBrakeHandle::NoHandle ) { if( mvOccupied->BrakeHandle != TBrakeHandle::NoHandle ) {
std::unordered_map<int, int> const brakepositions{ std::unordered_map<int, int> const brakepositions{
@@ -2730,6 +2732,10 @@ bool TController::PrepareEngine()
BrakeLevelSet( lookup->second ); // GBH BrakeLevelSet( lookup->second ); // GBH
} }
} }
// set up train brake
if( mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos( bh_RP ) ) {
cue_action( locale::string::driver_hint_trainbrakerelease );
}
// sync spring brake state across consist // sync spring brake state across consist
cue_action( cue_action(
mvOccupied->SpringBrake.Activate ? mvOccupied->SpringBrake.Activate ?
@@ -2885,7 +2891,7 @@ bool TController::IncBrake()
standalone = false; standalone = false;
} }
} }
else if( mvOccupied->TrainType == dt_DMU ) { else if( is_dmu() ) {
// enforce use of train brake for DMUs // enforce use of train brake for DMUs
standalone = false; standalone = false;
} }
@@ -2964,7 +2970,7 @@ bool TController::IncBrake()
if( /*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.1 ) { if( /*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition < 0.1 ) {
OK = /*mvOccupied->*/BrakeLevelAdd( BrakingInitialLevel ); //GBH OK = /*mvOccupied->*/BrakeLevelAdd( BrakingInitialLevel ); //GBH
// HACK: stronger braking to overcome SA134 engine behaviour // HACK: stronger braking to overcome SA134 engine behaviour
if( ( mvOccupied->TrainType == dt_DMU ) if( ( is_dmu() )
&& ( VelNext == 0.0 ) && ( VelNext == 0.0 )
&& ( fBrakeDist < 200.0 ) ) { && ( fBrakeDist < 200.0 ) ) {
BrakeLevelAdd( BrakeLevelAdd(
@@ -3099,7 +3105,7 @@ bool TController::DecBrake() {
auto deltaAcc { -1.0 }; auto deltaAcc { -1.0 };
if( ( fBrake_a0[ 0 ] != 0.0 ) if( ( fBrake_a0[ 0 ] != 0.0 )
|| ( fBrake_a1[ 0 ] != 0.0 ) ) { || ( fBrake_a1[ 0 ] != 0.0 ) ) {
auto const pos_diff { ( mvOccupied->TrainType == dt_DMU ? 0.25 : 1.0 ) }; auto const pos_diff { ( is_dmu() ? 0.25 : 1.0 ) };
deltaAcc = -AccDesired * BrakeAccFactor() - ( fBrake_a0[ 0 ] + 4 * (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition - pos_diff )*fBrake_a1[ 0 ] ); deltaAcc = -AccDesired * BrakeAccFactor() - ( fBrake_a0[ 0 ] + 4 * (/*GBH mvOccupied->BrakeCtrlPosR*/BrakeCtrlPosition - pos_diff )*fBrake_a1[ 0 ] );
} }
if (deltaAcc < 0) { if (deltaAcc < 0) {
@@ -4752,17 +4758,19 @@ TController::Update( double const Timedelta ) {
scan_route( awarenessrange ); scan_route( awarenessrange );
scan_obstacles( awarenessrange ); scan_obstacles( awarenessrange );
// generic actions // generic actions
control_wheelslip();
control_security_system( reactiontime ); control_security_system( reactiontime );
if( iEngineActive ) {
control_wheelslip();
control_horns( reactiontime ); control_horns( reactiontime );
control_pantographs(); control_pantographs();
CheckTimeControllers();
if( fActionTime > 0.0 ) { if( fActionTime > 0.0 ) {
// potentially delayed and/or low priority actions // potentially delayed and/or low priority actions
control_lights(); control_lights();
control_doors(); control_doors();
control_compartment_lights(); control_compartment_lights();
} }
}
CheckTimeControllers();
// external command actions // external command actions
UpdateCommand(); UpdateCommand();
// mode specific actions // mode specific actions
@@ -4770,9 +4778,11 @@ TController::Update( double const Timedelta ) {
handle_orders(); handle_orders();
// situational velocity and acceleration adjustments // situational velocity and acceleration adjustments
pick_optimal_speed( awarenessrange ); pick_optimal_speed( awarenessrange );
if( iEngineActive ) {
control_tractive_and_braking_force(); control_tractive_and_braking_force();
}
SetTimeControllers(); SetTimeControllers();
// if the route ahead is blocked we might need to head the other way // if the route ahead is blocked we might need to head the other way
check_route_behind( 1000 ); // NOTE: legacy scan range value check_route_behind( 1000 ); // NOTE: legacy scan range value
} }
@@ -5531,7 +5541,7 @@ void TController::sync_consist_reversers() {
auto const currentdirection { mvOccupied->DirActive }; auto const currentdirection { mvOccupied->DirActive };
auto const fastforward { ( auto const fastforward { (
( mvOccupied->TrainType == dt_EZT ) ( is_emu() )
&& ( mvOccupied->EngineType != TEngineType::ElectricInductionMotor ) ) && ( mvOccupied->EngineType != TEngineType::ElectricInductionMotor ) )
&& ( mvOccupied->Imin == mvOccupied->IminHi ) }; && ( mvOccupied->Imin == mvOccupied->IminHi ) };
@@ -5749,7 +5759,7 @@ TController::determine_consist_state() {
fBrake_a0[0] = fBrake_a0[index]; fBrake_a0[0] = fBrake_a0[index];
fBrake_a1[0] = fBrake_a1[index]; fBrake_a1[0] = fBrake_a1[index];
if ((mvOccupied->TrainType == dt_EZT) || (mvOccupied->TrainType == dt_DMU)) { if ((is_emu()) || (is_dmu())) {
auto Coeff = clamp( mvOccupied->Vel*0.015 , 0.5 , 1.0); auto Coeff = clamp( mvOccupied->Vel*0.015 , 0.5 , 1.0);
fAccThreshold = fNominalAccThreshold * Coeff - fBrake_a0[BrakeAccTableSize] * (1.0 - Coeff); fAccThreshold = fNominalAccThreshold * Coeff - fBrake_a0[BrakeAccTableSize] * (1.0 - Coeff);
} }
@@ -5895,6 +5905,12 @@ TController::determine_consist_state() {
} }
p = p->Next(); // pojazd podłączony z tyłu (patrząc od czoła) p = p->Next(); // pojazd podłączony z tyłu (patrząc od czoła)
} }
// test consist state for external events and/or weird things human user could've done
iEngineActive &=
( false == IsAnyConverterOverloadRelayOpen )
&& ( false == IsAnyLineBreakerOpen )
&& ( true == IsAnyConverterEnabled )
&& ( true == IsAnyCompressorEnabled );
} }
void void
@@ -5939,7 +5955,7 @@ TController::control_pantographs() {
// raise/lower pantographs as needed // raise/lower pantographs as needed
auto const useregularpantographlayout { auto const useregularpantographlayout {
( pVehicle->NextC( coupling::control ) == nullptr ) // standalone ( pVehicle->NextC( coupling::control ) == nullptr ) // standalone
|| ( mvControlling->TrainType == dt_EZT ) // special case || ( is_emu() ) // special case
|| ( mvControlling->TrainType == dt_ET41 ) }; // special case || ( mvControlling->TrainType == dt_ET41 ) }; // special case
if( mvOccupied->Vel > 0.05 ) { if( mvOccupied->Vel > 0.05 ) {
@@ -6080,6 +6096,10 @@ TController::control_security_system( double const Timedelta ) {
if( mvOccupied->SecuritySystem.Status >= s_aware ) { if( mvOccupied->SecuritySystem.Status >= s_aware ) {
// jak zadziałało CA/SHP // jak zadziałało CA/SHP
if( ( false == is_emu() )
&& ( mvOccupied->DirActive == 0 ) ) {
cue_action( locale::string::driver_hint_directionforward );
}
cue_action( locale::string::driver_hint_securitysystemreset ); // to skasuj cue_action( locale::string::driver_hint_securitysystemreset ); // to skasuj
if( ( BrakeCtrlPosition == 0 ) // TODO: verify whether it's 0 in all vehicle types if( ( BrakeCtrlPosition == 0 ) // TODO: verify whether it's 0 in all vehicle types
&& ( AccDesired > 0.0 ) && ( AccDesired > 0.0 )
@@ -6100,7 +6120,8 @@ TController::control_security_system( double const Timedelta ) {
m_radiocontroltime += Timedelta; m_radiocontroltime += Timedelta;
} }
} }
if( ( false == mvOccupied->Radio ) if( ( iEngineActive )
&& ( false == mvOccupied->Radio )
&& ( false == mvOccupied->RadioStopFlag ) ) { && ( false == mvOccupied->RadioStopFlag ) ) {
// otherwise if it's safe to do so, turn the radio back on // otherwise if it's safe to do so, turn the radio back on
// arbitrary 5 sec delay before switching radio back on // arbitrary 5 sec delay before switching radio back on
@@ -6249,10 +6270,9 @@ TController::control_doors() {
void void
TController::UpdateCommand() { TController::UpdateCommand() {
// TBD, TODO: rework recognizecommand() to use hint system, remove driver type condition?
if (AIControllFlag) { if( false == mvOccupied->CommandIn.Command.empty() ) {
if (mvOccupied->CommandIn.Command != "") if( false == mvOccupied->RunInternalCommand() ) {
if( !mvOccupied->RunInternalCommand() ) {
// rozpoznaj komende bo lokomotywa jej nie rozpoznaje // rozpoznaj komende bo lokomotywa jej nie rozpoznaje
RecognizeCommand(); // samo czyta komendę wstawioną do pojazdu? RecognizeCommand(); // samo czyta komendę wstawioną do pojazdu?
} }
@@ -6294,7 +6314,7 @@ TController::determine_braking_distance() {
} }
if( ( mvOccupied->Vel > 15.0 ) if( ( mvOccupied->Vel > 15.0 )
&& ( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) && ( mvControlling->EngineType == TEngineType::ElectricInductionMotor )
&& ( ( mvControlling->TrainType & dt_EZT ) != 0 ) ) { && ( is_emu() ) ) {
// HACK: make the induction motor powered EMUs start braking slightly earlier // HACK: make the induction motor powered EMUs start braking slightly earlier
fBrakeDist += 10.0; fBrakeDist += 10.0;
} }
@@ -6805,9 +6825,7 @@ TController::handle_engine() {
} }
// engine state can potentially deteriorate in one of usual driving modes // engine state can potentially deteriorate in one of usual driving modes
if( ( OrderCurrentGet() & ( Change_direction | Connect | Disconnect | Shunt | Loose_shunt | Obey_train | Bank ) ) if( ( OrderCurrentGet() & ( Change_direction | Connect | Disconnect | Shunt | Loose_shunt | Obey_train | Bank ) )
&& ( ( false == iEngineActive ) && ( false == iEngineActive ) ) {
|| ( IsAnyConverterOverloadRelayOpen ) // wywalił bezpiecznik nadmiarowy przetwornicy
|| ( IsAnyLineBreakerOpen ) ) ) { // WS może wywalić z powodu błędu w drutach
// jeśli coś ma robić to niech odpala do skutku // jeśli coś ma robić to niech odpala do skutku
PrepareEngine(); PrepareEngine();
} }
@@ -6877,7 +6895,7 @@ TController::pick_optimal_speed( double const Range ) {
if( false == TestFlag( iDrivigFlags, moveActive ) ) { if( false == TestFlag( iDrivigFlags, moveActive ) ) {
VelDesired = 0.0; VelDesired = 0.0;
AccDesired = std::min( AccDesired, EU07_AI_NOACCELERATION ); AccDesired = std::min( AccDesired, EU07_AI_NOACCELERATION );
return; // return;
} }
// basic velocity and acceleration adjustments // basic velocity and acceleration adjustments
@@ -7462,7 +7480,7 @@ void TController::control_motor_connectors() {
// ensure motor connectors are active // ensure motor connectors are active
if( ( mvControlling->EngineType == TEngineType::ElectricSeriesMotor ) if( ( mvControlling->EngineType == TEngineType::ElectricSeriesMotor )
|| ( mvControlling->EngineType == TEngineType::DieselElectric ) || ( mvControlling->EngineType == TEngineType::DieselElectric )
|| ( mvControlling->TrainType == dt_EZT ) ) { || ( is_emu() ) ) {
if( Need_TryAgain ) { if( Need_TryAgain ) {
// true, jeśli druga pozycja w elektryku nie załapała // true, jeśli druga pozycja w elektryku nie załapała
cue_action( locale::string::driver_hint_mastercontrollersetzerospeed ); cue_action( locale::string::driver_hint_mastercontrollersetzerospeed );
@@ -7555,7 +7573,7 @@ void TController::control_braking_force() {
} }
} }
if( mvOccupied->TrainType == dt_EZT ) { if( is_emu() ) {
// właściwie, to warunek powinien być na działający EP // właściwie, to warunek powinien być na działający EP
// Ra: to dobrze hamuje EP w EZT // Ra: to dobrze hamuje EP w EZT
auto const accthreshold { ( auto const accthreshold { (

View File

@@ -17,6 +17,8 @@ http://mozilla.org/MPL/2.0/.
#include "mtable.h" #include "mtable.h"
#include "translation.h" #include "translation.h"
auto const EU07_AI_NOACCELERATION = -0.05;
enum TOrders enum TOrders
{ // rozkazy dla AI { // rozkazy dla AI
Wait_for_orders = 0, // czekanie na dostarczenie następnych rozkazów Wait_for_orders = 0, // czekanie na dostarczenie następnych rozkazów
@@ -230,6 +232,10 @@ public:
return TestFlag( mvOccupied->CategoryFlag, 1 ); } return TestFlag( mvOccupied->CategoryFlag, 1 ); }
bool is_car() const { bool is_car() const {
return TestFlag( mvOccupied->CategoryFlag, 2 ); } return TestFlag( mvOccupied->CategoryFlag, 2 ); }
bool is_emu() const {
return ( mvControlling->TrainType == dt_EZT ); }
bool is_dmu() const {
return ( mvControlling->TrainType == dt_DMU ); }
bool has_diesel_engine() const { bool has_diesel_engine() const {
return ( ( mvControlling->EngineType == TEngineType::DieselElectric ) return ( ( mvControlling->EngineType == TEngineType::DieselElectric )
|| ( mvControlling->EngineType == TEngineType::DieselEngine ) ); || ( mvControlling->EngineType == TEngineType::DieselEngine ) );

View File

@@ -5476,32 +5476,56 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
m_powertrainsounds.water_heater.owner( this ); m_powertrainsounds.water_heater.owner( this );
} }
else if( ( ( token == "tractionmotor:" ) || ( token == "tractionacmotor:" ) ) else if( ( token == "tractionmotor:" ) && ( MoverParameters->Power > 0 ) ) {
&& ( MoverParameters->Power > 0 ) ) {
// dc motors are (legacy) default
m_powertrainsounds.dcmotors = ( token == "tractionmotor:" );
// plik z dzwiekiem silnika, mnozniki i ofsety amp. i czest. // plik z dzwiekiem silnika, mnozniki i ofsety amp. i czest.
sound_source motortemplate { sound_placement::external }; sound_source motortemplate { sound_placement::external };
motortemplate.deserialize( parser, sound_type::single, sound_parameters::range | sound_parameters::amplitude | sound_parameters::frequency ); motortemplate.deserialize( parser, sound_type::single, sound_parameters::range | sound_parameters::amplitude | sound_parameters::frequency );
auto const amplitudedivisor { static_cast<float>( MoverParameters->nmax * 60 + MoverParameters->Power * 3 ) };
motortemplate.m_amplitudefactor /= amplitudedivisor;
motortemplate.owner( this ); motortemplate.owner( this );
if( m_powertrainsounds.dcmotors ) { auto &motors { m_powertrainsounds.motors };
auto const amplitudedivisor = static_cast<float>( MoverParameters->nmax * 60 + MoverParameters->Power * 3 );
motortemplate.m_amplitudefactor /= amplitudedivisor;
}
if( true == m_powertrainsounds.motors.empty() ) { if( true == motors.empty() ) {
// fallback for cases without specified motor locations, convert sound template to a single sound source // fallback for cases without specified motor locations, convert sound template to a single sound source
m_powertrainsounds.motors.emplace_back( motortemplate ); motors.emplace_back( motortemplate );
} }
else { else {
// apply configuration to all defined motors // apply configuration to all defined motors
for( auto &motor : m_powertrainsounds.motors ) { for( auto &motor : motors ) {
// combine potential x- and y-axis offsets of the sound template with z-axis offsets of individual motors // combine potential x- and y-axis offsets of the sound template with z-axis offsets of individual motors
auto motoroffset { motortemplate.offset() }; auto motoroffset { motortemplate.offset() };
motoroffset.z = motor.offset().z; motoroffset.z = motor.offset().z;
motor = motortemplate; motor = motortemplate;
motor.offset( motoroffset ); motor.offset( motoroffset );
// apply randomized playback start offset for each instance, to reduce potential reverb with identical nearby sources
motor.start( LocalRandom( 0.0, 1.0 ) );
}
}
}
else if( ( token == "tractionacmotor:" ) && ( MoverParameters->Power > 0 ) ) {
// plik z dzwiekiem silnika, mnozniki i ofsety amp. i czest.
sound_source motortemplate { sound_placement::external };
motortemplate.deserialize( parser, sound_type::single, sound_parameters::range | sound_parameters::amplitude | sound_parameters::frequency );
motortemplate.owner( this );
auto &motors { m_powertrainsounds.acmotors };
if( true == motors.empty() ) {
// fallback for cases without specified motor locations, convert sound template to a single sound source
motors.emplace_back( motortemplate );
}
else {
// apply configuration to all defined motors
for( auto &motor : motors ) {
// combine potential x- and y-axis offsets of the sound template with z-axis offsets of individual motors
auto motoroffset { motortemplate.offset() };
motoroffset.z = motor.offset().z;
motor = motortemplate;
motor.offset( motoroffset );
// apply randomized playback start offset for each instance, to reduce potential reverb with identical nearby sources
motor.start( LocalRandom( 0.0, 1.0 ) );
} }
} }
} }
@@ -5531,6 +5555,8 @@ void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string co
bloweroffset.z = blower.offset().z; bloweroffset.z = blower.offset().z;
blower = blowertemplate; blower = blowertemplate;
blower.offset( bloweroffset ); blower.offset( bloweroffset );
// apply randomized playback start offset for each instance, to reduce potential reverb with identical nearby sources
blower.start( LocalRandom( 0.0, 1.0 ) );
} }
} }
} }
@@ -7587,9 +7613,8 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
// motor sounds // motor sounds
volume = 0.0; volume = 0.0;
// generic traction motor sounds
if( false == motors.empty() ) { if( false == motors.empty() ) {
// ac and dc motors have significantly different sounds
if( dcmotors ) {
if( std::abs( Vehicle.nrot ) > 0.01 ) { if( std::abs( Vehicle.nrot ) > 0.01 ) {
@@ -7678,12 +7703,13 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
} }
} }
} }
else { // inverter-specific traction motor sounds
// ac motors if( false == acmotors.empty() ) {
if( Vehicle.EngineType == TEngineType::ElectricInductionMotor ) { if( Vehicle.EngineType == TEngineType::ElectricInductionMotor ) {
if( Vehicle.InverterFrequency > 0.001 ) { if( Vehicle.InverterFrequency > 0.001 ) {
for( auto &motor : motors ) { for( auto &motor : acmotors ) {
motor motor
.pitch( motor.m_frequencyoffset + motor.m_frequencyfactor * Vehicle.InverterFrequency ) .pitch( motor.m_frequencyoffset + motor.m_frequencyfactor * Vehicle.InverterFrequency )
.gain( motor.m_amplitudeoffset + motor.m_amplitudefactor * std::sqrt( std::abs( Vehicle.eimv_pr ) ) ) .gain( motor.m_amplitudeoffset + motor.m_amplitudefactor * std::sqrt( std::abs( Vehicle.eimv_pr ) ) )
@@ -7691,13 +7717,12 @@ TDynamicObject::powertrain_sounds::render( TMoverParameters const &Vehicle, doub
} }
} }
else { else {
for( auto &motor : motors ) { for( auto &motor : acmotors ) {
motor.stop(); motor.stop();
} }
} }
} }
} }
}
// motor blowers // motor blowers
if( false == motorblowers.empty() ) { if( false == motorblowers.empty() ) {
for( auto &blowersound : motorblowers ) { for( auto &blowersound : motorblowers ) {

View File

@@ -373,8 +373,9 @@ private:
struct powertrain_sounds { struct powertrain_sounds {
sound_source inverter { sound_placement::engine }; sound_source inverter { sound_placement::engine };
std::vector<sound_source> motorblowers; std::vector<sound_source> motorblowers;
std::vector<sound_source> motors; // generally traction motor(s) std::vector<sound_source> motors; // generic traction motor sounds
bool dcmotors { true }; // traction dc motor(s) std::vector<sound_source> acmotors; // inverter-specific traction motor sounds
// bool dcmotors { true }; // traction dc motor(s)
double motor_volume { 0.0 }; // MC: pomocnicze zeby gladziej silnik buczal double motor_volume { 0.0 }; // MC: pomocnicze zeby gladziej silnik buczal
float motor_momentum { 0.f }; // recent change in motor revolutions float motor_momentum { 0.f }; // recent change in motor revolutions
sound_source motor_relay { sound_placement::engine }; sound_source motor_relay { sound_placement::engine };

View File

@@ -829,8 +829,8 @@ putvalues_event::export_as_text_( std::ostream &Output ) const {
bool bool
putvalues_event::is_command_for_owner( input_data const &Input ) const { putvalues_event::is_command_for_owner( input_data const &Input ) const {
if( Input.data_text.rfind( "Load=", 0 ) == std::string::npos ) { return false; } if( starts_with( Input.data_text, "Load=" ) ) { return false; }
if( Input.data_text.rfind( "UnLoad=", 0 ) == std::string::npos ) { return false; } if( starts_with( Input.data_text, "UnLoad=" ) ) { return false; }
// TBD, TODO: add other exceptions // TBD, TODO: add other exceptions
return true; return true;

View File

@@ -550,7 +550,8 @@ TController::cue_action( locale::string const Action, float const Actionparamete
hint( hint(
Action, Action,
[this](float const Parameter) -> bool { [this](float const Parameter) -> bool {
return ( ( AccDesired <= -0.06 ) return ( ( AccDesired <= EU07_AI_NOACCELERATION )
|| ( ( false == Ready ) && ( false == mvOccupied->ShuntMode ) )
|| ( AccDesired - AbsAccS <= 0.05 ) || ( AccDesired - AbsAccS <= 0.05 )
|| ( mvOccupied->EIMCtrlType > 0 ? || ( mvOccupied->EIMCtrlType > 0 ?
( mvControlling->eimic_real >= 1.0 ) : ( mvControlling->eimic_real >= 1.0 ) :
@@ -1250,7 +1251,8 @@ TController::cue_action( locale::string const Action, float const Actionparamete
break; break;
} }
case locale::string::driver_hint_headcodepc5: { case locale::string::driver_hint_headcodepc5: {
if( AIControllFlag || Global.AITrainman ) { if( ( AIControllFlag )
|| ( Global.AITrainman && ( false == pVehicles[ end::rear ]->is_connected( pVehicle, coupling::control ) ) ) ) {
pVehicles[ end::rear ]->RaLightsSet( -1, light::redmarker_left | light::redmarker_right | light::rearendsignals ); pVehicles[ end::rear ]->RaLightsSet( -1, light::redmarker_left | light::redmarker_right | light::rearendsignals );
} }
remove_hint( locale::string::driver_hint_headcodetb1 ); remove_hint( locale::string::driver_hint_headcodetb1 );

View File

@@ -28,7 +28,7 @@ enum class sound_type {
enum sound_parameters { enum sound_parameters {
range = 0x1, range = 0x1,
amplitude = 0x2, amplitude = 0x2,
frequency = 0x4 frequency = 0x4,
}; };
enum sound_flags { enum sound_flags {

View File

@@ -441,10 +441,10 @@ init() {
"Cofnac zezwolenie na otwarcie drzwi", "Cofnac zezwolenie na otwarcie drzwi",
"Podac sygnal dzwiekowy", "Podac sygnal dzwiekowy",
"Wylaczyc syrene", "Wylaczyc syrene",
"Zalaczyc oswietlenie skladu", "Zalaczyc oswietlenie pociagu",
"Wylaczyc oswietlenie skladu", "Wylaczyc oswietlenie pociagu",
"Zalaczyc ogrzewanie skladu", "Zalaczyc ogrzewanie pociagu",
"wylaczyc ogrzewanie skladu", "wylaczyc ogrzewanie pociagu",
"Zbic czuwak", "Zbic czuwak",
"Zalozyc polsprzeg", "Zalozyc polsprzeg",
"Zdjac polsprzeg", "Zdjac polsprzeg",

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 21 #define VERSION_MAJOR 21
#define VERSION_MINOR 303 #define VERSION_MINOR 304
#define VERSION_REVISION 0 #define VERSION_REVISION 0