mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
Merge branch 'milek-dev' into gfx-work
This commit is contained in:
193
Driver.cpp
193
Driver.cpp
@@ -180,9 +180,9 @@ TSpeedPos::TSpeedPos(TTrack *track, double dist, int flag)
|
||||
Set(track, dist, flag);
|
||||
};
|
||||
|
||||
TSpeedPos::TSpeedPos(basic_event *event, double dist, TOrders order)
|
||||
TSpeedPos::TSpeedPos(basic_event *event, double dist, double length, TOrders order)
|
||||
{
|
||||
Set(event, dist, order);
|
||||
Set(event, dist, length, order);
|
||||
};
|
||||
|
||||
void TSpeedPos::Clear()
|
||||
@@ -364,13 +364,20 @@ bool TSpeedPos::IsProperSemaphor(TOrders order)
|
||||
return false; // true gdy zatrzymanie, wtedy nie ma po co skanować dalej
|
||||
}
|
||||
|
||||
bool TSpeedPos::Set(basic_event *event, double dist, TOrders order)
|
||||
bool TSpeedPos::Set(basic_event *event, double dist, double length, TOrders order)
|
||||
{ // zapamiętanie zdarzenia
|
||||
fDist = dist;
|
||||
iFlags = spEnabled | spEvent; // event+istotny
|
||||
iFlags = spEvent;
|
||||
evEvent = event;
|
||||
vPos = event->input_location(); // współrzędne eventu albo komórki pamięci (zrzutować na tor?)
|
||||
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
|
||||
if( dist + length >= 0 ) {
|
||||
iFlags |= spEnabled;
|
||||
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
|
||||
}
|
||||
else {
|
||||
// located behind the tracking consist, don't bother with it
|
||||
return false;
|
||||
}
|
||||
// zależnie od trybu sprawdzenie czy jest tutaj gdzieś semafor lub tarcza manewrowa
|
||||
// jeśli wskazuje stop wtedy wystawiamy true jako koniec sprawdzania
|
||||
// WriteLog("EventSet: Vel=" + AnsiString(fVelNext) + " iFlags=" + AnsiString(iFlags) + " order="+AnsiString(order));
|
||||
@@ -580,6 +587,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
||||
if( newspeedpoint.Set(
|
||||
pEvent,
|
||||
GetDistanceToEvent( pTrack, pEvent, fLastDir, fCurrentDistance ),
|
||||
fLength,
|
||||
OrderCurrentGet() ) ) {
|
||||
|
||||
fDistance = newspeedpoint.fDist; // jeśli sygnał stop, to nie ma potrzeby dalej skanować
|
||||
@@ -1909,72 +1917,83 @@ void TController::AutoRewident()
|
||||
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
|
||||
while (d) {
|
||||
for( int i = 0; i < BrakeAccTableSize; ++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)
|
||||
{
|
||||
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 ) {
|
||||
if( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) {
|
||||
// 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 ] );
|
||||
if( OrderCurrentGet() & Shunt ) {
|
||||
// for uniform behaviour and compatibility with older scenarios set default acceleration table values for shunting
|
||||
fAccThreshold = (
|
||||
mvOccupied->TrainType == dt_EZT ? -0.55 :
|
||||
mvOccupied->TrainType == dt_DMU ? -0.45 :
|
||||
-0.2 );
|
||||
// HACK: emu with induction motors need to start their braking a bit sooner than the ones with series motors
|
||||
if( ( mvOccupied->TrainType == dt_EZT )
|
||||
&& ( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) ) {
|
||||
fAccThreshold += 0.10;
|
||||
}
|
||||
else {
|
||||
fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
|
||||
}
|
||||
fBrakeReaction = 0.25;
|
||||
}
|
||||
else if( mvOccupied->TrainType == dt_DMU ) {
|
||||
fNominalAccThreshold = std::max( -0.45, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
|
||||
fBrakeReaction = 0.25;
|
||||
}
|
||||
else if (ustaw > 16) {
|
||||
fNominalAccThreshold = -fBrake_a0[ BrakeAccTableSize ] - 4 * fBrake_a1[ BrakeAccTableSize ];
|
||||
fBrakeReaction = 1.00 + fLength*0.004;
|
||||
}
|
||||
else {
|
||||
fNominalAccThreshold = -fBrake_a0[ BrakeAccTableSize ] - 1 * fBrake_a1[ BrakeAccTableSize ];
|
||||
fBrakeReaction = 1.00 + fLength*0.005;
|
||||
}
|
||||
fAccThreshold = fNominalAccThreshold;
|
||||
/*
|
||||
if( IsHeavyCargoTrain ) {
|
||||
// HACK: heavy cargo trains don't activate brakes early enough
|
||||
fAccThreshold = std::max( -0.2, fAccThreshold );
|
||||
|
||||
if( OrderCurrentGet() & Obey_train ) {
|
||||
// 4. Przeliczanie siły hamowania
|
||||
double const velstep = ( mvOccupied->Vmax*0.5 ) / BrakeAccTableSize;
|
||||
d = pVehicles[0]; // pojazd na czele składu
|
||||
while (d) {
|
||||
for( int i = 0; i < BrakeAccTableSize; ++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)
|
||||
{
|
||||
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 ) {
|
||||
if( mvControlling->EngineType == TEngineType::ElectricInductionMotor ) {
|
||||
// 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 ] );
|
||||
}
|
||||
else {
|
||||
fNominalAccThreshold = std::max( -0.75, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
|
||||
}
|
||||
fBrakeReaction = 0.25;
|
||||
}
|
||||
else if( mvOccupied->TrainType == dt_DMU ) {
|
||||
fNominalAccThreshold = std::max( -0.45, -fBrake_a0[ BrakeAccTableSize ] - 8 * fBrake_a1[ BrakeAccTableSize ] );
|
||||
fBrakeReaction = 0.25;
|
||||
}
|
||||
else if (ustaw > 16) {
|
||||
fNominalAccThreshold = -fBrake_a0[ BrakeAccTableSize ] - 4 * fBrake_a1[ BrakeAccTableSize ];
|
||||
fBrakeReaction = 1.00 + fLength*0.004;
|
||||
}
|
||||
else {
|
||||
fNominalAccThreshold = -fBrake_a0[ BrakeAccTableSize ] - 1 * fBrake_a1[ BrakeAccTableSize ];
|
||||
fBrakeReaction = 1.00 + fLength*0.005;
|
||||
}
|
||||
fAccThreshold = fNominalAccThreshold;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
double TController::ESMVelocity(bool Main)
|
||||
@@ -2852,7 +2871,11 @@ bool TController::IncSpeed()
|
||||
auto const sufficienttractionforce { std::abs( mvControlling->Ft ) > ( IsHeavyCargoTrain ? 125 : 100 ) * 1000.0 };
|
||||
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 { mvControlling->EnginePowerSource.CollectorParameters.MaxV * ( IsHeavyCargoTrain ? 0.70 : 0.80 ) };
|
||||
auto const useseriesmodevoltage {
|
||||
interpolate(
|
||||
mvControlling->EnginePowerSource.CollectorParameters.MinV,
|
||||
mvControlling->EnginePowerSource.CollectorParameters.MaxV,
|
||||
( IsHeavyCargoTrain ? 0.35 : 0.40 ) ) };
|
||||
auto const useseriesmode = (
|
||||
( mvControlling->Imax > mvControlling->ImaxLo )
|
||||
|| ( fVoltage < useseriesmodevoltage )
|
||||
@@ -2883,10 +2906,12 @@ bool TController::IncSpeed()
|
||||
if( usefieldshunting ) {
|
||||
// to dać bocznik
|
||||
// engage the shuntfield only if there's sufficient power margin to draw from
|
||||
auto const sufficientpowermargin { fVoltage - useseriesmodevoltage > ( IsHeavyCargoTrain ? 100.0 : 75.0 ) };
|
||||
|
||||
OK = (
|
||||
fVoltage > useseriesmodevoltage + 0.0125 * mvControlling->EnginePowerSource.CollectorParameters.MaxV ?
|
||||
sufficientpowermargin ?
|
||||
mvControlling->IncScndCtrl( 1 ) :
|
||||
false );
|
||||
true );
|
||||
}
|
||||
else {
|
||||
// jeśli ustawiony bocznik to bocznik na zero po chamsku
|
||||
@@ -2894,10 +2919,19 @@ bool TController::IncSpeed()
|
||||
mvControlling->DecScndCtrl( 2 );
|
||||
}
|
||||
// kręcimy nastawnik jazdy
|
||||
// don't draw too much power;
|
||||
// keep from dropping into series mode when entering/using parallel mode, and from shutting down in the series mode
|
||||
auto const sufficientpowermargin {
|
||||
fVoltage - (
|
||||
mvControlling->RList[ std::min( mvControlling->MainCtrlPos + 1, mvControlling->MainCtrlPosNo ) ].Bn == 1 ?
|
||||
mvControlling->EnginePowerSource.CollectorParameters.MinV :
|
||||
useseriesmodevoltage )
|
||||
> ( IsHeavyCargoTrain ? 80.0 : 60.0 ) };
|
||||
|
||||
OK = (
|
||||
mvControlling->DelayCtrlFlag ?
|
||||
true :
|
||||
mvControlling->IncMainCtrl( 1 ) );
|
||||
( sufficientpowermargin && ( false == mvControlling->DelayCtrlFlag ) ) ?
|
||||
mvControlling->IncMainCtrl( 1 ) :
|
||||
true );
|
||||
// czekaj na 1 pozycji, zanim się nie włączą liniowe
|
||||
if( true == mvControlling->StLinFlag ) {
|
||||
iDrivigFlags |= moveIncSpeed;
|
||||
@@ -3903,12 +3937,13 @@ TController::UpdateSituation(double dt) {
|
||||
p = p->Next(); // pojazd podłączony z tyłu (patrząc od czoła)
|
||||
}
|
||||
|
||||
// crude way to deal with automatic door opening on W4 preventing further ride
|
||||
// HACK: crude way to deal with automatic door opening on W4 preventing further ride
|
||||
// for human-controlled vehicles with no door control and dynamic brake auto-activating with door open
|
||||
// TODO: check if this situation still happens and the hack is still needed
|
||||
if( ( false == AIControllFlag )
|
||||
&& ( iDrivigFlags & moveDoorOpened )
|
||||
&& ( mvOccupied->DoorCloseCtrl != control_t::driver )
|
||||
&& ( mvControlling->MainCtrlPos > 0 ) ) {
|
||||
&& ( mvControlling->MainCtrlPos > ( mvControlling->EngineType != TEngineType::DieselEngine ? 0 : 1 ) ) ) { // for diesel 1st position is effectively 0
|
||||
Doors( false );
|
||||
}
|
||||
|
||||
@@ -4006,7 +4041,15 @@ TController::UpdateSituation(double dt) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if( fVoltage < 0.75 * mvControlling->EnginePowerSource.CollectorParameters.MaxV ) {
|
||||
|
||||
// TODO: refactor this calculation into a subroutine
|
||||
auto const useseriesmodevoltage {
|
||||
interpolate(
|
||||
mvControlling->EnginePowerSource.CollectorParameters.MinV,
|
||||
mvControlling->EnginePowerSource.CollectorParameters.MaxV,
|
||||
( IsHeavyCargoTrain ? 0.35 : 0.40 ) ) };
|
||||
|
||||
if( fVoltage <= useseriesmodevoltage ) {
|
||||
// if the power station is heavily burdened try to reduce the load
|
||||
switch( mvControlling->EngineType ) {
|
||||
|
||||
@@ -5856,12 +5899,20 @@ basic_event * TController::CheckTrackEventBackward(double fDirection, TTrack *Tr
|
||||
{ // sprawdzanie eventu w torze, czy jest sygnałowym - skanowanie do tyłu
|
||||
// NOTE: this method returns only one event which meets the conditions, due to limitations in the caller
|
||||
// TBD, TODO: clean up the caller and return all suitable events, as in theory things will go awry if the track has more than one signal
|
||||
auto const dir{ pVehicles[ 0 ]->VectorFront() * pVehicles[ 0 ]->DirectionGet() };
|
||||
auto const pos{ pVehicles[ 0 ]->HeadPosition() };
|
||||
auto const &eventsequence { ( fDirection > 0 ? Track->m_events2 : Track->m_events1 ) };
|
||||
for( auto const &event : eventsequence ) {
|
||||
if( ( event.second != nullptr )
|
||||
&& ( event.second->m_passive )
|
||||
&& ( typeid(*(event.second)) == typeid( getvalues_event ) ) ) {
|
||||
return event.second;
|
||||
// since we're checking for events behind us discard the sources in front of the scanning vehicle
|
||||
auto const sl{ event.second->input_location() }; // położenie komórki pamięci
|
||||
auto const sem{ sl - pos }; // wektor do komórki pamięci od końca składu
|
||||
if( dir.x * sem.x + dir.z * sem.z < 0 ) {
|
||||
// iloczyn skalarny jest ujemny, gdy sygnał stoi z tyłu
|
||||
return event.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
4
Driver.h
4
Driver.h
@@ -141,7 +141,7 @@ class TSpeedPos
|
||||
|
||||
public:
|
||||
TSpeedPos(TTrack *track, double dist, int flag);
|
||||
TSpeedPos(basic_event *event, double dist, TOrders order);
|
||||
TSpeedPos(basic_event *event, double dist, double length, TOrders order);
|
||||
TSpeedPos() = default;
|
||||
void Clear();
|
||||
bool Update();
|
||||
@@ -150,7 +150,7 @@ class TSpeedPos
|
||||
void
|
||||
UpdateDistance( double dist ) {
|
||||
fDist -= dist; }
|
||||
bool Set(basic_event *e, double d, TOrders order = Wait_for_orders);
|
||||
bool Set(basic_event *e, double d, double length, TOrders order = Wait_for_orders);
|
||||
void Set(TTrack *t, double d, int f);
|
||||
std::string TableText() const;
|
||||
std::string GetName() const;
|
||||
|
||||
@@ -2780,7 +2780,7 @@ TDynamicObject::update_load_visibility() {
|
||||
}
|
||||
*/
|
||||
auto loadpercentage { (
|
||||
MoverParameters->MaxLoad == 0.0 ?
|
||||
MoverParameters->MaxLoad == 0.f ?
|
||||
0.0 :
|
||||
100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
|
||||
auto const sectionloadpercentage { (
|
||||
@@ -2814,7 +2814,7 @@ TDynamicObject::update_load_offset() {
|
||||
if( MoverParameters->LoadType.offset_min == 0.f ) { return; }
|
||||
|
||||
auto const loadpercentage { (
|
||||
MoverParameters->MaxLoad == 0.0 ?
|
||||
MoverParameters->MaxLoad == 0.f ?
|
||||
0.0 :
|
||||
100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ basic_event::event_conditions::test() const {
|
||||
match_value_2,
|
||||
flags );
|
||||
|
||||
std::string comparisonlog = "Test: MemCompare - ";
|
||||
std::string comparisonlog = "Test: MemCompare - " + cell->name() + " - ";
|
||||
|
||||
comparisonlog +=
|
||||
"[" + cell->Text() + "]"
|
||||
|
||||
@@ -374,6 +374,14 @@ global_settings::ConfigParse(cParser &Parser) {
|
||||
Parser.getTokens();
|
||||
Parser >> ResourceMove;
|
||||
}
|
||||
else if( token == "gfx.reflections.framerate" ) {
|
||||
|
||||
auto const updatespersecond { std::abs( Parser.getToken<double>() ) };
|
||||
ReflectionUpdatesPerSecond = (
|
||||
updatespersecond > 0 ?
|
||||
1000 / std::min( 30.0, updatespersecond ) :
|
||||
0 );
|
||||
}
|
||||
else if (token == "timespeed")
|
||||
{
|
||||
// przyspieszenie czasu, zmienna do testów
|
||||
|
||||
@@ -115,6 +115,7 @@ struct global_settings {
|
||||
float depth{ 250.f };
|
||||
float distance{ 500.f }; // no longer used
|
||||
} shadowtune;
|
||||
int ReflectionUpdatesPerSecond{ static_cast<int>( 1000 / ( 1.0 / 300.0 ) ) };
|
||||
float AnisotropicFiltering{ 8.f }; // requested level of anisotropic filtering. TODO: move it to renderer object
|
||||
float FieldOfView{ 45.f }; // vertical field of view for the camera. TODO: move it to the renderer
|
||||
GLint iMaxTextureSize{ 4096 }; // maksymalny rozmiar tekstury
|
||||
|
||||
@@ -1003,13 +1003,6 @@ public:
|
||||
TRotation Rot { 0.0, 0.0, 0.0 };
|
||||
std::string Name; /*nazwa wlasna*/
|
||||
TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami
|
||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
||||
double HVCouplers[ 2 ][ 2 ]; //przewod WN
|
||||
enum hvcoupler {
|
||||
current = 0,
|
||||
voltage
|
||||
};
|
||||
#endif
|
||||
bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/
|
||||
int SoundFlag = 0; /*!o patrz stale sound_ */
|
||||
double DistCounter = 0.0; /*! licznik kilometrow */
|
||||
|
||||
@@ -316,12 +316,6 @@ ActiveCab( Cab )
|
||||
Couplers[b].DmaxC = 0.1;
|
||||
Couplers[b].FmaxC = 1000.0;
|
||||
}
|
||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
||||
for( int side = 0; side < 2; ++side ) {
|
||||
HVCouplers[ side ][ hvcoupler::current ] = 0.0;
|
||||
HVCouplers[ side ][ hvcoupler::voltage ] = 0.0;
|
||||
}
|
||||
#endif
|
||||
for( int b = 0; b < 3; ++b ) {
|
||||
BrakeCylMult[ b ] = 0.0;
|
||||
}
|
||||
@@ -816,13 +810,23 @@ void TMoverParameters::UpdateBatteryVoltage(double dt)
|
||||
&& ( EngineType != TEngineType::WheelsDriven )
|
||||
&& ( NominalBatteryVoltage > 0 ) ) {
|
||||
|
||||
// HACK: allow to draw power also from adjacent converter, applicable for EMUs
|
||||
// TODO: expand power cables system to include low voltage power transfers
|
||||
// HACK: emulate low voltage generator powered directly by the diesel engine
|
||||
auto const converteractive{ (
|
||||
( ConverterFlag )
|
||||
|| ( ( ( Couplers[ side::front ].CouplingFlag & coupling::permanent ) != 0 ) && Couplers[ side::front ].Connected->ConverterFlag )
|
||||
|| ( ( ( Couplers[ side::rear ].CouplingFlag & coupling::permanent ) != 0 ) && Couplers[ side::rear ].Connected->ConverterFlag ) )
|
||||
|| ( ( EngineType == TEngineType::DieselElectric ) && ( true == Mains ) )
|
||||
|| ( ( EngineType == TEngineType::DieselEngine ) && ( true == Mains ) ) };
|
||||
|
||||
if ((NominalBatteryVoltage / BatteryVoltage < 1.22) && Battery)
|
||||
{ // 110V
|
||||
if (!ConverterFlag)
|
||||
if (!converteractive)
|
||||
sn1 = (dt * 2.0); // szybki spadek do ok 90V
|
||||
else
|
||||
sn1 = 0;
|
||||
if (ConverterFlag)
|
||||
if (converteractive)
|
||||
sn2 = -(dt * 2.0); // szybki wzrost do 110V
|
||||
else
|
||||
sn2 = 0;
|
||||
@@ -846,7 +850,7 @@ void TMoverParameters::UpdateBatteryVoltage(double dt)
|
||||
sn1 = (dt * 0.0046);
|
||||
else
|
||||
sn1 = 0;
|
||||
if (ConverterFlag)
|
||||
if (converteractive)
|
||||
sn2 = -(dt * 50); // szybki wzrost do 110V
|
||||
else
|
||||
sn2 = 0;
|
||||
@@ -1120,33 +1124,18 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
||||
|| ( ( Heating )
|
||||
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
|
||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
||||
HVCouplers[ oppositeside ][ hvcoupler::voltage ] =
|
||||
std::max(
|
||||
std::abs( hvc ),
|
||||
Couplers[ side ].Connected->HVCouplers[ Couplers[ side ].ConnectedNr ][ hvcoupler::voltage ] - HVCouplers[ side ][ hvcoupler::current ] * 0.02 );
|
||||
#else
|
||||
auto const &connectedcoupler = Couplers[ side ].Connected->Couplers[ Couplers[ side ].ConnectedNr ];
|
||||
Couplers[ oppositeside ].power_high.voltage =
|
||||
std::max(
|
||||
std::abs( hvc ),
|
||||
connectedcoupler.power_high.voltage - Couplers[ side ].power_high.current * 0.02 );
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
||||
HVCouplers[ oppositeside ][ hvcoupler::voltage ] = std::abs( hvc ) - HVCouplers[ side ][ hvcoupler::current ] * 0.02;
|
||||
#else
|
||||
Couplers[ oppositeside ].power_high.voltage = std::abs( hvc ) - Couplers[ side ].power_high.current * 0.02;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
||||
hvc = HVCouplers[ side::front ][ hvcoupler::voltage ] + HVCouplers[ side::rear ][ hvcoupler::voltage ];
|
||||
#else
|
||||
hvc = Couplers[ side::front ].power_high.voltage + Couplers[ side::rear ].power_high.voltage;
|
||||
#endif
|
||||
|
||||
if( std::abs( PantFrontVolt ) + std::abs( PantRearVolt ) < 1.0 ) {
|
||||
// bez napiecia...
|
||||
@@ -1160,29 +1149,17 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
||||
|| ( ( Heating )
|
||||
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
|
||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
||||
auto const oppositeside = ( Couplers[side].ConnectedNr == side::front ? side::rear : side::front );
|
||||
HVCouplers[ side ][ hvcoupler::current ] =
|
||||
Couplers[side].Connected->HVCouplers[oppositeside][hvcoupler::current] +
|
||||
Itot * HVCouplers[side][hvcoupler::voltage] / hvc; // obciążenie rozkladane stosownie do napiec
|
||||
#else
|
||||
auto const &connectedsothercoupler =
|
||||
auto const &connectedcoupler =
|
||||
Couplers[ side ].Connected->Couplers[
|
||||
( Couplers[ side ].ConnectedNr == side::front ?
|
||||
side::rear :
|
||||
side::front ) ];
|
||||
Couplers[ side ].power_high.current =
|
||||
connectedsothercoupler.power_high.current
|
||||
connectedcoupler.power_high.current
|
||||
+ Itot * Couplers[ side ].power_high.voltage / hvc; // obciążenie rozkladane stosownie do napiec
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
||||
// pierwszy pojazd
|
||||
HVCouplers[side][hvcoupler::current] = Itot * HVCouplers[side][hvcoupler::voltage] / hvc;
|
||||
#else
|
||||
Couplers[ side ].power_high.current = Itot * Couplers[ side ].power_high.voltage / hvc;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1196,19 +1173,13 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
|
||||
if( ( Couplers[ side ].CouplingFlag & ctrain_power )
|
||||
|| ( ( Heating )
|
||||
&& ( Couplers[ side ].CouplingFlag & ctrain_heating ) ) ) {
|
||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
||||
auto const oppositeside = ( Couplers[ side ].ConnectedNr == side::front ? side::rear : side::front );
|
||||
TotalCurrent += Couplers[ side ].Connected->HVCouplers[ oppositeside ][ hvcoupler::current ];
|
||||
HVCouplers[ side ][ hvcoupler::current ] = 0.0;
|
||||
#else
|
||||
auto const &connectedsothercoupler =
|
||||
auto const &connectedcoupler =
|
||||
Couplers[ side ].Connected->Couplers[
|
||||
( Couplers[ side ].ConnectedNr == side::front ?
|
||||
side::rear :
|
||||
side::front ) ];
|
||||
TotalCurrent += connectedsothercoupler.power_high.current;
|
||||
TotalCurrent += connectedcoupler.power_high.current;
|
||||
Couplers[ side ].power_high.current = 0.0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1561,18 +1532,18 @@ void TMoverParameters::WaterPumpCheck( double const Timestep ) {
|
||||
// water heater status check
|
||||
void TMoverParameters::WaterHeaterCheck( double const Timestep ) {
|
||||
|
||||
WaterHeater.is_damaged = (
|
||||
( true == WaterHeater.is_damaged )
|
||||
|| ( ( true == WaterHeater.is_active )
|
||||
&& ( false == WaterPump.is_active ) ) );
|
||||
|
||||
WaterHeater.is_active = (
|
||||
( false == WaterHeater.is_damaged )
|
||||
&& ( true == Battery )
|
||||
&& ( true == WaterHeater.is_enabled )
|
||||
&& ( true == WaterHeater.breaker )
|
||||
&& ( ( WaterHeater.is_active ) || ( WaterHeater.config.temp_min < 0 ) || ( dizel_heat.temperatura1 < WaterHeater.config.temp_min ) ) );
|
||||
|
||||
|
||||
WaterHeater.is_damaged = (
|
||||
( true == WaterHeater.is_damaged )
|
||||
|| ( ( true == WaterHeater.is_active )
|
||||
&& ( false == WaterPump.is_active ) ) );
|
||||
|
||||
if( ( WaterHeater.config.temp_max > 0 )
|
||||
&& ( dizel_heat.temperatura1 > WaterHeater.config.temp_max ) ) {
|
||||
WaterHeater.is_active = false;
|
||||
@@ -4017,11 +3988,9 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer)
|
||||
Voltage =
|
||||
std::max(
|
||||
RunningTraction.TractionVoltage,
|
||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
||||
std::max( HVCouplers[side::front][hvcoupler::voltage], HVCouplers[side::rear][hvcoupler::voltage] ) );
|
||||
#else
|
||||
std::max( Couplers[ side::front ].power_high.voltage, Couplers[ side::rear ].power_high.voltage ) );
|
||||
#endif
|
||||
std::max(
|
||||
Couplers[ side::front ].power_high.voltage,
|
||||
Couplers[ side::rear ].power_high.voltage ) );
|
||||
}
|
||||
else {
|
||||
Voltage = 0;
|
||||
@@ -6708,7 +6677,7 @@ TMoverParameters::AssignLoad( std::string const &Name, float const Amount ) {
|
||||
for( auto const &loadattributes : LoadAttributes ) {
|
||||
if( Name == loadattributes.name ) {
|
||||
LoadType = loadattributes;
|
||||
LoadAmount = Amount;
|
||||
LoadAmount = clamp( Amount, 0.f, MaxLoad ) ;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -6746,7 +6715,7 @@ bool TMoverParameters::LoadingDone(double const LSpeed, std::string const &Loadn
|
||||
if( ( LoadAmount <= 0 ) || ( CommandIn.Value1 <= 0 ) ) {
|
||||
// pusto lub rozładowano żądaną ilość
|
||||
LoadStatus = 4; // skończony rozładunek
|
||||
LoadAmount = std::max( 0.f, LoadAmount ); //ładunek nie może być ujemny
|
||||
LoadAmount = clamp( LoadAmount, 0.f, MaxLoad); //ładunek nie może być ujemny
|
||||
}
|
||||
if( LoadAmount == 0.f ) {
|
||||
AssignLoad(""); // jak nic nie ma, to nie ma też nazwy
|
||||
@@ -7033,16 +7002,6 @@ std::string TMoverParameters::EngineDescription(int what) const
|
||||
// *************************************************************************************************
|
||||
double TMoverParameters::GetTrainsetVoltage(void)
|
||||
{//ABu: funkcja zwracajaca napiecie dla calego skladu, przydatna dla EZT
|
||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
||||
return std::max(
|
||||
HVCouplers[ side::front ][ hvcoupler::voltage ],
|
||||
HVCouplers[ side::rear ][ hvcoupler::voltage ] );
|
||||
#else
|
||||
/*
|
||||
return std::max(
|
||||
Couplers[ side::front ].power_high.voltage,
|
||||
Couplers[ side::rear ].power_high.voltage );
|
||||
*/
|
||||
return std::max(
|
||||
( ( ( Couplers[side::front].Connected )
|
||||
&& ( ( Couplers[ side::front ].CouplingFlag & ctrain_power )
|
||||
@@ -7056,7 +7015,6 @@ double TMoverParameters::GetTrainsetVoltage(void)
|
||||
&& ( Couplers[ side::rear ].CouplingFlag & ctrain_heating ) ) ) ) ?
|
||||
Couplers[ side::rear ].Connected->Couplers[ Couplers[ side::rear ].ConnectedNr ].power_high.voltage :
|
||||
0.0 ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
|
||||
69
Train.cpp
69
Train.cpp
@@ -452,9 +452,9 @@ PyObject *TTrain::GetTrainState() {
|
||||
// basic systems state data
|
||||
PyDict_SetItemString( dict, "battery", PyGetBool( mvControlled->Battery ) );
|
||||
PyDict_SetItemString( dict, "linebreaker", PyGetBool( mvControlled->Mains ) );
|
||||
PyDict_SetItemString( dict, "converter", PyGetBool( mover->ConverterFlag ) );
|
||||
PyDict_SetItemString( dict, "converter_overload", PyGetBool( mover->ConvOvldFlag ) );
|
||||
PyDict_SetItemString( dict, "compress", PyGetBool( mover->CompressorFlag ) );
|
||||
PyDict_SetItemString( dict, "converter", PyGetBool( mvControlled->ConverterFlag ) );
|
||||
PyDict_SetItemString( dict, "converter_overload", PyGetBool( mvControlled->ConvOvldFlag ) );
|
||||
PyDict_SetItemString( dict, "compress", PyGetBool( mvControlled->CompressorFlag ) );
|
||||
// reverser
|
||||
PyDict_SetItemString( dict, "direction", PyGetInt( mover->ActiveDir ) );
|
||||
// throttle
|
||||
@@ -467,34 +467,35 @@ PyObject *TTrain::GetTrainState() {
|
||||
bool const bEP = ( mvControlled->LocHandle->GetCP() > 0.2 ) || ( fEIMParams[ 0 ][ 2 ] > 0.01 );
|
||||
PyDict_SetItemString( dict, "dir_brake", PyGetBool( bEP ) );
|
||||
bool bPN;
|
||||
if( ( typeid( *mvControlled->Hamulec ) == typeid( TLSt ) )
|
||||
|| ( typeid( *mvControlled->Hamulec ) == typeid( TEStED ) ) ) {
|
||||
if( ( typeid( *mvOccupied->Hamulec ) == typeid( TLSt ) )
|
||||
|| ( typeid( *mvOccupied->Hamulec ) == typeid( TEStED ) ) ) {
|
||||
|
||||
TBrake* temp_ham = mvControlled->Hamulec.get();
|
||||
TBrake* temp_ham = mvOccupied->Hamulec.get();
|
||||
bPN = ( static_cast<TLSt*>( temp_ham )->GetEDBCP() > 0.2 );
|
||||
}
|
||||
else
|
||||
bPN = false;
|
||||
PyDict_SetItemString( dict, "indir_brake", PyGetBool( bPN ) );
|
||||
PyDict_SetItemString( dict, "brake_delay_flag", PyGetInt( mvControlled->BrakeDelayFlag ));
|
||||
PyDict_SetItemString( dict, "brake_op_mode_flag", PyGetInt( mvControlled->BrakeOpModeFlag ));
|
||||
PyDict_SetItemString( dict, "brake_delay_flag", PyGetInt( mvOccupied->BrakeDelayFlag ));
|
||||
PyDict_SetItemString( dict, "brake_op_mode_flag", PyGetInt( mvOccupied->BrakeOpModeFlag ));
|
||||
// other controls
|
||||
PyDict_SetItemString( dict, "ca", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_aware ) ) );
|
||||
PyDict_SetItemString( dict, "shp", PyGetBool( TestFlag( mvOccupied->SecuritySystem.Status, s_active ) ) );
|
||||
PyDict_SetItemString( dict, "pantpress", PyGetFloat( mvControlled->PantPress ) );
|
||||
PyDict_SetItemString( dict, "universal3", PyGetBool( InstrumentLightActive ) );
|
||||
PyDict_SetItemString( dict, "radio_channel", PyGetInt( iRadioChannel ) );
|
||||
PyDict_SetItemString( dict, "door_lock", PyGetInt( mvOccupied->DoorLockEnabled ) );
|
||||
// movement data
|
||||
PyDict_SetItemString( dict, "velocity", PyGetFloat( mover->Vel ) );
|
||||
PyDict_SetItemString( dict, "tractionforce", PyGetFloat( mover->Ft ) );
|
||||
PyDict_SetItemString( dict, "slipping_wheels", PyGetBool( mover->SlippingWheels ) );
|
||||
PyDict_SetItemString( dict, "sanding", PyGetBool( mover->SandDose ) );
|
||||
// electric current data
|
||||
PyDict_SetItemString( dict, "traction_voltage", PyGetFloat( mover->RunningTraction.TractionVoltage ) );
|
||||
PyDict_SetItemString( dict, "voltage", PyGetFloat( mover->Voltage ) );
|
||||
PyDict_SetItemString( dict, "im", PyGetFloat( mover->Im ) );
|
||||
PyDict_SetItemString( dict, "fuse", PyGetBool( mover->FuseFlag ) );
|
||||
PyDict_SetItemString( dict, "epfuse", PyGetBool( mover->EpFuse ) );
|
||||
PyDict_SetItemString( dict, "traction_voltage", PyGetFloat( mvControlled->RunningTraction.TractionVoltage ) );
|
||||
PyDict_SetItemString( dict, "voltage", PyGetFloat( mvControlled->Voltage ) );
|
||||
PyDict_SetItemString( dict, "im", PyGetFloat( mvControlled->Im ) );
|
||||
PyDict_SetItemString( dict, "fuse", PyGetBool( mvControlled->FuseFlag ) );
|
||||
PyDict_SetItemString( dict, "epfuse", PyGetBool( mvOccupied->EpFuse ) );
|
||||
// induction motor state data
|
||||
char const *TXTT[ 10 ] = { "fd", "fdt", "fdb", "pd", "pdt", "pdb", "itothv", "1", "2", "3" };
|
||||
char const *TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" };
|
||||
@@ -554,7 +555,7 @@ PyObject *TTrain::GetTrainState() {
|
||||
PyDict_SetItemString( dict, "train_enginetype", PyGetString( timetable->LocSeries.c_str() ) );
|
||||
PyDict_SetItemString( dict, "train_engineload", PyGetFloat( timetable->LocLoad ) );
|
||||
|
||||
PyDict_SetItemString( dict, "train_stationindex", PyGetInt( driver->StationIndex() ) );
|
||||
PyDict_SetItemString( dict, "train_stationindex", PyGetInt( driver->iStationStart ) );
|
||||
auto const stationcount { driver->StationCount() };
|
||||
PyDict_SetItemString( dict, "train_stationcount", PyGetInt( stationcount ) );
|
||||
if( stationcount > 0 ) {
|
||||
@@ -579,6 +580,7 @@ PyObject *TTrain::GetTrainState() {
|
||||
PyDict_SetItemString( dict, "minutes", PyGetInt( simulation::Time.data().wMinute ) );
|
||||
PyDict_SetItemString( dict, "seconds", PyGetInt( simulation::Time.second() ) );
|
||||
PyDict_SetItemString( dict, "air_temperature", PyGetInt( Global.AirTemperature ) );
|
||||
PyDict_SetItemString( dict, "light_level", PyGetFloat( Global.fLuminance - std::max( 0.f, Global.Overcast - 1.f ) ) );
|
||||
|
||||
Application.release_python_lock();
|
||||
return dict;
|
||||
@@ -4084,14 +4086,14 @@ void TTrain::OnCommand_generictoggle( TTrain *Train, command_data const &Command
|
||||
|
||||
auto const itemindex = static_cast<int>( Command.command ) - static_cast<int>( user_command::generictoggle0 );
|
||||
auto &item = Train->ggUniversals[ itemindex ];
|
||||
|
||||
/*
|
||||
if( item.SubModel == nullptr ) {
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
WriteLog( "Train generic item " + std::to_string( itemindex ) + " is missing, or wasn't defined" );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
*/
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( item.GetDesiredValue() < 0.5 ) {
|
||||
@@ -4995,8 +4997,10 @@ bool TTrain::Update( double const Deltatime )
|
||||
iUnits[i] = iUnitNo;
|
||||
cCode[i] = p->MoverParameters->TypeName[p->MoverParameters->TypeName.length() - 1];
|
||||
asCarName[i] = p->name();
|
||||
bPants[iUnitNo - 1][0] = (bPants[iUnitNo - 1][0] || p->MoverParameters->PantFrontUp);
|
||||
bPants[iUnitNo - 1][1] = (bPants[iUnitNo - 1][1] || p->MoverParameters->PantRearUp);
|
||||
if( p->MoverParameters->EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) {
|
||||
bPants[iUnitNo - 1][side::front] = ( bPants[iUnitNo - 1][side::front] || p->MoverParameters->PantFrontUp );
|
||||
bPants[iUnitNo - 1][side::rear] = ( bPants[iUnitNo - 1][side::rear] || p->MoverParameters->PantRearUp );
|
||||
}
|
||||
bComp[iUnitNo - 1][0] = (bComp[iUnitNo - 1][0] || p->MoverParameters->CompressorAllow || (p->MoverParameters->CompressorStart == start_t::automatic));
|
||||
bSlip[i] = p->MoverParameters->SlippingWheels;
|
||||
if (p->MoverParameters->CompressorSpeed > 0.00001)
|
||||
@@ -5459,6 +5463,10 @@ bool TTrain::Update( double const Deltatime )
|
||||
// others
|
||||
btLampkaMalfunction.Turn( mvControlled->dizel_heat.PA );
|
||||
btLampkaMotorBlowers.Turn( ( mvControlled->MotorBlowers[ side::front ].is_active ) && ( mvControlled->MotorBlowers[ side::rear ].is_active ) );
|
||||
// universal devices state indicators
|
||||
for( auto idx = 0; idx < btUniversals.size(); ++idx ) {
|
||||
btUniversals[ idx ].Turn( ggUniversals[ idx ].GetValue() > 0.5 );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// wylaczone
|
||||
@@ -5514,6 +5522,10 @@ bool TTrain::Update( double const Deltatime )
|
||||
// others
|
||||
btLampkaMalfunction.Turn( false );
|
||||
btLampkaMotorBlowers.Turn( false );
|
||||
// universal devices state indicators
|
||||
for( auto &universal : btUniversals ) {
|
||||
universal.Turn( false );
|
||||
}
|
||||
}
|
||||
|
||||
{ // yB - wskazniki drugiego czlonu
|
||||
@@ -6173,7 +6185,9 @@ void TTrain::update_sounds_runningnoise( sound_source &Sound ) {
|
||||
// volume calculation
|
||||
auto volume =
|
||||
Sound.m_amplitudeoffset
|
||||
+ Sound.m_amplitudefactor * mvOccupied->Vel;
|
||||
+ Sound.m_amplitudefactor * interpolate(
|
||||
mvOccupied->Vel / ( 1 + mvOccupied->Vmax ), 1.0,
|
||||
0.5 ); // scale base volume between 0.5-1.0
|
||||
if( std::abs( mvOccupied->nrot ) > 0.01 ) {
|
||||
// hamulce wzmagaja halas
|
||||
auto const brakeforceratio { (
|
||||
@@ -6197,7 +6211,7 @@ void TTrain::update_sounds_runningnoise( sound_source &Sound ) {
|
||||
interpolate(
|
||||
0.0, 1.0,
|
||||
clamp(
|
||||
mvOccupied->Vel / 40.0,
|
||||
mvOccupied->Vel / 25.0,
|
||||
0.0, 1.0 ) );
|
||||
}
|
||||
|
||||
@@ -7072,6 +7086,9 @@ void TTrain::clear_cab_controls()
|
||||
btLampkaHamulecReczny.Clear();
|
||||
btLampkaBlokadaDrzwi.Clear();
|
||||
btLampkaDoorLockOff.Clear();
|
||||
for( auto &universal : btUniversals ) {
|
||||
universal.Clear();
|
||||
}
|
||||
btInstrumentLight.Clear();
|
||||
btDashboardLight.Clear();
|
||||
btTimetableLight.Clear();
|
||||
@@ -7504,7 +7521,17 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
||||
{ "i-rearrightend:", btLampkaRearRightEndLight },
|
||||
{ "i-dashboardlight:", btDashboardLight },
|
||||
{ "i-timetablelight:", btTimetableLight },
|
||||
{ "i-cablight:", btCabLight }
|
||||
{ "i-cablight:", btCabLight },
|
||||
{ "i-universal0:", btUniversals[ 0 ] },
|
||||
{ "i-universal1:", btUniversals[ 1 ] },
|
||||
{ "i-universal2:", btUniversals[ 2 ] },
|
||||
{ "i-universal3:", btUniversals[ 3 ] },
|
||||
{ "i-universal4:", btUniversals[ 4 ] },
|
||||
{ "i-universal5:", btUniversals[ 5 ] },
|
||||
{ "i-universal6:", btUniversals[ 6 ] },
|
||||
{ "i-universal7:", btUniversals[ 7 ] },
|
||||
{ "i-universal8:", btUniversals[ 8 ] },
|
||||
{ "i-universal9:", btUniversals[ 9 ] }
|
||||
};
|
||||
auto lookup = lights.find( Label );
|
||||
if( lookup != lights.end() ) {
|
||||
|
||||
1
Train.h
1
Train.h
@@ -507,6 +507,7 @@ public: // reszta może by?publiczna
|
||||
TButton btLampkaHamowanie2zes;
|
||||
TButton btLampkaOpory;
|
||||
TButton btLampkaWysRozr;
|
||||
std::array<TButton, 10> btUniversals; // NOTE: temporary arrangement until we have dynamically built control table
|
||||
TButton btInstrumentLight;
|
||||
TButton btDashboardLight;
|
||||
TButton btTimetableLight;
|
||||
|
||||
@@ -1122,6 +1122,7 @@ driver_mode::InOutKey()
|
||||
|
||||
if( train == nullptr ) {
|
||||
FreeFlyModeFlag = true; // nadal poza kabiną
|
||||
Camera.m_owner = nullptr; // detach camera from the vehicle
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
14
renderer.cpp
14
renderer.cpp
@@ -836,9 +836,14 @@ void opengl_renderer::Render_pass(rendermode const Mode)
|
||||
// creates dynamic environment cubemap
|
||||
bool opengl_renderer::Render_reflections()
|
||||
{
|
||||
if (Global.ReflectionUpdatesPerSecond == 0)
|
||||
return false;
|
||||
|
||||
auto const &time = simulation::Time.data();
|
||||
auto const timestamp = time.wDay * 24 * 60 + time.wHour * 60 + time.wMinute;
|
||||
if ((timestamp - m_environmentupdatetime < 1) && (glm::length(m_renderpass.camera.position() - m_environmentupdatelocation) < 1000.0))
|
||||
auto const timestamp = time.wMilliseconds + time.wSecond * 1000 + time.wMinute * 1000 * 60 + time.wHour * 1000 * 60 * 60;
|
||||
|
||||
if ((timestamp - m_environmentupdatetime < Global.ReflectionUpdatesPerSecond)
|
||||
&& (glm::length(m_renderpass.camera.position() - m_environmentupdatelocation) < 1000.0))
|
||||
{
|
||||
// run update every 5+ mins of simulation time, or at least 1km from the last location
|
||||
return false;
|
||||
@@ -2445,6 +2450,7 @@ void opengl_renderer::Render(TSubModel *Submodel)
|
||||
// we're capping how much effect the distance attenuation can have, otherwise the lights get too tiny at regular distances
|
||||
float const distancefactor{std::max(0.5f, (Submodel->fSquareMaxDist - TSubModel::fSquareDist) / Submodel->fSquareMaxDist)};
|
||||
auto const pointsize{std::max(3.f, 5.f * distancefactor * anglefactor)};
|
||||
auto const resolutionratio { Global.iWindowHeight / 1080.f };
|
||||
// additionally reduce light strength for farther sources in rain or snow
|
||||
if (Global.Overcast > 0.75f)
|
||||
{
|
||||
@@ -2478,14 +2484,14 @@ void opengl_renderer::Render(TSubModel *Submodel)
|
||||
{
|
||||
// fake fog halo
|
||||
float const fogfactor{interpolate(2.f, 1.f, clamp<float>(Global.fFogEnd / 2000, 0.f, 1.f)) * std::max(1.f, Global.Overcast)};
|
||||
model_ubs.param[1].x = pointsize * fogfactor * 2.0f;
|
||||
model_ubs.param[1].x = pointsize * resolutionratio * fogfactor * 2.0f;
|
||||
model_ubs.param[0] = glm::vec4(glm::vec3(lightcolor), Submodel->fVisible * std::min(1.f, lightlevel) * 0.5f);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
draw(Submodel->m_geometry);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
model_ubs.param[1].x = pointsize * 2.0f;
|
||||
model_ubs.param[1].x = pointsize * resolutionratio * 2.0f;
|
||||
model_ubs.param[0] = glm::vec4(glm::vec3(lightcolor), Submodel->fVisible * std::min(1.f, lightlevel));
|
||||
|
||||
draw(Submodel->m_geometry);
|
||||
|
||||
@@ -185,7 +185,7 @@ init() {
|
||||
u8"Nastawnik: %2d+%d %c%s",
|
||||
u8" Prędkość: %d km/h (limit %d km/h%s)%s",
|
||||
u8", nowy limit: %d km/h za %.1f km",
|
||||
u8" Pochylenie: %.1f%%%%",
|
||||
u8" Nachylenie: %.1f%%%%",
|
||||
u8"Hamulce: %4.1f+%-2.0f%c%s",
|
||||
u8" Ciśnienie: %.2f kPa (przewód główny: %.2f kPa)",
|
||||
u8"!CZUWAK! ",
|
||||
|
||||
Reference in New Issue
Block a user