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

additional motor ventilator parameters exposed in .fiz file, motor ventilator spin rate tweaks, mouse support for radiostop commands, restricted speed mode for driver ai, passed signals scanning fix, mouse and keyboard command input rate unification, basic material textures priority system

This commit is contained in:
tmj-fstate
2018-01-24 22:27:58 +01:00
parent 0dc1394d59
commit 9d008d2a3e
23 changed files with 299 additions and 163 deletions

View File

@@ -253,18 +253,21 @@ void TSpeedPos::CommandCheck()
break;
default:
// inna komenda w evencie skanowanym powoduje zatrzymanie i wysłanie tej komendy
iFlags &= ~(spShuntSemaphor | spPassengerStopPoint |
spStopOnSBL); // nie manewrowa, nie przystanek, nie zatrzymać na SBL
fVelNext = 0.0; // jak nieznana komenda w komórce sygnałowej, to zatrzymujemy
// nie manewrowa, nie przystanek, nie zatrzymać na SBL
iFlags &= ~(spShuntSemaphor | spPassengerStopPoint | spStopOnSBL);
// jak nieznana komenda w komórce sygnałowej, to zatrzymujemy
fVelNext = 0.0;
}
};
bool TSpeedPos::Update()
{
if( fDist < 0.0 )
iFlags |= spElapsed; // trzeba zazanaczyć, że minięty
if (iFlags & spTrack) // road/track
{
if( fDist < 0.0 ) {
// trzeba zazanaczyć, że minięty
iFlags |= spElapsed;
}
if (iFlags & spTrack) {
// road/track
if (trTrack) {
// może być NULL, jeśli koniec toru (???)
fVelNext = trTrack->VelocityGet(); // aktualizacja prędkości (może być zmieniana eventem)
@@ -301,10 +304,15 @@ bool TSpeedPos::Update()
}
}
}
else if (iFlags & spEvent) // jeśli event
{ // odczyt komórki pamięci najlepiej by było zrobić jako notyfikację, czyli zmiana komórki
// wywoła jakąś podaną funkcję
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
else if (iFlags & spEvent) {
// jeśli event
if( ( ( iFlags & spElapsed ) == 0 )
|| ( fVelNext == 0.0 ) ) {
// ignore already passed signals, but keep an eye on overrun stops
// odczyt komórki pamięci najlepiej by było zrobić jako notyfikację,
// czyli zmiana komórki wywoła jakąś podaną funkcję
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
}
}
return false;
};
@@ -1107,23 +1115,28 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// koniec toru)
}
}
else if (sSpeedTable[i].iFlags & spStopOnSBL)
{ // jeśli S1 na SBL
if (mvOccupied->Vel < 2.0) // stanąć nie musi, ale zwolnić przynajmniej
if (sSpeedTable[i].fDist < fMaxProximityDist) // jest w maksymalnym zasięgu
{
eSignSkip = sSpeedTable[i]
.evEvent; // to można go pominąć (wziąć drugą prędkosć)
iDrivigFlags |= moveVisibility; // jazda na widoczność - skanować
// możliwość kolizji i nie podjeżdżać
// zbyt blisko
else if (sSpeedTable[i].iFlags & spStopOnSBL) {
// jeśli S1 na SBL
if( mvOccupied->Vel < 2.0 ) {
// stanąć nie musi, ale zwolnić przynajmniej
if( ( sSpeedTable[ i ].fDist < fMaxProximityDist )
&& ( TrackBlock() > 1000.0 ) ) {
// jest w maksymalnym zasięgu to można go pominąć (wziąć drugą prędkosć)
// as long as there isn't any obstacle in arbitrary view range
eSignSkip = sSpeedTable[ i ].evEvent;
// jazda na widoczność - skanować możliwość kolizji i nie podjeżdżać zbyt blisko
// usunąć flagę po podjechaniu blisko semafora zezwalającego na jazdę
// ostrożnie interpretować sygnały - semafor może zezwalać na jazdę
// pociągu z przodu!
// ostrożnie interpretować sygnały - semafor może zezwalać na jazdę pociągu z przodu!
iDrivigFlags |= moveVisibility;
// store the ordered restricted speed and don't exceed it until the flag is cleared
VelRestricted = sSpeedTable[ i ].evEvent->ValueGet( 2 );
}
if (eSignSkip != sSpeedTable[i].evEvent) // jeśli ten SBL nie jest do pominięcia
// TODO sprawdzić do której zmiennej jest przypisywane v i zmienić to tutaj
v = sSpeedTable[i].evEvent->ValueGet(1); // to ma 0 odczytywać
}
if( eSignSkip != sSpeedTable[ i ].evEvent ) {
// jeśli ten SBL nie jest do pominięcia to ma 0 odczytywać
v = sSpeedTable[ i ].evEvent->ValueGet( 1 );
// TODO sprawdzić do której zmiennej jest przypisywane v i zmienić to tutaj
}
}
else if (sSpeedTable[i].IsProperSemaphor(OrderCurrentGet()))
{ // to semaphor
@@ -1230,41 +1243,42 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
}
}
}
else if (!(sSpeedTable[i].iFlags & spSectionVel)) //jeśli jakiś event pasywny ale nie ograniczenie
if (go == cm_Unknown) // jeśli nie było komendy wcześniej - pierwsza się liczy
// - ustawianie VelSignal
if (v < 0.0 ? true : v >= 1.0) // bo wartość 0.1 służy do hamowania tylko
{
go = cm_SetVelocity; // może odjechać
// Ra 2014-06: (VelSignal) nie może być tu ustawiane, bo semafor może
// być daleko
// VelSignal=v; //nie do końca tak, to jest druga prędkość; -1 nie
// wpisywać...
if (VelSignal == 0.0)
VelSignal = -1.0; // aby stojący ruszył
if (sSpeedTable[i].fDist < 0.0) // jeśli przejechany
{
VelSignal = (v != 0 ? -1.0 : 0.0);
// ustawienie, gdy przejechany jest lepsze niż
// wcale, ale to jeszcze nie to
if (sSpeedTable[i].iFlags & spEvent) // jeśli event
if ((sSpeedTable[i].evEvent != eSignSkip) ?
true :
(sSpeedTable[i].fVelNext != 0.0)) // ale inny niż ten,
// na którym minięto
// S1, chyba że się
// już zmieniło
iDrivigFlags &= ~moveVisibility; // sygnał zezwalający na
// jazdę wyłącza jazdę na
// widoczność (S1 na SBL)
// usunąć jeśli nie jest ograniczeniem prędkości
sSpeedTable[i].iFlags =
0; // to można usunąć (nie mogą być usuwane w skanowaniu)
else if( !( sSpeedTable[ i ].iFlags & spSectionVel ) ) {
//jeśli jakiś event pasywny ale nie ograniczenie
if( go == cm_Unknown ) {
// jeśli nie było komendy wcześniej - pierwsza się liczy - ustawianie VelSignal
if( ( v < 0.0 )
|| ( v >= 1.0 ) ) {
// bo wartość 0.1 służy do hamowania tylko
go = cm_SetVelocity; // może odjechać
// Ra 2014-06: (VelSignal) nie może być tu ustawiane, bo semafor może być daleko
// VelSignal=v; //nie do końca tak, to jest druga prędkość; -1 nie wpisywać...
if( VelSignal == 0.0 ) {
// aby stojący ruszył
VelSignal = -1.0;
}
if( sSpeedTable[ i ].fDist < 0.0 ) {
// jeśli przejechany
VelSignal = ( v == 0.0 ? 0.0 : -1.0 );
// ustawienie, gdy przejechany jest lepsze niż wcale, ale to jeszcze nie to
if( sSpeedTable[ i ].iFlags & spEvent ) {
// jeśli event
if( ( sSpeedTable[ i ].evEvent != eSignSkip )
|| ( sSpeedTable[ i ].fVelNext != VelRestricted ) ) {
// ale inny niż ten, na którym minięto S1, chyba że się już zmieniło
// sygnał zezwalający na jazdę wyłącza jazdę na widoczność (po S1 na SBL)
iDrivigFlags &= ~moveVisibility;
// remove restricted speed
VelRestricted = -1.0;
}
}
// jeśli nie jest ograniczeniem prędkości to można usunąć
// (nie mogą być usuwane w skanowaniu)
sSpeedTable[ i ].iFlags = 0;
}
}
else if (sSpeedTable[i].evEvent->StopCommand())
{ // jeśli prędkość jest zerowa, a komórka zawiera komendę
else if( sSpeedTable[ i ].evEvent->StopCommand() ) {
// jeśli prędkość jest zerowa, a komórka zawiera komendę
eSignNext = sSpeedTable[ i ].evEvent; // dla informacji
if( true == TestFlag( iDrivigFlags, moveStopHere ) ) {
// jeśli ma stać, dostaje komendę od razu
@@ -1276,6 +1290,8 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
go = cm_Command; // komenda z komórki, do wykonania po zatrzymaniu
}
}
}
}
} // jeśli nie ma zawalidrogi
} // jeśli event
if (v >= 0.0)
@@ -1366,7 +1382,9 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
fVelDes = Min0R(fVelDes, VelLimitLast);
if (VelRoad >= 0.0)
fVelDes = Min0R(fVelDes, VelRoad);
// nastepnego semafora albo zwrotnicy to uznajemy, że mijamy W5
if( VelRestricted >= 0.0 )
fVelDes = Min0R( fVelDes, VelRestricted );
// nastepnego semafora albo zwrotnicy to uznajemy, że mijamy W5
FirstSemaphorDist = d_to_next_sem; // przepisanie znalezionej wartosci do zmiennej
return go;
};
@@ -3740,7 +3758,6 @@ TController::UpdateSituation(double dt) {
// check for potential colliders
{
auto const collisionscanrange = 300.0 + fBrakeDist;
auto rearvehicle = (
pVehicles[ 0 ] == pVehicles[ 1 ] ?
pVehicles[ 0 ] :
@@ -3764,7 +3781,7 @@ TController::UpdateSituation(double dt) {
pVehicle->DirectionGet() == pVehicles[ 0 ]->DirectionGet() ?
1 :
-1 ),
collisionscanrange );
routescanrange );
}
else {
// towards coupler 1
@@ -3782,7 +3799,7 @@ TController::UpdateSituation(double dt) {
pVehicle->DirectionGet() == pVehicles[ 0 ]->DirectionGet() ?
-1 :
1 ),
collisionscanrange );
routescanrange );
}
}

View File

@@ -152,7 +152,7 @@ class TSpeedPos
inline
void
UpdateDistance( double dist ) {
fDist -= dist; }
fDist -= dist; }
bool Set(TEvent *e, double d, TOrders order = Wait_for_orders);
void Set(TTrack *t, double d, int f);
std::string TableText();
@@ -224,7 +224,7 @@ private:
double LastReactionTime = 0.0;
double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi
double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations
TAction eAction = actSleep; // aktualny stan
TAction eAction { actUnknown }; // aktualny stan
public:
inline
TAction GetAction() {
@@ -258,6 +258,7 @@ private:
double VelLimitLast = -1.0; // prędkość zadana przez ograniczenie // ostatnie ograniczenie bez ograniczenia
double VelRoad = -1.0; // aktualna prędkość drogowa (ze znaku W27) (PutValues albo komendą) // prędkość drogowa bez ograniczenia
double VelNext = 120.0; // prędkość, jaka ma być po przejechaniu długości ProximityDist
double VelRestricted = -1.0; // speed of travel after passing a permissive signal at stop
private:
double fProximityDist = 0.0; // odleglosc podawana w SetProximityVelocity(); >0:przeliczać do punktu, <0:podana wartość
double FirstSemaphorDist = 10000.0; // odległość do pierwszego znalezionego semafora

View File

@@ -915,14 +915,12 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
smWahacze[i]->SetRotate(float3(1, 0, 0),
fWahaczeAmp * cos(MoverParameters->eAngle));
if (Mechanik) {
if( ( Mechanik != nullptr )
&& ( Mechanik->GetAction() != actSleep ) ) {
// rysowanie figurki mechanika
if( MoverParameters->ActiveCab > 0 ) {
btMechanik1.Turn( true );
btnOn = true;
}
if( MoverParameters->ActiveCab < 0 ) {
btMechanik2.Turn( true );
btMechanik1.Turn( MoverParameters->ActiveCab > 0 );
btMechanik2.Turn( MoverParameters->ActiveCab < 0 );
if( MoverParameters->ActiveCab != 0 ) {
btnOn = true;
}
}
@@ -2309,7 +2307,7 @@ void TDynamicObject::Move(double fDistance)
{ // liczymy proporcję
double d = Axle0.GetTranslation(); // aktualne położenie na torze
if (Axle0.GetDirection() < 0)
d = t0->fTrackLength - d; // od drugiej strony liczona długość
d = t0->Length() - d; // od drugiej strony liczona długość
d /= fAxleDist; // rozsataw osi procentowe znajdowanie się na torze
float shadefrom = 1.0f, shadeto = 1.0f;
@@ -3483,9 +3481,9 @@ void TDynamicObject::RenderSounds() {
if( Global::iPause != 0 ) { return; }
double const dt { Timer::GetDeltaRenderTime() };
double volume { 0.0 };
double frequency { 1.0 };
double const dt{ Timer::GetDeltaRenderTime() };
double volume{ 0.0 };
double frequency{ 1.0 };
m_powertrainsounds.render( *MoverParameters, dt );
@@ -3493,8 +3491,8 @@ void TDynamicObject::RenderSounds() {
if( MoverParameters->ConverterFlag ) {
frequency = (
MoverParameters->EngineType == ElectricSeriesMotor ?
( MoverParameters->RunningTraction.TractionVoltage / MoverParameters->NominalVoltage ) * MoverParameters->RList[ MoverParameters->RlistSize ].Mn :
1.0 );
( MoverParameters->RunningTraction.TractionVoltage / MoverParameters->NominalVoltage ) * MoverParameters->RList[ MoverParameters->RlistSize ].Mn :
1.0 );
frequency = sConverter.m_frequencyoffset + sConverter.m_frequencyfactor * frequency;
sConverter
.pitch( clamp( frequency, 0.5, 1.25 ) ) // arbitrary limits )
@@ -3526,7 +3524,7 @@ void TDynamicObject::RenderSounds() {
// brake system and braking sounds:
if( m_lastbrakepressure != -1.f ) {
// calculate rate of pressure drop in brake cylinder, once it's been initialized
auto const brakepressuredifference { m_lastbrakepressure - MoverParameters->BrakePress };
auto const brakepressuredifference{ m_lastbrakepressure - MoverParameters->BrakePress };
m_brakepressurechange = interpolate<float>( m_brakepressurechange, brakepressuredifference / dt, 0.005f );
}
m_lastbrakepressure = MoverParameters->BrakePress;
@@ -3562,9 +3560,9 @@ void TDynamicObject::RenderSounds() {
if( MoverParameters->SlippingWheels ) {
if( ( MoverParameters->UnitBrakeForce > 100.0 )
&& ( GetVelocity() > 1.0 ) ) {
&& ( GetVelocity() > 1.0 ) ) {
auto const velocitydifference { GetVelocity() / MoverParameters->Vmax };
auto const velocitydifference{ GetVelocity() / MoverParameters->Vmax };
rsSlippery
.gain( rsSlippery.m_amplitudeoffset + rsSlippery.m_amplitudefactor * velocitydifference )
.play( sound_flags::exclusive | sound_flags::looping );
@@ -3582,10 +3580,10 @@ void TDynamicObject::RenderSounds() {
sSand.stop();
}
auto brakeforceratio { 0.0 };
auto brakeforceratio{ 0.0 };
if( //( false == mvOccupied->SlippingWheels ) &&
( MoverParameters->UnitBrakeForce > 10.0 )
&& ( MoverParameters->Vel > 0.05 ) ) {
&& ( MoverParameters->Vel > 0.05 ) ) {
brakeforceratio =
clamp(
@@ -3639,7 +3637,7 @@ void TDynamicObject::RenderSounds() {
}
// NBMX Obsluga drzwi, MC: zuniwersalnione
if( ( true == MoverParameters->DoorLeftOpened )
&& ( dDoorMoveL < MoverParameters->DoorMaxShiftL ) ) {
&& ( dDoorMoveL < MoverParameters->DoorMaxShiftL ) ) {
for( auto &door : m_doorsounds ) {
if( door.rsDoorClose.offset().x > 0.f ) {
@@ -3650,7 +3648,7 @@ void TDynamicObject::RenderSounds() {
}
}
if( ( false == MoverParameters->DoorLeftOpened )
&& ( dDoorMoveL > 0.01 ) ) {
&& ( dDoorMoveL > 0.01 ) ) {
for( auto &door : m_doorsounds ) {
if( door.rsDoorClose.offset().x > 0.f ) {
@@ -3661,7 +3659,7 @@ void TDynamicObject::RenderSounds() {
}
}
if( ( true == MoverParameters->DoorRightOpened )
&& ( dDoorMoveR < MoverParameters->DoorMaxShiftR ) ) {
&& ( dDoorMoveR < MoverParameters->DoorMaxShiftR ) ) {
for( auto &door : m_doorsounds ) {
if( door.rsDoorClose.offset().x < 0.f ) {
@@ -3672,7 +3670,7 @@ void TDynamicObject::RenderSounds() {
}
}
if( ( false == MoverParameters->DoorRightOpened )
&& ( dDoorMoveR > 0.01 ) ) {
&& ( dDoorMoveR > 0.01 ) ) {
for( auto &door : m_doorsounds ) {
if( door.rsDoorClose.offset().x < 0.f ) {
@@ -3699,15 +3697,15 @@ void TDynamicObject::RenderSounds() {
if( ( GetVelocity() > 0.5 )
&& ( false == rsOuterNoise.empty() )
&& ( // compound test whether the vehicle belongs to user-driven consist (as these don't emit outer noise in cab view)
FreeFlyModeFlag ? true : // in external view all vehicles emit outer noise
// Global::pWorld->train() == nullptr ? true : // (can skip this check, with no player train the external view is a given)
ctOwner == nullptr ? true : // standalone vehicle, can't be part of user-driven train
ctOwner != Global::pWorld->train()->Dynamic()->ctOwner ? true : // confirmed isn't a part of the user-driven train
Global::CabWindowOpen ? true : // sticking head out we get to hear outer noise
false ) ) {
FreeFlyModeFlag ? true : // in external view all vehicles emit outer noise
// Global::pWorld->train() == nullptr ? true : // (can skip this check, with no player train the external view is a given)
ctOwner == nullptr ? true : // standalone vehicle, can't be part of user-driven train
ctOwner != Global::pWorld->train()->Dynamic()->ctOwner ? true : // confirmed isn't a part of the user-driven train
Global::CabWindowOpen ? true : // sticking head out we get to hear outer noise
false ) ) {
// frequency calculation
auto const normalizer { (
// frequency calculation
auto const normalizer{ (
true == rsOuterNoise.is_combined() ?
MoverParameters->Vmax * 0.01f :
1.f ) };
@@ -3749,15 +3747,18 @@ void TDynamicObject::RenderSounds() {
rsOuterNoise.stop( false == FreeFlyModeFlag );
}
// flat spot sound
if( ( GetVelocity() > 1.0 )
&& ( MoverParameters->WheelFlat > 5.0 ) ) {
m_wheelflat
.pitch( m_wheelflat.m_frequencyoffset + std::abs( MoverParameters->nrot ) * m_wheelflat.m_frequencyfactor )
.gain( m_wheelflat.m_amplitudeoffset + m_wheelflat.m_amplitudefactor * ( ( 1.0 + ( MoverParameters->Vel / MoverParameters->Vmax ) + clamp( MoverParameters->WheelFlat / 60.0, 0.0, 1.0 ) ) / 3.0 ) )
.play( sound_flags::exclusive | sound_flags::looping );
}
else {
m_wheelflat.stop();
if( MoverParameters->CategoryFlag == 1 ) {
// trains only
if( ( GetVelocity() > 1.0 )
&& ( MoverParameters->WheelFlat > 5.0 ) ) {
m_wheelflat
.pitch( m_wheelflat.m_frequencyoffset + std::abs( MoverParameters->nrot ) * m_wheelflat.m_frequencyfactor )
.gain( m_wheelflat.m_amplitudeoffset + m_wheelflat.m_amplitudefactor * ( ( 1.0 + ( MoverParameters->Vel / MoverParameters->Vmax ) + clamp( MoverParameters->WheelFlat / 60.0, 0.0, 1.0 ) ) / 3.0 ) )
.play( sound_flags::exclusive | sound_flags::looping );
}
else {
m_wheelflat.stop();
}
}
// youBy: dzwiek ostrych lukow i ciasnych zwrotek

View File

@@ -68,6 +68,7 @@ double Global::fFogStart = 1700;
double Global::fFogEnd = 2000;
float Global::Overcast { 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
std::string Global::Season; // season of the year, based on simulation date
std::string Global::Weather { "clear" }; // current weather
float Global::BaseDrawRange { 2500.f };
opengl_light Global::DayLight;

View File

@@ -189,6 +189,7 @@ public:
static double fFogStart;
static double fFogEnd;
static std::string Season; // season of the year, based on simulation date
static std::string Weather; // current weather
// TODO: put these things in the renderer
static float BaseDrawRange;

View File

@@ -84,8 +84,6 @@ extern int ConversionError;
const double Steel2Steel_friction = 0.15; //tarcie statyczne
const double g = 9.81; //przyspieszenie ziemskie
const double SandSpeed = 0.1; //ile kg/s}
const double RVentSpeed = 3.5; //rozpedzanie sie wentylatora obr/s^2}
const double RVentMinI = 50.0; //przy jakim pradzie sie wylaczaja}
const double Pirazy2 = 6.2831853071794f;
#define PI 3.1415926535897f
@@ -739,7 +737,8 @@ public:
double u = 0.0; //wspolczynnik tarcia yB wywalic!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
double CircuitRes = 0.0; /*rezystancje silnika i obwodu*/
int IminLo = 0; int IminHi = 0; /*prady przelacznika automatycznego rozruchu, uzywane tez przez ai_driver*/
int ImaxLo = 0; int ImaxHi = 0; /*maksymalny prad niskiego i wysokiego rozruchu*/
int ImaxLo = 0; // maksymalny prad niskiego rozruchu
int ImaxHi = 0; // maksymalny prad wysokiego rozruchu
double nmax = 0.0; /*maksymalna dop. ilosc obrotow /s*/
double InitialCtrlDelay = 0.0; double CtrlDelay = 0.0; /* -//- -//- miedzy kolejnymi poz.*/
double CtrlDownDelay = 0.0; /* -//- -//- przy schodzeniu z poz.*/ /*hunter-101012*/
@@ -752,6 +751,8 @@ public:
int RVentType = 0; /*0 - brak, 1 - jest, 2 - automatycznie wlaczany*/
double RVentnmax = 1.0; /*maks. obroty wentylatorow oporow rozruchowych*/
double RVentCutOff = 0.0; /*rezystancja wylaczania wentylatorow dla RVentType=2*/
double RVentSpeed { 0.5 }; //rozpedzanie sie wentylatora obr/s^2}
double RVentMinI { 50.0 }; //przy jakim pradzie sie wylaczaja}
int CompressorPower = 1; /*0: bezp. z obwodow silnika, 1: z przetwornicy, reczne, 2: w przetwornicy, stale, 5: z silnikowego*/
int SmallCompressorPower = 0; /*Winger ZROBIC*/
bool Trafo = false; /*pojazd wyposażony w transformator*/

View File

@@ -4252,7 +4252,7 @@ double TMoverParameters::TractionForce(double dt)
RventRot += ( RVentnmax - RventRot ) * RVentSpeed * dt;
}
else {
RventRot = std::max( 0.0, RventRot - RVentSpeed * dt );
RventRot *= std::max( 0.0, 1.0 - RVentSpeed * dt );
}
break;
}
@@ -4260,14 +4260,30 @@ double TMoverParameters::TractionForce(double dt)
case 2: { // automatic
if( ( std::abs( Itot ) > RVentMinI )
&& ( RList[ MainCtrlActualPos ].R > RVentCutOff ) ) {
/*
RventRot += ( RVentnmax * abs( Itot ) / ( ImaxLo * RList[ MainCtrlActualPos ].Bn ) - RventRot ) * RVentSpeed * dt;
*/
RventRot = std::min(
RVentnmax,
RventRot
+ ( RVentnmax
* std::abs( Itot )
* std::min( 1.25, ( ( std::abs( Itot ) / NPoweredAxles ) / RVentMinI ) )
/ ImaxLo
- RventRot )
* RVentSpeed * dt );
/*
RventRot = std::min(
RVentnmax,
RventRot + ( ( std::abs( Itot ) / ( RList[ MainCtrlActualPos ].Bn * RList[ MainCtrlActualPos ].Mn ) ) / RVentMinI ) * RVentSpeed * dt );
*/
}
else if( ( DynamicBrakeType == dbrake_automatic )
&& ( true == DynamicBrakeFlag ) ) {
RventRot += ( RVentnmax * Im / ImaxLo - RventRot ) * RVentSpeed * dt;
}
else {
RventRot = std::max( 0.0, RventRot - RVentSpeed * dt );
RventRot *= std::max( 0.0, 1.0 - RVentSpeed * dt );
}
break;
}
@@ -4278,8 +4294,9 @@ double TMoverParameters::TractionForce(double dt)
} // rventtype
} // mains
else {
RventRot = std::max( 0.0, RventRot - RVentSpeed * dt );
RventRot *= std::max( 0.0, 1.0 - RVentSpeed * dt );
}
break;
}
case DieselElectric: {
@@ -7739,6 +7756,8 @@ void TMoverParameters::LoadFIZ_RList( std::string const &Input ) {
RVentnmax /= 60.0;
extract_value( RVentCutOff, "RVentCutOff", Input, "" );
}
extract_value( RVentMinI, "RVentMinI", Input, "" );
extract_value( RVentSpeed, "RVentSpeed", Input, "" );
}
void TMoverParameters::LoadFIZ_DList( std::string const &Input ) {

View File

@@ -19,9 +19,9 @@ class TSegment
private:
Math3D::vector3 Point1, CPointOut, CPointIn, Point2;
float
fRoll1{ 0.f },
fRoll2{ 0.f }; // przechyłka na końcach
double fLength = 0.0; // długość policzona
fRoll1 { 0.f },
fRoll2 { 0.f }; // przechyłka na końcach
double fLength { -1.0 }; // długość policzona
double *fTsBuffer = nullptr; // wartości parametru krzywej dla równych odcinków
double fStep = 0.0;
int iSegCount = 0; // ilość odcinków do rysowania krzywej

View File

@@ -406,7 +406,12 @@ void TTrack::Load(cParser *parser, vector3 pOrigin)
if (Global::iWriteLogEnabled & 4)
WriteLog(str);
parser->getTokens(4);
*parser >> fTrackLength >> fTrackWidth >> fFriction >> fSoundDistance;
float discard {};
*parser
>> discard
>> fTrackWidth
>> fFriction
>> fSoundDistance;
fTrackWidth2 = fTrackWidth; // rozstaw/szerokość w punkcie 2, na razie taka sama
parser->getTokens(2);
*parser >> iQualityFlag >> iDamageFlag;
@@ -485,30 +490,40 @@ void TTrack::Load(cParser *parser, vector3 pOrigin)
p2.y += 0.18;
// na przechyłce doliczyć jeszcze pół przechyłki
}
if( fRadius != 0 ) // gdy podany promień
segsize = clamp( std::fabs( fRadius ) * ( 0.02 / Global::SplineFidelity ), 2.0 / Global::SplineFidelity, 10.0 );
if( ( ( ( p1 + p1 + p2 ) / 3.0 - p1 - cp1 ).Length() < 0.02 )
|| ( ( ( p1 + p2 + p2 ) / 3.0 - p2 + cp1 ).Length() < 0.02 ) ) {
// "prostowanie" prostych z kontrolnymi, dokładność 2cm
cp1 = cp2 = Math3D::vector3( 0, 0, 0 );
}
if( fRadius != 0 ) {
// gdy podany promień
segsize = clamp( std::abs( fRadius ) * ( 0.02 / Global::SplineFidelity ), 2.0 / Global::SplineFidelity, 10.0 );
}
else {
// HACK: crude check whether claimed straight is an actual straight piece
// NOTE: won't detect cases where control points are placed on the straight line formed by the ends, but, eh
if( ( cp1 == Math3D::vector3() )
&& ( cp1 == Math3D::vector3() ) ) {
&& ( cp2 == Math3D::vector3() ) ) {
segsize = 10.0; // for straights, 10m per segment works good enough
}
else {
// HACK: divide roughly in 10 segments.
segsize = clamp( fTrackLength * ( 0.1 / Global::SplineFidelity ), 2.0 / Global::SplineFidelity, 10.0 );
segsize = clamp( ( p1 - p2 ).Length() * ( 0.1 / Global::SplineFidelity ), 2.0 / Global::SplineFidelity, 10.0 );
}
}
if ((((p1 + p1 + p2) / 3.0 - p1 - cp1).Length() < 0.02) ||
(((p1 + p2 + p2) / 3.0 - p2 + cp1).Length() < 0.02))
cp1 = cp2 = vector3(0, 0, 0); //"prostowanie" prostych z kontrolnymi, dokładność 2cm
if( ( cp1 == vector3( 0, 0, 0 ) )
&& ( cp2 == vector3( 0, 0, 0 ) ) ) {
// Ra: hm, czasem dla prostego są podane...
// gdy prosty, kontrolne wyliczane przy zmiennej przechyłce
Segment->Init( p1, p2, segsize, r1, r2 );
}
else {
// gdy łuk (ustawia bCurve=true)
Segment->Init( p1, cp1 + p1, cp2 + p2, p2, segsize, r1, r2 );
}
if ((cp1 == vector3(0, 0, 0)) &&
(cp2 == vector3(0, 0, 0))) // Ra: hm, czasem dla prostego są podane...
Segment->Init(p1, p2, segsize, r1, r2); // gdy prosty, kontrolne wyliczane przy zmiennej przechyłce
else
Segment->Init(p1, cp1 + p1, cp2 + p2, p2, segsize, r1, r2); // gdy łuk (ustawia bCurve=true)
if ((r1 != 0) || (r2 != 0))
iTrapezoid = 1; // są przechyłki do uwzględniania w rysowaniu
if (eType == tt_Table) // obrotnica ma doklejkę

View File

@@ -184,7 +184,7 @@ private:
double fVelocity = -1.0; // ograniczenie prędkości // prędkość dla AI (powyżej rośnie prawdopowobieństwo wykolejenia)
public:
// McZapkie-100502:
double fTrackLength = 100.0; // długość z wpisu, nigdzie nie używana
// double fTrackLength = 100.0; // długość z wpisu, nigdzie nie używana
double fRadius = 0.0; // promień, dla zwrotnicy kopiowany z tabeli
bool ScannedFlag = false; // McZapkie: do zaznaczania kolorem torów skanowanych przez AI
TGroundNode *nFouling[ 2 ] = { nullptr, nullptr }; // współrzędne ukresu albo oporu kozła

View File

@@ -285,6 +285,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
{ user_command::radiotoggle, &TTrain::OnCommand_radiotoggle },
{ user_command::radiochannelincrease, &TTrain::OnCommand_radiochannelincrease },
{ user_command::radiochanneldecrease, &TTrain::OnCommand_radiochanneldecrease },
{ user_command::radiostopsend, &TTrain::OnCommand_radiostopsend },
{ user_command::radiostoptest, &TTrain::OnCommand_radiostoptest },
{ user_command::cabchangeforward, &TTrain::OnCommand_cabchangeforward },
{ user_command::cabchangebackward, &TTrain::OnCommand_cabchangebackward },
@@ -3104,11 +3105,33 @@ void TTrain::OnCommand_radiochanneldecrease( TTrain *Train, command_data const &
}
}
void TTrain::OnCommand_radiostopsend( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) {
if( true == Train->mvOccupied->Radio ) {
simulation::Region->RadioStop( Train->Dynamic()->GetPosition() );
}
// visual feedback
Train->ggRadioStop.UpdateValue( 1.0 );
}
else if( Command.action == GLFW_RELEASE ) {
// visual feedback
Train->ggRadioStop.UpdateValue( 0.0 );
}
}
void TTrain::OnCommand_radiostoptest( TTrain *Train, command_data const &Command ) {
if( Command.action == GLFW_PRESS ) {
Train->Dynamic()->RadioStop();
if( Train->RadioChannel() == 10 ) {
Train->Dynamic()->RadioStop();
}
// visual feedback
Train->ggRadioTest.UpdateValue( 1.0 );
}
else if( Command.action == GLFW_RELEASE ) {
// visual feedback
Train->ggRadioTest.UpdateValue( 0.0 );
}
}
@@ -3939,6 +3962,7 @@ bool TTrain::Update( double const Deltatime )
btLampkaMaxSila.Turn(abs(mvControlled->Im) >= 350);
btLampkaPrzekrMaxSila.Turn(abs(mvControlled->Im) >= 450);
btLampkaRadio.Turn(mvOccupied->Radio);
btLampkaRadioStop.Turn( mvOccupied->Radio && mvOccupied->RadioStopFlag );
btLampkaHamulecReczny.Turn(mvOccupied->ManualBrakePos > 0);
// NBMX wrzesien 2003 - drzwi oraz sygnał odjazdu
btLampkaDoorLeft.Turn(mvOccupied->DoorLeftOpened);
@@ -3974,6 +3998,7 @@ bool TTrain::Update( double const Deltatime )
btLampkaMaxSila.Turn( false );
btLampkaPrzekrMaxSila.Turn( false );
btLampkaRadio.Turn( false );
btLampkaRadioStop.Turn( false );
btLampkaHamulecReczny.Turn( false );
btLampkaDoorLeft.Turn( false );
btLampkaDoorRight.Turn( false );
@@ -4187,6 +4212,8 @@ bool TTrain::Update( double const Deltatime )
ggRadioChannelSelector.Update();
ggRadioChannelPrevious.Update();
ggRadioChannelNext.Update();
ggRadioStop.Update();
ggRadioTest.Update();
ggDepartureSignalButton.Update();
ggPantFrontButton.Update();
@@ -4563,6 +4590,15 @@ TTrain::update_sounds( double const Deltatime ) {
}
}
// radiostop
if( ( true == mvOccupied->Radio )
&& ( true == mvOccupied->RadioStopFlag ) ) {
m_radiostop.play( sound_flags::exclusive | sound_flags::looping );
}
else {
m_radiostop.stop();
}
if( fTachoCount > 3.f ) {
dsbHasler.play( sound_flags::exclusive | sound_flags::looping );
}
@@ -4648,6 +4684,11 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName)
dsbBuzzer.deserialize( parser, sound_type::single );
dsbBuzzer.owner( DynamicObject );
}
else if( token == "radiostop:" ) {
// radiostop
m_radiostop.deserialize( parser, sound_type::single );
m_radiostop.owner( DynamicObject );
}
else if (token == "slipalarm:")
{
// Bombardier 011010: alarm przy poslizgu:
@@ -4787,7 +4828,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
&dsbSwitch, &dsbPneumaticSwitch,
&rsHiss, &rsHissU, &rsHissE, &rsHissX, &rsHissT, &rsSBHiss, &rsSBHissU,
&rsFadeSound, &rsRunningNoise,
&dsbHasler, &dsbBuzzer, &dsbSlipAlarm, &m_radiosound
&dsbHasler, &dsbBuzzer, &dsbSlipAlarm, &m_radiosound, &m_radiostop
};
for( auto sound : sounds ) {
sound->offset( nullvector );
@@ -4967,6 +5008,9 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
if( m_radiosound.offset() == nullvector ) {
m_radiosound.offset( btLampkaRadio.model_offset() );
}
if( m_radiostop.offset() == nullvector ) {
m_radiostop.offset( m_radiosound.offset() );
}
auto const localbrakeoffset { ggLocalBrake.model_offset() };
std::vector<sound_source *> localbrakesounds = {
&rsSBHiss, &rsSBHissU
@@ -5183,6 +5227,8 @@ void TTrain::clear_cab_controls()
ggRadioChannelSelector.Clear();
ggRadioChannelPrevious.Clear();
ggRadioChannelNext.Clear();
ggRadioStop.Clear();
ggRadioTest.Clear();
ggDoorLeftButton.Clear();
ggDoorRightButton.Clear();
ggDepartureSignalButton.Clear();
@@ -5242,6 +5288,7 @@ void TTrain::clear_cab_controls()
btLampkaMaxSila.Clear();
btLampkaPrzekrMaxSila.Clear();
btLampkaRadio.Clear();
btLampkaRadioStop.Clear();
btLampkaHamulecReczny.Clear();
btLampkaBlokadaDrzwi.Clear();
btInstrumentLight.Clear();
@@ -5502,6 +5549,7 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
{ "i-maxft:", btLampkaMaxSila },
{ "i-maxftt:", btLampkaPrzekrMaxSila },
{ "i-radio:", btLampkaRadio },
{ "i-radiostop:", btLampkaRadioStop },
{ "i-manual_brake:", btLampkaHamulecReczny },
{ "i-door_blocked:", btLampkaBlokadaDrzwi },
{ "i-slippery:", btLampkaPoslizg },
@@ -5655,6 +5703,8 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
{ "radiochannel_sw:", ggRadioChannelSelector },
{ "radiochannelprev_sw:", ggRadioChannelPrevious },
{ "radiochannelnext_sw:", ggRadioChannelNext },
{ "radiostop_sw:", ggRadioStop },
{ "radiotest_sw:", ggRadioTest },
{ "pantfront_sw:", ggPantFrontButton },
{ "pantrear_sw:", ggPantRearButton },
{ "pantfrontoff_sw:", ggPantFrontButtonOff },

View File

@@ -211,6 +211,7 @@ class TTrain
static void OnCommand_radiotoggle( TTrain *Train, command_data const &Command );
static void OnCommand_radiochannelincrease( TTrain *Train, command_data const &Command );
static void OnCommand_radiochanneldecrease( TTrain *Train, command_data const &Command );
static void OnCommand_radiostopsend( TTrain *Train, command_data const &Command );
static void OnCommand_radiostoptest( TTrain *Train, command_data const &Command );
static void OnCommand_cabchangeforward( TTrain *Train, command_data const &Command );
static void OnCommand_cabchangebackward( TTrain *Train, command_data const &Command );
@@ -274,6 +275,8 @@ public: // reszta może by?publiczna
TGauge ggRadioChannelSelector;
TGauge ggRadioChannelPrevious;
TGauge ggRadioChannelNext;
TGauge ggRadioTest;
TGauge ggRadioStop;
TGauge ggUpperLightButton;
TGauge ggLeftLightButton;
TGauge ggRightLightButton;
@@ -357,6 +360,7 @@ public: // reszta może by?publiczna
TButton btLampkaUkrotnienie;
TButton btLampkaHamPosp;
TButton btLampkaRadio;
TButton btLampkaRadioStop;
TButton btLampkaHamowanie1zes;
TButton btLampkaHamowanie2zes;
TButton btLampkaOpory;
@@ -458,6 +462,7 @@ public: // reszta może by?publiczna
sound_source dsbSlipAlarm { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // Bombardier 011010: alarm przy poslizgu dla 181/182
sound_source m_radiosound { sound_placement::internal, 2 * EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // cached template for radio messages
std::vector<sound_source> m_radiomessages; // list of currently played radio messages
sound_source m_radiostop { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE };
int iCabLightFlag; // McZapkie:120503: oswietlenie kabiny (0: wyl, 1: przyciemnione, 2: pelne)
bool bCabLight; // hunter-091012: czy swiatlo jest zapalone?

View File

@@ -629,11 +629,6 @@ void TWorld::OnKeyDown(int cKey) {
Global::iTextMode = GLFW_KEY_F1; // to wyświetlić zegar i informację
}
}
else if( ( cKey == GLFW_KEY_PAUSE ) && ( Global::ctrlState ) && ( Global::shiftState ) ) {
//[Ctrl]+[Break] hamowanie wszystkich pojazdów w okolicy // added shift to prevent odd issue with glfw producing pause presses on its own
if( Controlled->MoverParameters->Radio )
simulation::Region->RadioStop( Camera.Pos );
}
else {
if( ( true == DebugModeFlag )
@@ -1424,15 +1419,16 @@ TWorld::Update_UI() {
uitextline4 +=
"Driver: Vd=" + to_string( vehicle->Mechanik->VelDesired, 0 )
+ " Ad=" + to_string( vehicle->Mechanik->AccDesired, 2 )
+ " Ah=" + to_string( vehicle->Mechanik->fAccThreshold, 2 )
+ "@" + to_string( vehicle->Mechanik->fBrake_a0[0], 2 )
+ "+" + to_string( vehicle->Mechanik->fBrake_a1[0], 2 )
+ " Ah=" + to_string( vehicle->Mechanik->fAccThreshold, 2 )
+ "@" + to_string( vehicle->Mechanik->fBrake_a0[ 0 ], 2 )
+ "+" + to_string( vehicle->Mechanik->fBrake_a1[ 0 ], 2 )
+ " Bd=" + to_string( vehicle->Mechanik->fBrakeDist, 0 )
+ " Pd=" + to_string( vehicle->Mechanik->ActualProximityDist, 0 )
+ " Vn=" + to_string( vehicle->Mechanik->VelNext, 0 )
+ " VSl=" + to_string( vehicle->Mechanik->VelSignalLast, 0 )
+ " VLl=" + to_string( vehicle->Mechanik->VelLimitLast, 0 )
+ " VRd=" + to_string( vehicle->Mechanik->VelRoad, 0 );
+ " VRd=" + to_string( vehicle->Mechanik->VelRoad, 0 )
+ " VRst=" + to_string( vehicle->Mechanik->VelRestricted, 0 );
if( ( vehicle->Mechanik->VelNext == 0.0 )
&& ( vehicle->Mechanik->eSignNext ) ) {

View File

@@ -76,6 +76,7 @@ commanddescription_sequence Commands_descriptions = {
{ "radiotoggle", command_target::vehicle },
{ "radiochannelincrease", command_target::vehicle },
{ "radiochanneldecrease", command_target::vehicle },
{ "radiostopsend", command_target::vehicle },
{ "radiostoptest", command_target::vehicle },
// TBD, TODO: make cab change controls entity-centric
{ "cabchangeforward", command_target::vehicle },

View File

@@ -71,6 +71,7 @@ enum class user_command {
radiotoggle,
radiochannelincrease,
radiochanneldecrease,
radiostopsend,
radiostoptest,
cabchangeforward,
cabchangebackward,

View File

@@ -42,7 +42,7 @@ keyboard_input::recall_bindings() {
{ ";", GLFW_KEY_SEMICOLON }, { "'", GLFW_KEY_APOSTROPHE }, { "enter", GLFW_KEY_ENTER },
{ ",", GLFW_KEY_COMMA }, { ".", GLFW_KEY_PERIOD }, { "/", GLFW_KEY_SLASH },
{ "space", GLFW_KEY_SPACE },
{ "insert", GLFW_KEY_INSERT },{ "delete", GLFW_KEY_DELETE }, { "home", GLFW_KEY_HOME }, { "end", GLFW_KEY_END },
{ "pause", GLFW_KEY_PAUSE }, { "insert", GLFW_KEY_INSERT }, { "delete", GLFW_KEY_DELETE }, { "home", GLFW_KEY_HOME }, { "end", GLFW_KEY_END },
// numpad block
{ "num_/", GLFW_KEY_KP_DIVIDE }, { "num_*", GLFW_KEY_KP_MULTIPLY }, { "num_-", GLFW_KEY_KP_SUBTRACT },
{ "num_7", GLFW_KEY_KP_7 }, { "num_8", GLFW_KEY_KP_8 }, { "num_9", GLFW_KEY_KP_9 }, { "num_+", GLFW_KEY_KP_ADD },
@@ -281,6 +281,8 @@ keyboard_input::default_bindings() {
{ GLFW_KEY_R | keymodifier::shift },
// radiochanneldecrease
{ GLFW_KEY_R },
// radiostopsend
{ GLFW_KEY_PAUSE | keymodifier::shift | keymodifier::control },
// radiostoptest
{ GLFW_KEY_R | keymodifier::shift | keymodifier::control },
// cabchangeforward

View File

@@ -57,19 +57,27 @@ opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool c
; // all work is done in the header
}
}
else if( key == Global::Weather ) {
// weather textures override generic and seasonal textures
while( true == deserialize_mapping( blockparser, 2, Loadnow ) ) {
; // all work is done in the header
}
}
}
else if( key == "texture1:" ) {
// TODO: full-fledged priority system
if( ( texture1 == null_handle )
|| ( Priority > 0 ) ) {
|| ( Priority > priority1 ) ) {
texture1 = GfxRenderer.Fetch_Texture( path + value, Loadnow );
priority1 = Priority;
}
}
else if( key == "texture2:" ) {
// TODO: full-fledged priority system
if( ( texture2 == null_handle )
|| ( Priority > 0 ) ) {
|| ( Priority > priority2 ) ) {
texture2 = GfxRenderer.Fetch_Texture( path + value, Loadnow );
priority2 = Priority;
}
}

View File

@@ -24,13 +24,20 @@ struct opengl_material {
bool has_alpha { false }; // alpha state, calculated from presence of alpha in texture1
std::string name;
// methods:
// methods
bool
deserialize( cParser &Input, bool const Loadnow );
private:
// methods
// imports member data pair from the config file, overriding existing parameter values of lower priority
bool
deserialize_mapping( cParser &Input, int const Priority, bool const Loadnow );
// members
int priority1 { -1 }; // priority of last loaded primary texture
int priority2 { -1 }; // priority of last loaded secondary texture
};
class material_manager {

View File

@@ -25,6 +25,10 @@ mouse_input::init() {
DWORD systemkeyboardspeed;
::SystemParametersInfo( SPI_GETKEYBOARDSPEED, 0, &systemkeyboardspeed, 0 );
m_updaterate = interpolate( 0.5, 0.04, systemkeyboardspeed / 31.0 );
DWORD systemkeyboarddelay;
::SystemParametersInfo( SPI_GETKEYBOARDDELAY, 0, &systemkeyboarddelay, 0 );
m_updatedelay = interpolate( 0.25, 1.0, systemkeyboarddelay / 3.0 );
#endif
return true;
}
@@ -139,7 +143,7 @@ mouse_input::button( int const Button, int const Action ) {
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
// TODO: pass correct entity id once the missing systems are in place
m_relay.post( mousecommand, 0, 0, Action, 0 );
m_updateaccumulator = 0.0; // prevent potential command repeat right after issuing one
m_updateaccumulator = -0.25; // prevent potential command repeat right after issuing one
switch( mousecommand ) {
case user_command::mastercontrollerincrease:
@@ -183,23 +187,21 @@ mouse_input::poll() {
updaterate /= std::max( 0.15, 2.0 * glm::length( m_cursorposition - m_commandstartcursor ) / std::max( 1, Global::iWindowHeight ) );
}
if( m_updateaccumulator < updaterate ) {
// too early for any work
return;
}
m_updateaccumulator -= updaterate;
while( m_updateaccumulator > updaterate ) {
if( m_mousecommandleft != user_command::none ) {
// NOTE: basic keyboard controls don't have any parameters
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
// TODO: pass correct entity id once the missing systems are in place
m_relay.post( m_mousecommandleft, 0, 0, GLFW_REPEAT, 0 );
}
if( m_mousecommandright != user_command::none ) {
// NOTE: basic keyboard controls don't have any parameters
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
// TODO: pass correct entity id once the missing systems are in place
m_relay.post( m_mousecommandright, 0, 0, GLFW_REPEAT, 0 );
if( m_mousecommandleft != user_command::none ) {
// NOTE: basic keyboard controls don't have any parameters
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
// TODO: pass correct entity id once the missing systems are in place
m_relay.post( m_mousecommandleft, 0, 0, GLFW_REPEAT, 0 );
}
if( m_mousecommandright != user_command::none ) {
// NOTE: basic keyboard controls don't have any parameters
// as we haven't yet implemented either item id system or multiplayer, the 'local' controlled vehicle and entity have temporary ids of 0
// TODO: pass correct entity id once the missing systems are in place
m_relay.post( m_mousecommandright, 0, 0, GLFW_REPEAT, 0 );
}
m_updateaccumulator -= updaterate;
}
}
@@ -351,6 +353,12 @@ mouse_input::default_bindings() {
{ "radiochannelnext_sw:", {
user_command::radiochannelincrease,
user_command::none } },
{ "radiostop_sw:", {
user_command::radiostopsend,
user_command::none } },
{ "radiotest_sw:", {
user_command::radiostoptest,
user_command::none } },
{ "pantfront_sw:", {
user_command::pantographtogglefront,
user_command::none } },

View File

@@ -48,6 +48,7 @@ private:
user_command m_mousecommandleft { user_command::none }; // last if any command issued with left mouse button
user_command m_mousecommandright { user_command::none }; // last if any command issued with right mouse button
double m_updaterate { 0.075 };
double m_updatedelay { 0.25 };
double m_updateaccumulator { 0.0 };
bool m_pickmodepanning { false }; // indicates mouse is in view panning mode
glm::dvec2 m_cursorposition; // stored last cursor position, used for panning

View File

@@ -1460,8 +1460,7 @@ opengl_renderer::Render( world_environment *Environment ) {
Render( Environment->m_clouds.mdCloud, nullptr, 100.0 );
Render_Alpha( Environment->m_clouds.mdCloud, nullptr, 100.0 );
// post-render cleanup
GLfloat noambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, noambient );
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, glm::value_ptr( colors::none ) );
::glEnable( GL_LIGHT0 ); // other lights will be enabled during lights update
::glDisable( GL_LIGHTING );
}

View File

@@ -66,6 +66,8 @@ static std::unordered_map<std::string, std::string> m_cabcontrols = {
{ "radiochannel_sw:", "radio channel" },
{ "radiochannelprev_sw:", "radio channel" },
{ "radiochannelnext_sw:", "radio channel" },
{ "radiotest_sw:", "radiostop test" },
{ "radiostop_sw:", "radiostop" },
{ "pantfront_sw:", "pantograph A" },
{ "pantrear_sw:", "pantograph B" },
{ "pantfrontoff_sw:", "pantograph A" },

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 18
#define VERSION_MINOR 122
#define VERSION_MINOR 124
#define VERSION_REVISION 0