mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-24 07:39:17 +02:00
Merge branch 'tmj-dev' into milek-dev
This commit is contained in:
13
Driver.cpp
13
Driver.cpp
@@ -3514,7 +3514,7 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
|
|||||||
if (NewValue1 > 0)
|
if (NewValue1 > 0)
|
||||||
{
|
{
|
||||||
fWarningDuration = NewValue1; // czas trąbienia
|
fWarningDuration = NewValue1; // czas trąbienia
|
||||||
mvOccupied->WarningSignal = (NewValue2 > 1) ? 2 : 1; // wysokość tonu
|
mvOccupied->WarningSignal = NewValue2; // horn combination flag
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (NewCommand == "Radio_channel")
|
else if (NewCommand == "Radio_channel")
|
||||||
@@ -5881,22 +5881,27 @@ void TController::DirectionForward(bool forward)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Mtable::TTrainParameters const *
|
||||||
|
TController::TrainTimetable() const {
|
||||||
|
return TrainParams;
|
||||||
|
}
|
||||||
|
|
||||||
std::string TController::Relation()
|
std::string TController::Relation()
|
||||||
{ // zwraca relację pociągu
|
{ // zwraca relację pociągu
|
||||||
return TrainParams->ShowRelation();
|
return TrainParams->ShowRelation();
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string TController::TrainName()
|
std::string TController::TrainName() const
|
||||||
{ // zwraca numer pociągu
|
{ // zwraca numer pociągu
|
||||||
return TrainParams->TrainName;
|
return TrainParams->TrainName;
|
||||||
};
|
};
|
||||||
|
|
||||||
int TController::StationCount()
|
int TController::StationCount() const
|
||||||
{ // zwraca ilość stacji (miejsc zatrzymania)
|
{ // zwraca ilość stacji (miejsc zatrzymania)
|
||||||
return TrainParams->StationCount;
|
return TrainParams->StationCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
int TController::StationIndex()
|
int TController::StationIndex() const
|
||||||
{ // zwraca indeks aktualnej stacji (miejsca zatrzymania)
|
{ // zwraca indeks aktualnej stacji (miejsca zatrzymania)
|
||||||
return TrainParams->StationIndex;
|
return TrainParams->StationIndex;
|
||||||
};
|
};
|
||||||
|
|||||||
11
Driver.h
11
Driver.h
@@ -314,8 +314,6 @@ private:
|
|||||||
void AutoRewident(); // ustawia hamulce w składzie
|
void AutoRewident(); // ustawia hamulce w składzie
|
||||||
double ESMVelocity(bool Main);
|
double ESMVelocity(bool Main);
|
||||||
public:
|
public:
|
||||||
Mtable::TTrainParameters *Timetable() {
|
|
||||||
return TrainParams; };
|
|
||||||
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation, TStopReason reason = stopComm);
|
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation, TStopReason reason = stopComm);
|
||||||
bool PutCommand( std::string NewCommand, double NewValue1, double NewValue2, glm::dvec3 const *NewLocation, TStopReason reason = stopComm );
|
bool PutCommand( std::string NewCommand, double NewValue1, double NewValue2, glm::dvec3 const *NewLocation, TStopReason reason = stopComm );
|
||||||
void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę
|
void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę
|
||||||
@@ -385,13 +383,14 @@ private:
|
|||||||
void PhysicsLog();
|
void PhysicsLog();
|
||||||
std::string StopReasonText();
|
std::string StopReasonText();
|
||||||
~TController();
|
~TController();
|
||||||
std::string NextStop();
|
|
||||||
void TakeControl(bool yes);
|
void TakeControl(bool yes);
|
||||||
|
Mtable::TTrainParameters const * TrainTimetable() const;
|
||||||
|
std::string TrainName() const;
|
||||||
std::string Relation();
|
std::string Relation();
|
||||||
std::string TrainName();
|
int StationCount() const;
|
||||||
int StationCount();
|
int StationIndex() const;
|
||||||
int StationIndex();
|
|
||||||
bool IsStop();
|
bool IsStop();
|
||||||
|
std::string NextStop();
|
||||||
inline
|
inline
|
||||||
bool Primary() const {
|
bool Primary() const {
|
||||||
return ( ( iDrivigFlags & movePrimary ) != 0 ); };
|
return ( ( iDrivigFlags & movePrimary ) != 0 ); };
|
||||||
|
|||||||
711
DynObj.cpp
711
DynObj.cpp
@@ -72,8 +72,7 @@ void TAnimPant::AKP_4E()
|
|||||||
};
|
};
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
int TAnim::TypeSet(int i, int fl)
|
int TAnim::TypeSet(int i, int fl)
|
||||||
{ // ustawienie typu animacji i zależnej od
|
{ // ustawienie typu animacji i zależnej od niego ilości animowanych submodeli
|
||||||
// niego ilości animowanych submodeli
|
|
||||||
fMaxDist = -1.0; // normalnie nie pokazywać
|
fMaxDist = -1.0; // normalnie nie pokazywać
|
||||||
switch (i)
|
switch (i)
|
||||||
{ // maska 0x000F: ile używa wskaźników na submodele (0 gdy jeden,
|
{ // maska 0x000F: ile używa wskaźników na submodele (0 gdy jeden,
|
||||||
@@ -106,16 +105,19 @@ int TAnim::TypeSet(int i, int fl)
|
|||||||
case 6:
|
case 6:
|
||||||
iFlags = 0x068;
|
iFlags = 0x068;
|
||||||
break; // 6-tłok i rozrząd - 8 submodeli
|
break; // 6-tłok i rozrząd - 8 submodeli
|
||||||
|
case 7:
|
||||||
|
iFlags = 0x070;
|
||||||
|
break; // doorstep
|
||||||
|
case 8:
|
||||||
|
iFlags = 0x080;
|
||||||
|
break; // mirror
|
||||||
default:
|
default:
|
||||||
iFlags = 0;
|
iFlags = 0;
|
||||||
}
|
}
|
||||||
yUpdate = nullptr;
|
yUpdate = nullptr;
|
||||||
return iFlags & 15; // ile wskaźników rezerwować dla danego typu animacji
|
return iFlags & 15; // ile wskaźników rezerwować dla danego typu animacji
|
||||||
};
|
};
|
||||||
TAnim::TAnim()
|
|
||||||
{ // potrzebne to w ogóle?
|
|
||||||
iFlags = -1; // nieznany typ - destruktor nic nie usuwa
|
|
||||||
};
|
|
||||||
TAnim::~TAnim()
|
TAnim::~TAnim()
|
||||||
{ // usuwanie animacji
|
{ // usuwanie animacji
|
||||||
switch (iFlags & 0xF0)
|
switch (iFlags & 0xF0)
|
||||||
@@ -126,13 +128,15 @@ TAnim::~TAnim()
|
|||||||
case 0x50: // 5-pantograf
|
case 0x50: // 5-pantograf
|
||||||
delete fParamPants;
|
delete fParamPants;
|
||||||
break;
|
break;
|
||||||
case 0x60: // 6-tłok i rozrząd
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
/*
|
||||||
void TAnim::Parovoz(){
|
void TAnim::Parovoz(){
|
||||||
// animowanie tłoka i rozrządu parowozu
|
// animowanie tłoka i rozrządu parowozu
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
TDynamicObject * TDynamicObject::FirstFind(int &coupler_nr, int cf)
|
TDynamicObject * TDynamicObject::FirstFind(int &coupler_nr, int cf)
|
||||||
{ // szukanie skrajnego połączonego pojazdu w pociagu
|
{ // szukanie skrajnego połączonego pojazdu w pociagu
|
||||||
@@ -402,11 +406,6 @@ void TDynamicObject::UpdateBoogie(TAnim *pAnim)
|
|||||||
|
|
||||||
void TDynamicObject::UpdateDoorTranslate(TAnim *pAnim)
|
void TDynamicObject::UpdateDoorTranslate(TAnim *pAnim)
|
||||||
{ // animacja drzwi - przesuw
|
{ // animacja drzwi - przesuw
|
||||||
// WriteLog("Dla drzwi nr:", i);
|
|
||||||
// WriteLog("Wspolczynnik", DoorSpeedFactor[i]);
|
|
||||||
// Ra: te współczynniki są bez sensu, bo modyfikują wektor przesunięcia
|
|
||||||
// w efekcie drzwi otwierane na zewnątrz będą odlatywac dowolnie daleko :)
|
|
||||||
// ograniczyłem zakres ruchu funkcją max
|
|
||||||
if (pAnim->smAnimated) {
|
if (pAnim->smAnimated) {
|
||||||
|
|
||||||
if( pAnim->iNumber & 1 ) {
|
if( pAnim->iNumber & 1 ) {
|
||||||
@@ -429,9 +428,7 @@ void TDynamicObject::UpdateDoorTranslate(TAnim *pAnim)
|
|||||||
void TDynamicObject::UpdateDoorRotate(TAnim *pAnim)
|
void TDynamicObject::UpdateDoorRotate(TAnim *pAnim)
|
||||||
{ // animacja drzwi - obrót
|
{ // animacja drzwi - obrót
|
||||||
if (pAnim->smAnimated)
|
if (pAnim->smAnimated)
|
||||||
{ // if (MoverParameters->DoorOpenMethod==2) //obrotowe
|
{
|
||||||
// albo dwójłomne (trzeba kombinowac
|
|
||||||
// submodelami i ShiftL=90,R=180)
|
|
||||||
if (pAnim->iNumber & 1)
|
if (pAnim->iNumber & 1)
|
||||||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), dDoorMoveR);
|
pAnim->smAnimated->SetRotate(float3(1, 0, 0), dDoorMoveR);
|
||||||
else
|
else
|
||||||
@@ -442,9 +439,7 @@ void TDynamicObject::UpdateDoorRotate(TAnim *pAnim)
|
|||||||
void TDynamicObject::UpdateDoorFold(TAnim *pAnim)
|
void TDynamicObject::UpdateDoorFold(TAnim *pAnim)
|
||||||
{ // animacja drzwi - obrót
|
{ // animacja drzwi - obrót
|
||||||
if (pAnim->smAnimated)
|
if (pAnim->smAnimated)
|
||||||
{ // if (MoverParameters->DoorOpenMethod==2) //obrotowe
|
{
|
||||||
// albo dwójłomne (trzeba kombinowac
|
|
||||||
// submodelami i ShiftL=90,R=180)
|
|
||||||
if (pAnim->iNumber & 1)
|
if (pAnim->iNumber & 1)
|
||||||
{
|
{
|
||||||
pAnim->smAnimated->SetRotate(float3(0, 0, 1), dDoorMoveR);
|
pAnim->smAnimated->SetRotate(float3(0, 0, 1), dDoorMoveR);
|
||||||
@@ -460,7 +455,6 @@ void TDynamicObject::UpdateDoorFold(TAnim *pAnim)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
pAnim->smAnimated->SetRotate(float3(0, 0, 1), dDoorMoveL);
|
pAnim->smAnimated->SetRotate(float3(0, 0, 1), dDoorMoveL);
|
||||||
// SubModel->SetRotate(float3(0,1,0),fValue*360.0);
|
|
||||||
TSubModel *sm = pAnim->smAnimated->ChildGet(); // skrzydło mniejsze
|
TSubModel *sm = pAnim->smAnimated->ChildGet(); // skrzydło mniejsze
|
||||||
if (sm)
|
if (sm)
|
||||||
{
|
{
|
||||||
@@ -473,6 +467,35 @@ void TDynamicObject::UpdateDoorFold(TAnim *pAnim)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void TDynamicObject::UpdateDoorPlug(TAnim *pAnim)
|
||||||
|
{ // animacja drzwi - odskokprzesuw
|
||||||
|
if (pAnim->smAnimated) {
|
||||||
|
|
||||||
|
if( pAnim->iNumber & 1 ) {
|
||||||
|
pAnim->smAnimated->SetTranslate(
|
||||||
|
Math3D::vector3 {
|
||||||
|
std::min(
|
||||||
|
dDoorMoveR * 2,
|
||||||
|
MoverParameters->DoorMaxPlugShift ),
|
||||||
|
0.0,
|
||||||
|
std::max(
|
||||||
|
0.0,
|
||||||
|
dDoorMoveR - MoverParameters->DoorMaxPlugShift * 0.5f ) } );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pAnim->smAnimated->SetTranslate(
|
||||||
|
Math3D::vector3 {
|
||||||
|
std::min(
|
||||||
|
dDoorMoveL * 2,
|
||||||
|
MoverParameters->DoorMaxPlugShift ),
|
||||||
|
0.0,
|
||||||
|
std::max(
|
||||||
|
0.0,
|
||||||
|
dDoorMoveL - MoverParameters->DoorMaxPlugShift * 0.5f ) } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TDynamicObject::UpdatePant(TAnim *pAnim)
|
void TDynamicObject::UpdatePant(TAnim *pAnim)
|
||||||
{ // animacja pantografu - 4 obracane ramiona, ślizg piąty
|
{ // animacja pantografu - 4 obracane ramiona, ślizg piąty
|
||||||
float a, b, c;
|
float a, b, c;
|
||||||
@@ -489,37 +512,66 @@ void TDynamicObject::UpdatePant(TAnim *pAnim)
|
|||||||
pAnim->smElement[3]->SetRotate(float3(-1, 0, 0), c);
|
pAnim->smElement[3]->SetRotate(float3(-1, 0, 0), c);
|
||||||
if (pAnim->smElement[4])
|
if (pAnim->smElement[4])
|
||||||
pAnim->smElement[4]->SetRotate(float3(-1, 0, 0), b); //ślizg
|
pAnim->smElement[4]->SetRotate(float3(-1, 0, 0), b); //ślizg
|
||||||
};
|
}
|
||||||
|
|
||||||
void TDynamicObject::UpdateDoorPlug(TAnim *pAnim)
|
// doorstep animation, shift
|
||||||
{ // animacja drzwi - odskokprzesuw
|
void TDynamicObject::UpdatePlatformTranslate( TAnim *pAnim ) {
|
||||||
if (pAnim->smAnimated) {
|
|
||||||
|
|
||||||
if( pAnim->iNumber & 1 ) {
|
if( pAnim->smAnimated == nullptr ) { return; }
|
||||||
pAnim->smAnimated->SetTranslate(
|
|
||||||
Math3D::vector3 {
|
if( pAnim->iNumber & 1 ) {
|
||||||
std::min(
|
pAnim->smAnimated->SetTranslate(
|
||||||
dDoorMoveR * 2,
|
Math3D::vector3{
|
||||||
MoverParameters->DoorMaxPlugShift ),
|
interpolate( 0.0, MoverParameters->PlatformMaxShift, dDoorstepMoveR ),
|
||||||
0.0,
|
0.0,
|
||||||
std::max(
|
0.0 } );
|
||||||
0.0,
|
|
||||||
dDoorMoveR - MoverParameters->DoorMaxPlugShift * 0.5 ) } );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pAnim->smAnimated->SetTranslate(
|
|
||||||
Math3D::vector3 {
|
|
||||||
std::min(
|
|
||||||
dDoorMoveL * 2,
|
|
||||||
MoverParameters->DoorMaxPlugShift ),
|
|
||||||
0.0,
|
|
||||||
std::max(
|
|
||||||
0.0,
|
|
||||||
dDoorMoveL - MoverParameters->DoorMaxPlugShift * 0.5f ) } );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
else {
|
||||||
|
pAnim->smAnimated->SetTranslate(
|
||||||
|
Math3D::vector3{
|
||||||
|
interpolate( 0.0, MoverParameters->PlatformMaxShift, dDoorstepMoveL ),
|
||||||
|
0.0,
|
||||||
|
0.0 } );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// doorstep animation, rotate
|
||||||
|
void TDynamicObject::UpdatePlatformRotate( TAnim *pAnim ) {
|
||||||
|
|
||||||
|
if( pAnim->smAnimated == nullptr ) { return; }
|
||||||
|
|
||||||
|
if( pAnim->iNumber & 1 )
|
||||||
|
pAnim->smAnimated->SetRotate(
|
||||||
|
float3( 0, 1, 0 ),
|
||||||
|
interpolate( 0.0, MoverParameters->PlatformMaxShift, dDoorstepMoveR ) );
|
||||||
|
else
|
||||||
|
pAnim->smAnimated->SetRotate(
|
||||||
|
float3( 0, 1, 0 ),
|
||||||
|
interpolate( 0.0, MoverParameters->PlatformMaxShift, dDoorstepMoveL ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// mirror animation, rotate
|
||||||
|
void TDynamicObject::UpdateMirror( TAnim *pAnim ) {
|
||||||
|
|
||||||
|
if( pAnim->smAnimated == nullptr ) { return; }
|
||||||
|
|
||||||
|
// only animate the mirror if it's located on the same end of the vehicle as the active cab
|
||||||
|
auto const isactive { (
|
||||||
|
MoverParameters->ActiveCab > 0 ? ( ( pAnim->iNumber >> 4 ) == side::front ? 1.0 : 0.0 ) :
|
||||||
|
MoverParameters->ActiveCab < 0 ? ( ( pAnim->iNumber >> 4 ) == side::rear ? 1.0 : 0.0 ) :
|
||||||
|
0.0 ) };
|
||||||
|
|
||||||
|
if( pAnim->iNumber & 1 )
|
||||||
|
pAnim->smAnimated->SetRotate(
|
||||||
|
float3( 0, 1, 0 ),
|
||||||
|
interpolate( 0.0, MoverParameters->MirrorMaxShift, dMirrorMoveR * isactive ) );
|
||||||
|
else
|
||||||
|
pAnim->smAnimated->SetRotate(
|
||||||
|
float3( 0, 1, 0 ),
|
||||||
|
interpolate( 0.0, MoverParameters->MirrorMaxShift, dMirrorMoveL * isactive ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void TDynamicObject::UpdateLeverDouble(TAnim *pAnim)
|
void TDynamicObject::UpdateLeverDouble(TAnim *pAnim)
|
||||||
{ // animacja gałki zależna od double
|
{ // animacja gałki zależna od double
|
||||||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fSpeed * *pAnim->fDoubleBase);
|
pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fSpeed * *pAnim->fDoubleBase);
|
||||||
@@ -539,7 +591,7 @@ void TDynamicObject::UpdateLeverEnum(TAnim *pAnim)
|
|||||||
// pAnim->fParam[0]; - dodać lepkość
|
// pAnim->fParam[0]; - dodać lepkość
|
||||||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fParam[*pAnim->iIntBase]);
|
pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fParam[*pAnim->iIntBase]);
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
// sets light levels for registered interior sections
|
// sets light levels for registered interior sections
|
||||||
void
|
void
|
||||||
TDynamicObject::toggle_lights() {
|
TDynamicObject::toggle_lights() {
|
||||||
@@ -588,10 +640,14 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
|||||||
|
|
||||||
if (ObjSqrDist < ( 400 * 400 ) ) // gdy bliżej niż 400m
|
if (ObjSqrDist < ( 400 * 400 ) ) // gdy bliżej niż 400m
|
||||||
{
|
{
|
||||||
for (int i = 0; i < iAnimations; ++i) // wykonanie kolejnych animacji
|
for( auto &animation : pAnimations ) {
|
||||||
if (ObjSqrDist < pAnimations[ i ].fMaxDist)
|
// wykonanie kolejnych animacji
|
||||||
if (pAnimations[ i ].yUpdate) // jeśli zdefiniowana funkcja
|
if( ( ObjSqrDist < animation.fMaxDist )
|
||||||
pAnimations[ i ].yUpdate( &pAnimations[ i ] ); // aktualizacja animacji (położenia submodeli
|
&& ( animation.yUpdate ) ) {
|
||||||
|
// jeśli zdefiniowana funkcja aktualizacja animacji (położenia submodeli
|
||||||
|
animation.yUpdate( &animation );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( ( mdModel != nullptr )
|
if( ( mdModel != nullptr )
|
||||||
&& ( ObjSqrDist < ( 50 * 50 ) ) ) {
|
&& ( ObjSqrDist < ( 50 * 50 ) ) ) {
|
||||||
@@ -1657,13 +1713,6 @@ TDynamicObject::TDynamicObject() {
|
|||||||
// w MMD)
|
// w MMD)
|
||||||
// ustawienie liczby modeli animowanych podczas konstruowania obiektu a nie na 0
|
// ustawienie liczby modeli animowanych podczas konstruowania obiektu a nie na 0
|
||||||
// prowadzi prosto do wysypów jeśli źle zdefiniowane mmd
|
// prowadzi prosto do wysypów jeśli źle zdefiniowane mmd
|
||||||
iAnimType[ANIM_WHEELS] = 0; // 0-osie (8)
|
|
||||||
iAnimType[ANIM_DOORS] = 0; // 1-drzwi (8)
|
|
||||||
iAnimType[ANIM_LEVERS] = 0; // 2-wahacze (4) - np. nogi konia
|
|
||||||
iAnimType[ANIM_BUFFERS] = 0; // 3-zderzaki (4)
|
|
||||||
iAnimType[ANIM_BOOGIES] = 0; // 4-wózki (2)
|
|
||||||
iAnimType[ANIM_PANTS] = 0; // 5-pantografy (2)
|
|
||||||
iAnimType[ANIM_STEAMS] = 0; // 6-tłoki (napęd parowozu)
|
|
||||||
iAnimations = 0; // na razie nie ma żadnego
|
iAnimations = 0; // na razie nie ma żadnego
|
||||||
pAnimated = NULL;
|
pAnimated = NULL;
|
||||||
fShade = 0.0; // standardowe oświetlenie na starcie
|
fShade = 0.0; // standardowe oświetlenie na starcie
|
||||||
@@ -1977,7 +2026,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
|||||||
}
|
}
|
||||||
if( true == setambient ) {
|
if( true == setambient ) {
|
||||||
// TODO: pull ambient temperature from environment data
|
// TODO: pull ambient temperature from environment data
|
||||||
MoverParameters->dizel_HeatSet( 15.f );
|
MoverParameters->dizel_HeatSet( Global.AirTemperature );
|
||||||
}
|
}
|
||||||
} // temperature
|
} // temperature
|
||||||
/* else if (ActPar.substr(0, 1) == "") // tu mozna wpisac inny prefiks i inne rzeczy
|
/* else if (ActPar.substr(0, 1) == "") // tu mozna wpisac inny prefiks i inne rzeczy
|
||||||
@@ -3588,21 +3637,85 @@ bool TDynamicObject::Update(double dt, double dt1)
|
|||||||
&& ( true == MoverParameters->DoorLeftOpened ) ) {
|
&& ( true == MoverParameters->DoorLeftOpened ) ) {
|
||||||
dDoorMoveL += dt1 * MoverParameters->DoorOpenSpeed;
|
dDoorMoveL += dt1 * MoverParameters->DoorOpenSpeed;
|
||||||
dDoorMoveL = std::min( dDoorMoveL, MoverParameters->DoorMaxShiftL );
|
dDoorMoveL = std::min( dDoorMoveL, MoverParameters->DoorMaxShiftL );
|
||||||
|
DoorDelayL = 0.f;
|
||||||
}
|
}
|
||||||
if( ( dDoorMoveL > 0 )
|
if( ( dDoorMoveL > 0.0 )
|
||||||
&& ( false == MoverParameters->DoorLeftOpened ) ) {
|
&& ( false == MoverParameters->DoorLeftOpened ) ) {
|
||||||
dDoorMoveL -= dt1 * MoverParameters->DoorCloseSpeed;
|
DoorDelayL += dt1;
|
||||||
dDoorMoveL = std::max( dDoorMoveL, 0.0 );
|
if( DoorDelayL > MoverParameters->DoorCloseDelay ) {
|
||||||
|
dDoorMoveL -= dt1 * MoverParameters->DoorCloseSpeed;
|
||||||
|
dDoorMoveL = std::max( dDoorMoveL, 0.0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( ( dDoorMoveR < MoverParameters->DoorMaxShiftR )
|
if( ( dDoorMoveR < MoverParameters->DoorMaxShiftR )
|
||||||
&& ( true == MoverParameters->DoorRightOpened ) ) {
|
&& ( true == MoverParameters->DoorRightOpened ) ) {
|
||||||
dDoorMoveR += dt1 * MoverParameters->DoorOpenSpeed;
|
dDoorMoveR += dt1 * MoverParameters->DoorOpenSpeed;
|
||||||
dDoorMoveR = std::min( dDoorMoveR, MoverParameters->DoorMaxShiftR );
|
dDoorMoveR = std::min( dDoorMoveR, MoverParameters->DoorMaxShiftR );
|
||||||
}
|
DoorDelayR = 0.f;
|
||||||
if( ( dDoorMoveR > 0 )
|
}
|
||||||
|
if( ( dDoorMoveR > 0.0 )
|
||||||
&& ( false == MoverParameters->DoorRightOpened ) ) {
|
&& ( false == MoverParameters->DoorRightOpened ) ) {
|
||||||
dDoorMoveR -= dt1 * MoverParameters->DoorCloseSpeed;
|
DoorDelayR += dt1;
|
||||||
dDoorMoveR = std::max( dDoorMoveR, 0.0 );
|
if( DoorDelayR > MoverParameters->DoorCloseDelay ) {
|
||||||
|
dDoorMoveR -= dt1 * MoverParameters->DoorCloseSpeed;
|
||||||
|
dDoorMoveR = std::max( dDoorMoveR, 0.0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// doorsteps
|
||||||
|
if( ( dDoorstepMoveL < 1.0 )
|
||||||
|
&& ( true == MoverParameters->DoorLeftOpened ) ) {
|
||||||
|
dDoorstepMoveL = std::min(
|
||||||
|
1.0,
|
||||||
|
dDoorstepMoveL + MoverParameters->PlatformSpeed * dt1 );
|
||||||
|
}
|
||||||
|
if( ( dDoorstepMoveL > 0.0 )
|
||||||
|
&& ( false == MoverParameters->DoorLeftOpened )
|
||||||
|
&& ( DoorDelayL > MoverParameters->DoorCloseDelay ) ) {
|
||||||
|
dDoorstepMoveL = std::max(
|
||||||
|
0.0,
|
||||||
|
dDoorstepMoveL - MoverParameters->PlatformSpeed * dt1 );
|
||||||
|
}
|
||||||
|
if( ( dDoorstepMoveR < 1.0 )
|
||||||
|
&& ( true == MoverParameters->DoorRightOpened ) ) {
|
||||||
|
dDoorstepMoveR = std::min(
|
||||||
|
1.0,
|
||||||
|
dDoorstepMoveR + MoverParameters->PlatformSpeed * dt1 );
|
||||||
|
}
|
||||||
|
if( ( dDoorstepMoveR > 0.0 )
|
||||||
|
&& ( false == MoverParameters->DoorRightOpened )
|
||||||
|
&& ( DoorDelayR > MoverParameters->DoorCloseDelay ) ) {
|
||||||
|
dDoorstepMoveR = std::max(
|
||||||
|
0.0,
|
||||||
|
dDoorstepMoveR - MoverParameters->PlatformSpeed * dt1 );
|
||||||
|
}
|
||||||
|
// mirrors
|
||||||
|
if( MoverParameters->Vel > 5.0 ) {
|
||||||
|
// automatically fold mirrors when above velocity threshold
|
||||||
|
if( dMirrorMoveL > 0.0 ) {
|
||||||
|
dMirrorMoveL = std::max(
|
||||||
|
0.0,
|
||||||
|
dMirrorMoveL - 1.0 * dt1 );
|
||||||
|
}
|
||||||
|
if( dMirrorMoveR > 0.0 ) {
|
||||||
|
dMirrorMoveR = std::max(
|
||||||
|
0.0,
|
||||||
|
dMirrorMoveR - 1.0 * dt1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// unfold mirror on the side with open doors, if not moving too fast
|
||||||
|
if( ( dMirrorMoveL < 1.0 )
|
||||||
|
&& ( true == MoverParameters->DoorLeftOpened ) ) {
|
||||||
|
dMirrorMoveL = std::min(
|
||||||
|
1.0,
|
||||||
|
dMirrorMoveL + 1.0 * dt1 );
|
||||||
|
}
|
||||||
|
if( ( dMirrorMoveR < 1.0 )
|
||||||
|
&& ( true == MoverParameters->DoorRightOpened ) ) {
|
||||||
|
dMirrorMoveR = std::min(
|
||||||
|
1.0,
|
||||||
|
dMirrorMoveR + 1.0 * dt1 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// compartment lights
|
// compartment lights
|
||||||
@@ -3770,14 +3883,40 @@ void TDynamicObject::RenderSounds() {
|
|||||||
|
|
||||||
|
|
||||||
// brake system and braking sounds:
|
// brake system and braking sounds:
|
||||||
|
|
||||||
|
// brake cylinder piston
|
||||||
|
auto const brakepressureratio { std::max( 0.0, MoverParameters->BrakePress ) / std::max( 1.0, MoverParameters->MaxBrakePress[ 3 ] ) };
|
||||||
|
if( m_lastbrakepressure != -1.f ) {
|
||||||
|
auto const quantizedratio { static_cast<int>( 15 * brakepressureratio ) };
|
||||||
|
auto const lastbrakepressureratio { std::max( 0.f, m_lastbrakepressure ) / std::max( 1.0, MoverParameters->MaxBrakePress[ 3 ] ) };
|
||||||
|
auto const quantizedratiochange { quantizedratio - static_cast<int>( 15 * lastbrakepressureratio ) };
|
||||||
|
if( quantizedratiochange > 0 ) {
|
||||||
|
m_brakecylinderpistonadvance
|
||||||
|
.pitch(
|
||||||
|
true == m_brakecylinderpistonadvance.is_combined() ?
|
||||||
|
quantizedratio * 0.01f :
|
||||||
|
m_brakecylinderpistonadvance.m_frequencyoffset + m_brakecylinderpistonadvance.m_frequencyfactor * 1.f )
|
||||||
|
.play();
|
||||||
|
}
|
||||||
|
else if( quantizedratiochange < 0 ) {
|
||||||
|
m_brakecylinderpistonrecede
|
||||||
|
.pitch(
|
||||||
|
true == m_brakecylinderpistonrecede.is_combined() ?
|
||||||
|
quantizedratio * 0.01f :
|
||||||
|
m_brakecylinderpistonrecede.m_frequencyoffset + m_brakecylinderpistonrecede.m_frequencyfactor * 1.f )
|
||||||
|
.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// air release
|
||||||
if( m_lastbrakepressure != -1.f ) {
|
if( m_lastbrakepressure != -1.f ) {
|
||||||
// calculate rate of pressure drop in brake cylinder, once it's been initialized
|
// 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_brakepressurechange = interpolate<float>( m_brakepressurechange, brakepressuredifference / dt, 0.005f );
|
||||||
}
|
}
|
||||||
m_lastbrakepressure = MoverParameters->BrakePress;
|
m_lastbrakepressure = MoverParameters->BrakePress;
|
||||||
// ensure some basic level of volume and scale it up depending on pressure in the cylinder; scale this by the leak rate
|
// ensure some basic level of volume and scale it up depending on pressure in the cylinder; scale this by the air release rate
|
||||||
volume = 20 * m_brakepressurechange * ( 0.25 + 0.75 * ( std::max( 0.0, MoverParameters->BrakePress ) / std::max( 1.0, MoverParameters->MaxBrakePress[ 3 ] ) ) );
|
volume = 20 * m_brakepressurechange * ( 0.25 + 0.75 * brakepressureratio );
|
||||||
if( volume > 0.075f ) {
|
if( volume > 0.075f ) {
|
||||||
rsUnbrake
|
rsUnbrake
|
||||||
.gain( volume )
|
.gain( volume )
|
||||||
@@ -3805,6 +3944,7 @@ void TDynamicObject::RenderSounds() {
|
|||||||
sReleaser.stop();
|
sReleaser.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// slipping wheels
|
||||||
if( MoverParameters->SlippingWheels ) {
|
if( MoverParameters->SlippingWheels ) {
|
||||||
|
|
||||||
if( ( MoverParameters->UnitBrakeForce > 100.0 )
|
if( ( MoverParameters->UnitBrakeForce > 100.0 )
|
||||||
@@ -3828,6 +3968,7 @@ void TDynamicObject::RenderSounds() {
|
|||||||
sSand.stop();
|
sSand.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// brakes
|
||||||
auto brakeforceratio{ 0.0 };
|
auto brakeforceratio{ 0.0 };
|
||||||
if( //( false == mvOccupied->SlippingWheels ) &&
|
if( //( false == mvOccupied->SlippingWheels ) &&
|
||||||
( MoverParameters->UnitBrakeForce > 10.0 )
|
( MoverParameters->UnitBrakeForce > 10.0 )
|
||||||
@@ -3888,7 +4029,14 @@ void TDynamicObject::RenderSounds() {
|
|||||||
}
|
}
|
||||||
// NBMX sygnal odjazdu
|
// NBMX sygnal odjazdu
|
||||||
if( MoverParameters->DoorClosureWarning ) {
|
if( MoverParameters->DoorClosureWarning ) {
|
||||||
if( MoverParameters->DepartureSignal ) {
|
if( ( MoverParameters->DepartureSignal )
|
||||||
|
/*
|
||||||
|
|| ( ( MoverParameters->DoorCloseCtrl = control::autonomous )
|
||||||
|
&& ( ( ( false == MoverParameters->DoorLeftOpened ) && ( dDoorMoveL > 0.0 ) )
|
||||||
|
|| ( ( false == MoverParameters->DoorRightOpened ) && ( dDoorMoveR > 0.0 ) ) ) )
|
||||||
|
*/
|
||||||
|
) {
|
||||||
|
// for the autonomous doors play the warning automatically whenever a door is closing
|
||||||
// MC: pod warunkiem ze jest zdefiniowane w chk
|
// MC: pod warunkiem ze jest zdefiniowane w chk
|
||||||
sDepartureSignal.play( sound_flags::exclusive | sound_flags::looping );
|
sDepartureSignal.play( sound_flags::exclusive | sound_flags::looping );
|
||||||
}
|
}
|
||||||
@@ -3897,47 +4045,96 @@ void TDynamicObject::RenderSounds() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// NBMX Obsluga drzwi, MC: zuniwersalnione
|
// NBMX Obsluga drzwi, MC: zuniwersalnione
|
||||||
if( ( true == MoverParameters->DoorLeftOpened )
|
if( true == MoverParameters->DoorLeftOpened ) {
|
||||||
&& ( dDoorMoveL < MoverParameters->DoorMaxShiftL ) ) {
|
// open left door
|
||||||
|
// door sounds
|
||||||
for( auto &door : m_doorsounds ) {
|
if( dDoorMoveL < MoverParameters->DoorMaxShiftL ) {
|
||||||
if( door.rsDoorClose.offset().x > 0.f ) {
|
for( auto &door : m_doorsounds ) {
|
||||||
// determine left side doors from their offset
|
if( door.rsDoorClose.offset().x > 0.f ) {
|
||||||
door.rsDoorOpen.play( sound_flags::exclusive );
|
// determine left side doors from their offset
|
||||||
door.rsDoorClose.stop();
|
door.rsDoorOpen.play( sound_flags::exclusive );
|
||||||
|
door.rsDoorClose.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// doorstep sounds
|
||||||
|
if( dDoorstepMoveL < 1.0 ) {
|
||||||
|
for( auto &door : m_doorsounds ) {
|
||||||
|
if( door.step_close.offset().x > 0.f ) {
|
||||||
|
door.step_open.play( sound_flags::exclusive );
|
||||||
|
door.step_close.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( ( false == MoverParameters->DoorLeftOpened )
|
if( false == MoverParameters->DoorLeftOpened ) {
|
||||||
&& ( dDoorMoveL > 0.01 ) ) {
|
// close left door
|
||||||
|
// door sounds can start playing before the door begins moving
|
||||||
for( auto &door : m_doorsounds ) {
|
if( dDoorMoveL > 0.0 ) {
|
||||||
if( door.rsDoorClose.offset().x > 0.f ) {
|
for( auto &door : m_doorsounds ) {
|
||||||
// determine left side doors from their offset
|
if( door.rsDoorClose.offset().x > 0.f ) {
|
||||||
door.rsDoorClose.play( sound_flags::exclusive );
|
// determine left side doors from their offset
|
||||||
door.rsDoorOpen.stop();
|
door.rsDoorClose.play( sound_flags::exclusive );
|
||||||
|
door.rsDoorOpen.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// doorstep sounds are played only when the doorstep is moving
|
||||||
|
if( ( dDoorstepMoveL > 0.0 )
|
||||||
|
&& ( dDoorstepMoveL < 1.0 ) ) {
|
||||||
|
for( auto &door : m_doorsounds ) {
|
||||||
|
if( door.step_close.offset().x > 0.f ) {
|
||||||
|
// determine left side doors from their offset
|
||||||
|
door.step_close.play( sound_flags::exclusive );
|
||||||
|
door.step_open.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( ( true == MoverParameters->DoorRightOpened )
|
|
||||||
&& ( dDoorMoveR < MoverParameters->DoorMaxShiftR ) ) {
|
|
||||||
|
|
||||||
for( auto &door : m_doorsounds ) {
|
if( true == MoverParameters->DoorRightOpened ) {
|
||||||
if( door.rsDoorClose.offset().x < 0.f ) {
|
// open right door
|
||||||
// determine left side doors from their offset
|
// door sounds
|
||||||
door.rsDoorOpen.play( sound_flags::exclusive );
|
if( dDoorMoveR < MoverParameters->DoorMaxShiftR ) {
|
||||||
door.rsDoorClose.stop();
|
for( auto &door : m_doorsounds ) {
|
||||||
|
if( door.rsDoorClose.offset().x < 0.f ) {
|
||||||
|
// determine right side doors from their offset
|
||||||
|
door.rsDoorOpen.play( sound_flags::exclusive );
|
||||||
|
door.rsDoorClose.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// doorstep sounds
|
||||||
|
if( dDoorstepMoveR < 1.0 ) {
|
||||||
|
for( auto &door : m_doorsounds ) {
|
||||||
|
if( door.step_close.offset().x < 0.f ) {
|
||||||
|
door.step_open.play( sound_flags::exclusive );
|
||||||
|
door.step_close.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( ( false == MoverParameters->DoorRightOpened )
|
if( false == MoverParameters->DoorRightOpened ) {
|
||||||
&& ( dDoorMoveR > 0.01 ) ) {
|
// close right door
|
||||||
|
// door sounds can start playing before the door begins moving
|
||||||
for( auto &door : m_doorsounds ) {
|
if( dDoorMoveR > 0.0 ) {
|
||||||
if( door.rsDoorClose.offset().x < 0.f ) {
|
for( auto &door : m_doorsounds ) {
|
||||||
// determine left side doors from their offset
|
if( door.rsDoorClose.offset().x < 0.f ) {
|
||||||
door.rsDoorClose.play( sound_flags::exclusive );
|
// determine left side doors from their offset
|
||||||
door.rsDoorOpen.stop();
|
door.rsDoorClose.play( sound_flags::exclusive );
|
||||||
|
door.rsDoorOpen.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// doorstep sounds are played only when the doorstep is moving
|
||||||
|
if( ( dDoorstepMoveR > 0.0 )
|
||||||
|
&& ( dDoorstepMoveR < 1.0 ) ) {
|
||||||
|
for( auto &door : m_doorsounds ) {
|
||||||
|
if( door.step_close.offset().x < 0.f ) {
|
||||||
|
// determine left side doors from their offset
|
||||||
|
door.step_close.play( sound_flags::exclusive );
|
||||||
|
door.step_open.stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3954,6 +4151,12 @@ void TDynamicObject::RenderSounds() {
|
|||||||
else {
|
else {
|
||||||
sHorn2.stop();
|
sHorn2.stop();
|
||||||
}
|
}
|
||||||
|
if( TestFlag( MoverParameters->WarningSignal, 4 ) ) {
|
||||||
|
sHorn3.play( sound_flags::exclusive | sound_flags::looping );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sHorn3.stop();
|
||||||
|
}
|
||||||
// szum w czasie jazdy
|
// szum w czasie jazdy
|
||||||
if( ( GetVelocity() > 0.5 )
|
if( ( GetVelocity() > 0.5 )
|
||||||
&& ( false == m_bogiesounds.empty() )
|
&& ( false == m_bogiesounds.empty() )
|
||||||
@@ -4340,64 +4543,39 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
{ // kolejne liczby to ilość animacj, -1 to znacznik końca
|
{ // kolejne liczby to ilość animacj, -1 to znacznik końca
|
||||||
parser.getTokens( 1, false );
|
parser.getTokens( 1, false );
|
||||||
parser >> ile; // ilość danego typu animacji
|
parser >> ile; // ilość danego typu animacji
|
||||||
// if (co==ANIM_PANTS)
|
if (ile >= 0)
|
||||||
// if (!Global.bLoadTraction)
|
{
|
||||||
// if (!DebugModeFlag) //w debugmode pantografy mają "niby działać"
|
iAnimType[co] = ile; // zapamiętanie
|
||||||
// ile=0; //wyłączenie animacji pantografów
|
iAnimations += ile; // ogólna ilość animacji
|
||||||
if (co < ANIM_TYPES)
|
}
|
||||||
if (ile >= 0)
|
else {
|
||||||
{
|
iAnimType[co] = 0;
|
||||||
iAnimType[co] = ile; // zapamiętanie
|
}
|
||||||
iAnimations += ile; // ogólna ilość animacji
|
|
||||||
}
|
|
||||||
++co;
|
++co;
|
||||||
} while (ile >= 0); //-1 to znacznik końca
|
} while ( (ile >= 0) && (co < ANIM_TYPES) ); //-1 to znacznik końca
|
||||||
|
|
||||||
while( co < ANIM_TYPES ) {
|
pAnimations.resize( iAnimations );
|
||||||
iAnimType[ co++ ] = 0; // zerowanie pozostałych
|
int i, j, k = 0, sm = 0;
|
||||||
}
|
for (j = 0; j < ANIM_TYPES; ++j)
|
||||||
parser.getTokens(); parser >> token; // NOTE: should this be here? seems at best superfluous
|
for (i = 0; i < iAnimType[j]; ++i)
|
||||||
}
|
{
|
||||||
// WriteLog("Total animations: "+AnsiString(iAnimations));
|
if (j == ANIM_PANTS) // zliczamy poprzednie animacje
|
||||||
}
|
if (!pants)
|
||||||
|
if (iAnimType[ANIM_PANTS]) // o ile jakieś pantografy są (a domyślnie są)
|
||||||
if( true == pAnimations.empty() ) {
|
pants = &pAnimations[k]; // zapamiętanie na potrzeby wyszukania submodeli
|
||||||
// Ra: tworzenie tabeli animacji, jeśli jeszcze nie było
|
pAnimations[k].iShift = sm; // przesunięcie do przydzielenia wskaźnika
|
||||||
/*
|
sm += pAnimations[k++].TypeSet(j); // ustawienie typu animacji i zliczanie tablicowanych submodeli
|
||||||
// disabled as default animation amounts are no longer supported
|
}
|
||||||
if( !iAnimations ) {
|
if (sm) // o ile są bardziej złożone animacje
|
||||||
// jeśli nie podano jawnie, ile ma być animacji
|
|
||||||
iAnimations = 28; // tyle było kiedyś w każdym pojeździe (2 wiązary wypadły)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
/* //pojazd może mieć pantograf do innych celów niż napęd
|
|
||||||
if (MoverParameters->EnginePowerSource.SourceType!=CurrentCollector)
|
|
||||||
{//nie będzie pantografów, to się trochę uprości
|
|
||||||
iAnimations-=iAnimType[ANIM_PANTS]; //domyślnie były 2 pantografy
|
|
||||||
iAnimType[ANIM_PANTS]=0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
pAnimations.resize( iAnimations );
|
|
||||||
int i, j, k = 0, sm = 0;
|
|
||||||
for (j = 0; j < ANIM_TYPES; ++j)
|
|
||||||
for (i = 0; i < iAnimType[j]; ++i)
|
|
||||||
{
|
{
|
||||||
if (j == ANIM_PANTS) // zliczamy poprzednie animacje
|
pAnimated = new TSubModel *[sm]; // tabela na animowane submodele
|
||||||
if (!pants)
|
for (k = 0; k < iAnimations; ++k)
|
||||||
if (iAnimType[ANIM_PANTS]) // o ile jakieś pantografy są (a domyślnie są)
|
pAnimations[k].smElement = pAnimated + pAnimations[k].iShift; // przydzielenie wskaźnika do tabelki
|
||||||
pants = &pAnimations[k]; // zapamiętanie na potrzeby wyszukania submodeli
|
|
||||||
pAnimations[k].iShift = sm; // przesunięcie do przydzielenia wskaźnika
|
|
||||||
sm += pAnimations[k++].TypeSet(j); // ustawienie typu animacji i zliczanie tablicowanych submodeli
|
|
||||||
}
|
}
|
||||||
if (sm) // o ile są bardziej złożone animacje
|
|
||||||
{
|
|
||||||
pAnimated = new TSubModel *[sm]; // tabela na animowane submodele
|
|
||||||
for (k = 0; k < iAnimations; ++k)
|
|
||||||
pAnimations[k].smElement = pAnimated + pAnimations[k].iShift; // przydzielenie wskaźnika do tabelki
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(token == "lowpolyinterior:") {
|
else if(token == "lowpolyinterior:") {
|
||||||
// ABu: wnetrze lowpoly
|
// ABu: wnetrze lowpoly
|
||||||
parser.getTokens();
|
parser.getTokens();
|
||||||
parser >> asModel;
|
parser >> asModel;
|
||||||
@@ -4405,10 +4583,9 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
asModel = BaseDir + asModel; // McZapkie-200702 - dynamics maja swoje modele w dynamic/basedir
|
asModel = BaseDir + asModel; // McZapkie-200702 - dynamics maja swoje modele w dynamic/basedir
|
||||||
Global.asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
|
Global.asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
|
||||||
mdLowPolyInt = TModelsManager::GetModel(asModel, true);
|
mdLowPolyInt = TModelsManager::GetModel(asModel, true);
|
||||||
// Global.asCurrentTexturePath=AnsiString(szTexturePath); //kiedyś uproszczone wnętrze mieszało tekstury nieba
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( token == "brakemode:" ) {
|
else if( token == "brakemode:" ) {
|
||||||
// Ra 15-01: gałka nastawy hamulca
|
// Ra 15-01: gałka nastawy hamulca
|
||||||
parser.getTokens();
|
parser.getTokens();
|
||||||
parser >> asAnimName;
|
parser >> asAnimName;
|
||||||
@@ -4416,7 +4593,7 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
// jeszcze wczytać kąty obrotu dla poszczególnych ustawień
|
// jeszcze wczytać kąty obrotu dla poszczególnych ustawień
|
||||||
}
|
}
|
||||||
|
|
||||||
if( token == "loadmode:" ) {
|
else if( token == "loadmode:" ) {
|
||||||
// Ra 15-01: gałka nastawy hamulca
|
// Ra 15-01: gałka nastawy hamulca
|
||||||
parser.getTokens();
|
parser.getTokens();
|
||||||
parser >> asAnimName;
|
parser >> asAnimName;
|
||||||
@@ -4486,7 +4663,7 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
// Ra: pantografy po nowemu mają literki i numerki
|
// Ra: pantografy po nowemu mają literki i numerki
|
||||||
}
|
}
|
||||||
// Pantografy - Winger 160204
|
// Pantografy - Winger 160204
|
||||||
if( token == "animpantrd1prefix:" ) {
|
else if( token == "animpantrd1prefix:" ) {
|
||||||
// prefiks ramion dolnych 1
|
// prefiks ramion dolnych 1
|
||||||
parser.getTokens(); parser >> token;
|
parser.getTokens(); parser >> token;
|
||||||
float4x4 m; // macierz do wyliczenia pozycji i wektora ruchu pantografu
|
float4x4 m; // macierz do wyliczenia pozycji i wektora ruchu pantografu
|
||||||
@@ -4653,6 +4830,7 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if( token == "pantfactors:" ) {
|
else if( token == "pantfactors:" ) {
|
||||||
// Winger 010304:
|
// Winger 010304:
|
||||||
// parametry pantografow
|
// parametry pantografow
|
||||||
@@ -4790,23 +4968,6 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
parser >> fWahaczeAmp;
|
parser >> fWahaczeAmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
else if (str == AnsiString("engineer:"))
|
|
||||||
{ // nazwa submodelu maszynisty
|
|
||||||
str = Parser->GetNextSymbol();
|
|
||||||
smMechanik0 = mdModel->GetFromName(str.c_str());
|
|
||||||
if (!smMechanik0)
|
|
||||||
{ // jak nie ma bez numerka, to może jest z
|
|
||||||
// numerkiem?
|
|
||||||
smMechanik0 = mdModel->GetFromName(AnsiString(str + "1").c_str());
|
|
||||||
smMechanik1 = mdModel->GetFromName(AnsiString(str + "2").c_str());
|
|
||||||
}
|
|
||||||
// aby dało się go obracać, musi mieć włączoną animację w T3D!
|
|
||||||
// if (!smMechanik1) //jeśli drugiego nie ma
|
|
||||||
// if (smMechanik0) //a jest pierwszy
|
|
||||||
// smMechanik0->WillBeAnimated(); //to będziemy go obracać
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
else if( token == "animdoorprefix:" ) {
|
else if( token == "animdoorprefix:" ) {
|
||||||
// nazwa animowanych drzwi
|
// nazwa animowanych drzwi
|
||||||
@@ -4841,9 +5002,80 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
}
|
}
|
||||||
pAnimations[i + j].iNumber = i; // parzyste działają inaczej niż nieparzyste
|
pAnimations[i + j].iNumber = i; // parzyste działają inaczej niż nieparzyste
|
||||||
pAnimations[i + j].fMaxDist = 300 * 300; // drzwi to z daleka widać
|
pAnimations[i + j].fMaxDist = 300 * 300; // drzwi to z daleka widać
|
||||||
|
/*
|
||||||
|
// NOTE: no longer used
|
||||||
pAnimations[i + j].fSpeed = Random(150); // oryginalny koncept z DoorSpeedFactor
|
pAnimations[i + j].fSpeed = Random(150); // oryginalny koncept z DoorSpeedFactor
|
||||||
pAnimations[i + j].fSpeed = (pAnimations[i + j].fSpeed + 100) / 100;
|
pAnimations[i + j].fSpeed = (pAnimations[i + j].fSpeed + 100) / 100;
|
||||||
// Ra: te współczynniki są bez sensu, bo modyfikują wektor przesunięcia
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( token == "animstepprefix:" ) {
|
||||||
|
// animated doorstep submodel name prefix
|
||||||
|
int i, j;
|
||||||
|
parser.getTokens(1, false); parser >> token;
|
||||||
|
for (i = 0, j = 0; i < ANIM_DOORSTEPS; ++i)
|
||||||
|
j += iAnimType[i]; // zliczanie wcześniejszych animacji
|
||||||
|
for (i = 0; i < iAnimType[ANIM_DOORSTEPS]; ++i) // liczba drzwi
|
||||||
|
{ // NBMX wrzesien 2003: wyszukiwanie drzwi o nazwie str*
|
||||||
|
// ustalenie submodelu
|
||||||
|
asAnimName = token + std::to_string(i + 1);
|
||||||
|
pAnimations[i + j].smAnimated = mdModel->GetFromName(asAnimName);
|
||||||
|
if (pAnimations[i + j].smAnimated)
|
||||||
|
{ //++iAnimatedDoors;
|
||||||
|
pAnimations[i + j].smAnimated->WillBeAnimated(); // wyłączenie optymalizacji transformu
|
||||||
|
switch (MoverParameters->PlatformOpenMethod)
|
||||||
|
{ // od razu zapinamy potrzebny typ animacji
|
||||||
|
case 1: // shift
|
||||||
|
pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdatePlatformTranslate, this, std::placeholders::_1 );
|
||||||
|
break;
|
||||||
|
case 2: // rotate
|
||||||
|
pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdatePlatformRotate, this, std::placeholders::_1 );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pAnimations[i + j].iNumber = i; // parzyste działają inaczej niż nieparzyste
|
||||||
|
pAnimations[i + j].fMaxDist = 150 * 150; // drzwi to z daleka widać
|
||||||
|
/*
|
||||||
|
// NOTE: no longer used
|
||||||
|
pAnimations[i + j].fSpeed = Random(150); // oryginalny koncept z DoorSpeedFactor
|
||||||
|
pAnimations[i + j].fSpeed = (pAnimations[i + j].fSpeed + 100) / 100;
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( token == "animmirrorprefix:" ) {
|
||||||
|
// animated mirror submodel name prefix
|
||||||
|
int i, j;
|
||||||
|
parser.getTokens( 1, false ); parser >> token;
|
||||||
|
for( i = 0, j = 0; i < ANIM_MIRRORS; ++i )
|
||||||
|
j += iAnimType[ i ]; // zliczanie wcześniejszych animacji
|
||||||
|
for( i = 0; i < iAnimType[ ANIM_MIRRORS ]; ++i ) // liczba drzwi
|
||||||
|
{ // NBMX wrzesien 2003: wyszukiwanie drzwi o nazwie str*
|
||||||
|
// ustalenie submodelu
|
||||||
|
asAnimName = token + std::to_string( i + 1 );
|
||||||
|
pAnimations[ i + j ].smAnimated = mdModel->GetFromName( asAnimName );
|
||||||
|
if( pAnimations[ i + j ].smAnimated ) {
|
||||||
|
pAnimations[ i + j ].smAnimated->WillBeAnimated(); // wyłączenie optymalizacji transformu
|
||||||
|
// od razu zapinamy potrzebny typ animacji
|
||||||
|
auto const offset { pAnimations[ i + j ].smAnimated->offset() };
|
||||||
|
pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateMirror, this, std::placeholders::_1 );
|
||||||
|
// we don't expect more than 2-4 mirrors, so it should be safe to store submodel location (front/rear) in the higher bits
|
||||||
|
// parzyste działają inaczej niż nieparzyste
|
||||||
|
pAnimations[ i + j ].iNumber =
|
||||||
|
( ( pAnimations[ i + j ].smAnimated->offset().z > 0 ?
|
||||||
|
side::front :
|
||||||
|
side::rear ) << 4 )
|
||||||
|
+ i;
|
||||||
|
pAnimations[ i + j ].fMaxDist = 150 * 150; // drzwi to z daleka widać
|
||||||
|
/*
|
||||||
|
// NOTE: no longer used
|
||||||
|
pAnimations[i + j].fSpeed = Random(150); // oryginalny koncept z DoorSpeedFactor
|
||||||
|
pAnimations[i + j].fSpeed = (pAnimations[i + j].fSpeed + 100) / 100;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4984,6 +5216,18 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
rsPisk.m_amplitudeoffset *= ( 105.f - Random( 10.f ) ) / 100.f;
|
rsPisk.m_amplitudeoffset *= ( 105.f - Random( 10.f ) ) / 100.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if( token == "brakecylinderinc:" ) {
|
||||||
|
// brake cylinder pressure increase sounds
|
||||||
|
m_brakecylinderpistonadvance.deserialize( parser, sound_type::single );
|
||||||
|
m_brakecylinderpistonadvance.owner( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( token == "brakecylinderdec:" ) {
|
||||||
|
// brake cylinder pressure decrease sounds
|
||||||
|
m_brakecylinderpistonrecede.deserialize( parser, sound_type::single );
|
||||||
|
m_brakecylinderpistonrecede.owner( this );
|
||||||
|
}
|
||||||
|
|
||||||
else if( token == "brakeacc:" ) {
|
else if( token == "brakeacc:" ) {
|
||||||
// plik z przyspieszaczem (upust po zlapaniu hamowania)
|
// plik z przyspieszaczem (upust po zlapaniu hamowania)
|
||||||
sBrakeAcc.deserialize( parser, sound_type::single );
|
sBrakeAcc.deserialize( parser, sound_type::single );
|
||||||
@@ -5019,12 +5263,17 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
// pliki z trabieniem wysokoton.
|
// pliki z trabieniem wysokoton.
|
||||||
sHorn2.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
sHorn2.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
||||||
sHorn2.owner( this );
|
sHorn2.owner( this );
|
||||||
|
// TBD, TODO: move horn selection to ai config file
|
||||||
if( iHornWarning ) {
|
if( iHornWarning ) {
|
||||||
iHornWarning = 2; // numer syreny do użycia po otrzymaniu sygnału do jazdy
|
iHornWarning = 2; // numer syreny do użycia po otrzymaniu sygnału do jazdy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if( token == "horn3:" ) {
|
||||||
|
sHorn3.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
||||||
|
sHorn3.owner( this );
|
||||||
|
}
|
||||||
|
|
||||||
else if( token == "departuresignal:" ) {
|
else if( token == "departuresignal:" ) {
|
||||||
// pliki z sygnalem odjazdu
|
// pliki z sygnalem odjazdu
|
||||||
sDepartureSignal.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
sDepartureSignal.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
||||||
@@ -5067,6 +5316,7 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
// pliki z turbogeneratorem
|
// pliki z turbogeneratorem
|
||||||
m_powertrainsounds.engine_turbo.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
m_powertrainsounds.engine_turbo.deserialize( parser, sound_type::multipart, sound_parameters::range );
|
||||||
m_powertrainsounds.engine_turbo.owner( this );
|
m_powertrainsounds.engine_turbo.owner( this );
|
||||||
|
m_powertrainsounds.engine_turbo.gain( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
else if( token == "small-compressor:" ) {
|
else if( token == "small-compressor:" ) {
|
||||||
@@ -5076,29 +5326,53 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if( token == "dooropen:" ) {
|
else if( token == "dooropen:" ) {
|
||||||
sound_source doortemplate { sound_placement::general };
|
sound_source soundtemplate { sound_placement::general };
|
||||||
doortemplate.deserialize( parser, sound_type::single );
|
soundtemplate.deserialize( parser, sound_type::single );
|
||||||
doortemplate.owner( this );
|
soundtemplate.owner( this );
|
||||||
for( auto &door : m_doorsounds ) {
|
for( auto &door : m_doorsounds ) {
|
||||||
// apply configuration to all defined doors, but preserve their individual offsets
|
// apply configuration to all defined doors, but preserve their individual offsets
|
||||||
auto const dooroffset { door.rsDoorOpen.offset() };
|
auto const dooroffset { door.rsDoorOpen.offset() };
|
||||||
door.rsDoorOpen = doortemplate;
|
door.rsDoorOpen = soundtemplate;
|
||||||
door.rsDoorOpen.offset( dooroffset );
|
door.rsDoorOpen.offset( dooroffset );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if( token == "doorclose:" ) {
|
else if( token == "doorclose:" ) {
|
||||||
sound_source doortemplate { sound_placement::general };
|
sound_source soundtemplate { sound_placement::general };
|
||||||
doortemplate.deserialize( parser, sound_type::single );
|
soundtemplate.deserialize( parser, sound_type::single );
|
||||||
doortemplate.owner( this );
|
soundtemplate.owner( this );
|
||||||
for( auto &door : m_doorsounds ) {
|
for( auto &door : m_doorsounds ) {
|
||||||
// apply configuration to all defined doors, but preserve their individual offsets
|
// apply configuration to all defined doors, but preserve their individual offsets
|
||||||
auto const dooroffset { door.rsDoorClose.offset() };
|
auto const dooroffset { door.rsDoorClose.offset() };
|
||||||
door.rsDoorClose = doortemplate;
|
door.rsDoorClose = soundtemplate;
|
||||||
door.rsDoorClose.offset( dooroffset );
|
door.rsDoorClose.offset( dooroffset );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if( token == "doorstepopen:" ) {
|
||||||
|
sound_source soundtemplate { sound_placement::general };
|
||||||
|
soundtemplate.deserialize( parser, sound_type::single );
|
||||||
|
soundtemplate.owner( this );
|
||||||
|
for( auto &door : m_doorsounds ) {
|
||||||
|
// apply configuration to all defined doors, but preserve their individual offsets
|
||||||
|
auto const dooroffset { door.step_open.offset() };
|
||||||
|
door.step_open = soundtemplate;
|
||||||
|
door.step_open.offset( dooroffset );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( token == "doorstepclose:" ) {
|
||||||
|
sound_source soundtemplate { sound_placement::general };
|
||||||
|
soundtemplate.deserialize( parser, sound_type::single );
|
||||||
|
soundtemplate.owner( this );
|
||||||
|
for( auto &door : m_doorsounds ) {
|
||||||
|
// apply configuration to all defined doors, but preserve their individual offsets
|
||||||
|
auto const dooroffset { door.step_close.offset() };
|
||||||
|
door.step_close = soundtemplate;
|
||||||
|
door.step_close.offset( dooroffset );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else if( token == "unloading:" ) {
|
else if( token == "unloading:" ) {
|
||||||
m_exchangesounds.unloading.deserialize( parser, sound_type::single );
|
m_exchangesounds.unloading.deserialize( parser, sound_type::single );
|
||||||
m_exchangesounds.unloading.owner( this );
|
m_exchangesounds.unloading.owner( this );
|
||||||
@@ -5178,6 +5452,8 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
auto const location { glm::vec3 { MoverParameters->Dim.W * 0.5f, MoverParameters->Dim.H * 0.5f, offset } };
|
auto const location { glm::vec3 { MoverParameters->Dim.W * 0.5f, MoverParameters->Dim.H * 0.5f, offset } };
|
||||||
door.rsDoorClose.offset( location );
|
door.rsDoorClose.offset( location );
|
||||||
door.rsDoorOpen.offset( location );
|
door.rsDoorOpen.offset( location );
|
||||||
|
door.step_close.offset( location );
|
||||||
|
door.step_open.offset( location );
|
||||||
m_doorsounds.emplace_back( door );
|
m_doorsounds.emplace_back( door );
|
||||||
}
|
}
|
||||||
if( ( sides == "both" )
|
if( ( sides == "both" )
|
||||||
@@ -5186,6 +5462,8 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
|
|||||||
auto const location { glm::vec3 { MoverParameters->Dim.W * -0.5f, MoverParameters->Dim.H * 0.5f, offset } };
|
auto const location { glm::vec3 { MoverParameters->Dim.W * -0.5f, MoverParameters->Dim.H * 0.5f, offset } };
|
||||||
door.rsDoorClose.offset( location );
|
door.rsDoorClose.offset( location );
|
||||||
door.rsDoorOpen.offset( location );
|
door.rsDoorOpen.offset( location );
|
||||||
|
door.step_close.offset( location );
|
||||||
|
door.step_open.offset( location );
|
||||||
m_doorsounds.emplace_back( door );
|
m_doorsounds.emplace_back( door );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6413,19 +6691,9 @@ vehicle_table::update( double Deltatime, int Iterationcount ) {
|
|||||||
// Ra 2015-01: tylko tu przelicza sieć trakcyjną
|
// Ra 2015-01: tylko tu przelicza sieć trakcyjną
|
||||||
vehicle->Update( Deltatime, totaltime );
|
vehicle->Update( Deltatime, totaltime );
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// TODO: re-implement
|
// jeśli jest coś do usunięcia z listy, to trzeba na końcu
|
||||||
if (TDynamicObject::bDynamicRemove)
|
erase_disabled();
|
||||||
{ // jeśli jest coś do usunięcia z listy, to trzeba na końcu
|
|
||||||
for (TGroundNode *Current = nRootDynamic; Current; Current = Current->nNext)
|
|
||||||
if ( false == Current->DynamicObject->bEnabled)
|
|
||||||
{
|
|
||||||
DynamicRemove(Current->DynamicObject); // usunięcie tego i podłączonych
|
|
||||||
Current = nRootDynamic; // sprawdzanie listy od początku
|
|
||||||
}
|
|
||||||
TDynamicObject::bDynamicRemove = false; // na razie koniec
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// legacy method, checks for presence and height of traction wire for specified vehicle
|
// legacy method, checks for presence and height of traction wire for specified vehicle
|
||||||
@@ -6536,3 +6804,56 @@ vehicle_table::DynamicList( bool const Onlycontrolled ) const {
|
|||||||
// informacja o końcu listy
|
// informacja o końcu listy
|
||||||
multiplayer::WyslijString( "none", 6 );
|
multiplayer::WyslijString( "none", 6 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// maintenance; removes from tracks consists with vehicles marked as disabled
|
||||||
|
bool
|
||||||
|
vehicle_table::erase_disabled() {
|
||||||
|
|
||||||
|
if( false == TDynamicObject::bDynamicRemove ) { return false; }
|
||||||
|
|
||||||
|
// go through the list and retrieve vehicles scheduled for removal...
|
||||||
|
type_sequence disabledvehicles;
|
||||||
|
for( auto *vehicle : m_items ) {
|
||||||
|
if( false == vehicle->bEnabled ) {
|
||||||
|
disabledvehicles.emplace_back( vehicle );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ...now propagate removal flag through affected consists...
|
||||||
|
for( auto *vehicle : disabledvehicles ) {
|
||||||
|
TDynamicObject *coupledvehicle { vehicle };
|
||||||
|
while( ( coupledvehicle = coupledvehicle->Next() ) != nullptr ) {
|
||||||
|
coupledvehicle->bEnabled = false;
|
||||||
|
}
|
||||||
|
// (try to) run propagation in both directions, it's simpler than branching based on direction etc
|
||||||
|
coupledvehicle = vehicle;
|
||||||
|
while( ( coupledvehicle = coupledvehicle->Prev() ) != nullptr ) {
|
||||||
|
coupledvehicle->bEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ...then actually remove all disabled vehicles...
|
||||||
|
auto vehicleiter = std::begin( m_items );
|
||||||
|
while( vehicleiter != std::end( m_items ) ) {
|
||||||
|
|
||||||
|
auto *vehicle { *vehicleiter };
|
||||||
|
|
||||||
|
if( true == vehicle->bEnabled ) {
|
||||||
|
++vehicleiter;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if( vehicle->MyTrack != nullptr ) {
|
||||||
|
vehicle->MyTrack->RemoveDynamicObject( vehicle );
|
||||||
|
}
|
||||||
|
// clear potential train binding
|
||||||
|
Global.pWorld->TrainDelete( vehicle );
|
||||||
|
// remove potential entries in the light array
|
||||||
|
simulation::Lights.remove( vehicle );
|
||||||
|
// finally get rid of the vehicle and its record themselves
|
||||||
|
SafeDelete( vehicle );
|
||||||
|
vehicleiter = m_items.erase( vehicleiter );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ...and call it a day
|
||||||
|
TDynamicObject::bDynamicRemove = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
54
DynObj.h
54
DynObj.h
@@ -24,7 +24,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
int const ANIM_TYPES = 7; // Ra: ilość typów animacji
|
|
||||||
int const ANIM_WHEELS = 0; // koła
|
int const ANIM_WHEELS = 0; // koła
|
||||||
int const ANIM_DOORS = 1; // drzwi
|
int const ANIM_DOORS = 1; // drzwi
|
||||||
int const ANIM_LEVERS = 2; // elementy obracane (wycieraczki, koła skrętne, przestawiacze, klocki ham.)
|
int const ANIM_LEVERS = 2; // elementy obracane (wycieraczki, koła skrętne, przestawiacze, klocki ham.)
|
||||||
@@ -32,6 +31,9 @@ int const ANIM_BUFFERS = 3; // elementy przesuwane (zderzaki)
|
|||||||
int const ANIM_BOOGIES = 4; // wózki (są skręcane w dwóch osiach)
|
int const ANIM_BOOGIES = 4; // wózki (są skręcane w dwóch osiach)
|
||||||
int const ANIM_PANTS = 5; // pantografy
|
int const ANIM_PANTS = 5; // pantografy
|
||||||
int const ANIM_STEAMS = 6; // napęd parowozu
|
int const ANIM_STEAMS = 6; // napęd parowozu
|
||||||
|
int const ANIM_DOORSTEPS = 7;
|
||||||
|
int const ANIM_MIRRORS = 8;
|
||||||
|
int const ANIM_TYPES = 9; // Ra: ilość typów animacji
|
||||||
|
|
||||||
class TAnim;
|
class TAnim;
|
||||||
//typedef void(__closure *TUpdate)(TAnim *pAnim); // typ funkcji aktualizującej położenie submodeli
|
//typedef void(__closure *TUpdate)(TAnim *pAnim); // typ funkcji aktualizującej położenie submodeli
|
||||||
@@ -104,7 +106,14 @@ class TAnimPant
|
|||||||
class TAnim
|
class TAnim
|
||||||
{ // klasa animowanej części pojazdu (koła, drzwi, pantografy, burty, napęd parowozu, siłowniki
|
{ // klasa animowanej części pojazdu (koła, drzwi, pantografy, burty, napęd parowozu, siłowniki
|
||||||
// itd.)
|
// itd.)
|
||||||
public:
|
public:
|
||||||
|
// constructor
|
||||||
|
TAnim() = default;
|
||||||
|
// destructor
|
||||||
|
~TAnim();
|
||||||
|
// methods
|
||||||
|
int TypeSet( int i, int fl = 0 ); // ustawienie typu
|
||||||
|
// members
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
TSubModel *smAnimated; // animowany submodel (jeśli tylko jeden, np. oś)
|
TSubModel *smAnimated; // animowany submodel (jeśli tylko jeden, np. oś)
|
||||||
@@ -126,16 +135,15 @@ class TAnim
|
|||||||
int *iIntBase; // jakiś int w fizyce
|
int *iIntBase; // jakiś int w fizyce
|
||||||
};
|
};
|
||||||
// void _fastcall Update(); //wskaźnik do funkcji aktualizacji animacji
|
// void _fastcall Update(); //wskaźnik do funkcji aktualizacji animacji
|
||||||
int iFlags; // flagi animacji
|
int iFlags{ 0 }; // flagi animacji
|
||||||
float fMaxDist; // do jakiej odległości wykonywana jest animacja
|
float fMaxDist; // do jakiej odległości wykonywana jest animacja
|
||||||
float fSpeed; // parametr szybkości animacji
|
float fSpeed; // parametr szybkości animacji
|
||||||
int iNumber; // numer kolejny obiektu
|
int iNumber; // numer kolejny obiektu
|
||||||
public:
|
|
||||||
TAnim();
|
|
||||||
~TAnim();
|
|
||||||
TUpdate yUpdate; // metoda TDynamicObject aktualizująca animację
|
TUpdate yUpdate; // metoda TDynamicObject aktualizująca animację
|
||||||
int TypeSet(int i, int fl = 0); // ustawienie typu
|
/*
|
||||||
void Parovoz(); // wykonanie obliczeń animacji
|
void Parovoz(); // wykonanie obliczeń animacji
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -216,16 +224,15 @@ public:
|
|||||||
*Material() const {
|
*Material() const {
|
||||||
return &m_materialdata; }
|
return &m_materialdata; }
|
||||||
// tymczasowo udostępnione do wyszukiwania drutu
|
// tymczasowo udostępnione do wyszukiwania drutu
|
||||||
int iAnimType[ ANIM_TYPES ]; // 0-osie,1-drzwi,2-obracane,3-zderzaki,4-wózki,5-pantografy,6-tłoki
|
std::array<int, ANIM_TYPES> iAnimType{ 0 }; // 0-osie,1-drzwi,2-obracane,3-zderzaki,4-wózki,5-pantografy,6-tłoki
|
||||||
private:
|
private:
|
||||||
int iAnimations; // liczba obiektów animujących
|
int iAnimations; // liczba obiektów animujących
|
||||||
/*
|
|
||||||
TAnim *pAnimations; // obiekty animujące (zawierają wskaźnik do funkcji wykonującej animację)
|
|
||||||
*/
|
|
||||||
std::vector<TAnim> pAnimations;
|
std::vector<TAnim> pAnimations;
|
||||||
TSubModel ** pAnimated; // lista animowanych submodeli (może być ich więcej niż obiektów animujących)
|
TSubModel ** pAnimated; // lista animowanych submodeli (może być ich więcej niż obiektów animujących)
|
||||||
double dWheelAngle[3]; // kąty obrotu kół: 0=przednie toczne, 1=napędzające i wiązary, 2=tylne toczne
|
double dWheelAngle[3]; // kąty obrotu kół: 0=przednie toczne, 1=napędzające i wiązary, 2=tylne toczne
|
||||||
|
/*
|
||||||
void UpdateNone(TAnim *pAnim){}; // animacja pusta (funkcje ustawiania submodeli, gdy blisko kamery)
|
void UpdateNone(TAnim *pAnim){}; // animacja pusta (funkcje ustawiania submodeli, gdy blisko kamery)
|
||||||
|
*/
|
||||||
void UpdateAxle(TAnim *pAnim); // animacja osi
|
void UpdateAxle(TAnim *pAnim); // animacja osi
|
||||||
void UpdateBoogie(TAnim *pAnim); // animacja wózka
|
void UpdateBoogie(TAnim *pAnim); // animacja wózka
|
||||||
void UpdateDoorTranslate(TAnim *pAnim); // animacja drzwi - przesuw
|
void UpdateDoorTranslate(TAnim *pAnim); // animacja drzwi - przesuw
|
||||||
@@ -233,10 +240,15 @@ private:
|
|||||||
void UpdateDoorFold(TAnim *pAnim); // animacja drzwi - składanie
|
void UpdateDoorFold(TAnim *pAnim); // animacja drzwi - składanie
|
||||||
void UpdateDoorPlug(TAnim *pAnim); // animacja drzwi - odskokowo-przesuwne
|
void UpdateDoorPlug(TAnim *pAnim); // animacja drzwi - odskokowo-przesuwne
|
||||||
void UpdatePant(TAnim *pAnim); // animacja pantografu
|
void UpdatePant(TAnim *pAnim); // animacja pantografu
|
||||||
|
void UpdatePlatformTranslate(TAnim *pAnim); // doorstep animation, shift
|
||||||
|
void UpdatePlatformRotate(TAnim *pAnim); // doorstep animation, rotate
|
||||||
|
void UpdateMirror(TAnim *pAnim); // mirror animation
|
||||||
|
/*
|
||||||
void UpdateLeverDouble(TAnim *pAnim); // animacja gałki zależna od double
|
void UpdateLeverDouble(TAnim *pAnim); // animacja gałki zależna od double
|
||||||
void UpdateLeverFloat(TAnim *pAnim); // animacja gałki zależna od float
|
void UpdateLeverFloat(TAnim *pAnim); // animacja gałki zależna od float
|
||||||
void UpdateLeverInt(TAnim *pAnim); // animacja gałki zależna od int (wartość)
|
void UpdateLeverInt(TAnim *pAnim); // animacja gałki zależna od int (wartość)
|
||||||
void UpdateLeverEnum(TAnim *pAnim); // animacja gałki zależna od int (lista kątów)
|
void UpdateLeverEnum(TAnim *pAnim); // animacja gałki zależna od int (lista kątów)
|
||||||
|
*/
|
||||||
void toggle_lights(); // switch light levels for registered interior sections
|
void toggle_lights(); // switch light levels for registered interior sections
|
||||||
private: // Ra: ciąg dalszy animacji, dopiero do ogarnięcia
|
private: // Ra: ciąg dalszy animacji, dopiero do ogarnięcia
|
||||||
// ABuWozki 060504
|
// ABuWozki 060504
|
||||||
@@ -256,8 +268,14 @@ private:
|
|||||||
public:
|
public:
|
||||||
TAnim *pants; // indeks obiektu animującego dla pantografu 0
|
TAnim *pants; // indeks obiektu animującego dla pantografu 0
|
||||||
double NoVoltTime; // czas od utraty zasilania
|
double NoVoltTime; // czas od utraty zasilania
|
||||||
|
float DoorDelayL{ 0.f }; // left side door closing delay timer
|
||||||
|
float DoorDelayR{ 0.f }; // right side door closing delay timer
|
||||||
double dDoorMoveL; // NBMX
|
double dDoorMoveL; // NBMX
|
||||||
double dDoorMoveR; // NBMX
|
double dDoorMoveR; // NBMX
|
||||||
|
double dDoorstepMoveL{ 0.0 };
|
||||||
|
double dDoorstepMoveR{ 0.0 };
|
||||||
|
double dMirrorMoveL{ 0.0 };
|
||||||
|
double dMirrorMoveR{ 0.0 };
|
||||||
TSubModel *smBrakeSet; // nastawa hamulca (wajcha)
|
TSubModel *smBrakeSet; // nastawa hamulca (wajcha)
|
||||||
TSubModel *smLoadSet; // nastawa ładunku (wajcha)
|
TSubModel *smLoadSet; // nastawa ładunku (wajcha)
|
||||||
TSubModel *smWiper; // wycieraczka (poniekąd też wajcha)
|
TSubModel *smWiper; // wycieraczka (poniekąd też wajcha)
|
||||||
@@ -290,6 +308,8 @@ private:
|
|||||||
struct door_sounds {
|
struct door_sounds {
|
||||||
sound_source rsDoorOpen { sound_placement::general, 25.f }; // Ra: przeniesione z kabiny
|
sound_source rsDoorOpen { sound_placement::general, 25.f }; // Ra: przeniesione z kabiny
|
||||||
sound_source rsDoorClose { sound_placement::general, 25.f };
|
sound_source rsDoorClose { sound_placement::general, 25.f };
|
||||||
|
sound_source step_open { sound_placement::general, 25.f };
|
||||||
|
sound_source step_close { sound_placement::general, 25.f };
|
||||||
};
|
};
|
||||||
|
|
||||||
struct exchange_sounds {
|
struct exchange_sounds {
|
||||||
@@ -391,8 +411,10 @@ private:
|
|||||||
bool bBrakeAcc { false };
|
bool bBrakeAcc { false };
|
||||||
sound_source rsPisk { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // McZapkie-260302
|
sound_source rsPisk { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // McZapkie-260302
|
||||||
sound_source rsUnbrake { sound_placement::external }; // yB - odglos luzowania
|
sound_source rsUnbrake { sound_placement::external }; // yB - odglos luzowania
|
||||||
float m_lastbrakepressure { -1.f }; // helper, cached level of pressure in brake cylinder
|
sound_source m_brakecylinderpistonadvance { sound_placement::external };
|
||||||
float m_brakepressurechange { 0.f }; // recent change of pressure in brake cylinder
|
sound_source m_brakecylinderpistonrecede { sound_placement::external };
|
||||||
|
float m_lastbrakepressure { -1.f }; // helper, cached level of pressure in the brake cylinder
|
||||||
|
float m_brakepressurechange { 0.f }; // recent change of pressure in the brake cylinder
|
||||||
sound_source sReleaser { sound_placement::external };
|
sound_source sReleaser { sound_placement::external };
|
||||||
sound_source rsSlippery { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab
|
sound_source rsSlippery { sound_placement::external, EU07_SOUND_BRAKINGCUTOFFRANGE }; // moved from cab
|
||||||
sound_source sSand { sound_placement::external };
|
sound_source sSand { sound_placement::external };
|
||||||
@@ -403,6 +425,7 @@ private:
|
|||||||
sound_source sDepartureSignal { sound_placement::general };
|
sound_source sDepartureSignal { sound_placement::general };
|
||||||
sound_source sHorn1 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
sound_source sHorn1 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||||
sound_source sHorn2 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
sound_source sHorn2 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||||
|
sound_source sHorn3 { sound_placement::external, 5 * EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||||
std::vector<sound_source> m_bogiesounds; // TBD, TODO: wrapper for all bogie-related sounds (noise, brakes, squeal etc)
|
std::vector<sound_source> m_bogiesounds; // TBD, TODO: wrapper for all bogie-related sounds (noise, brakes, squeal etc)
|
||||||
sound_source m_wheelflat { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
sound_source m_wheelflat { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE };
|
||||||
sound_source rscurve { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // youBy
|
sound_source rscurve { sound_placement::external, EU07_SOUND_RUNNINGNOISECUTOFFRANGE }; // youBy
|
||||||
@@ -600,6 +623,11 @@ public:
|
|||||||
// legacy method, sends list of vehicles over network
|
// legacy method, sends list of vehicles over network
|
||||||
void
|
void
|
||||||
DynamicList( bool const Onlycontrolled = false ) const;
|
DynamicList( bool const Onlycontrolled = false ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// maintenance; removes from tracks consists with vehicles marked as disabled
|
||||||
|
bool
|
||||||
|
erase_disabled();
|
||||||
};
|
};
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
4
Event.h
4
Event.h
@@ -137,6 +137,10 @@ public:
|
|||||||
bool
|
bool
|
||||||
insert( TEventLauncher *Launcher ) {
|
insert( TEventLauncher *Launcher ) {
|
||||||
return m_launchers.insert( Launcher ); }
|
return m_launchers.insert( Launcher ); }
|
||||||
|
// returns first event in the queue
|
||||||
|
TEvent *
|
||||||
|
begin() {
|
||||||
|
return QueryRootEvent; }
|
||||||
// legacy method, returns pointer to specified event, or null
|
// legacy method, returns pointer to specified event, or null
|
||||||
TEvent *
|
TEvent *
|
||||||
FindEvent( std::string const &Name );
|
FindEvent( std::string const &Name );
|
||||||
|
|||||||
17
Gauge.cpp
17
Gauge.cpp
@@ -21,6 +21,13 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
|
||||||
|
TGauge::TGauge( sound_source const &Soundtemplate ) :
|
||||||
|
m_soundtemplate( Soundtemplate )
|
||||||
|
{
|
||||||
|
m_soundfxincrease = m_soundtemplate;
|
||||||
|
m_soundfxdecrease = m_soundtemplate;
|
||||||
|
}
|
||||||
|
|
||||||
void TGauge::Init(TSubModel *Submodel, TGaugeType Type, float Scale, float Offset, float Friction, float Value, float const Endvalue, float const Endscale, bool const Interpolatescale )
|
void TGauge::Init(TSubModel *Submodel, TGaugeType Type, float Scale, float Offset, float Friction, float Value, float const Endvalue, float const Endscale, bool const Interpolatescale )
|
||||||
{ // ustawienie parametrów animacji submodelu
|
{ // ustawienie parametrów animacji submodelu
|
||||||
SubModel = Submodel;
|
SubModel = Submodel;
|
||||||
@@ -172,7 +179,7 @@ TGauge::Load_mapping( cParser &Input ) {
|
|||||||
if( indexstart != std::string::npos ) {
|
if( indexstart != std::string::npos ) {
|
||||||
m_soundfxvalues.emplace(
|
m_soundfxvalues.emplace(
|
||||||
std::stoi( key.substr( indexstart, indexend - indexstart ) ),
|
std::stoi( key.substr( indexstart, indexend - indexstart ) ),
|
||||||
sound_source( sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE ).deserialize( Input, sound_type::single ) );
|
sound_source( m_soundtemplate ).deserialize( Input, sound_type::single ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true; // return value marks a key: value pair was extracted, nothing about whether it's recognized
|
return true; // return value marks a key: value pair was extracted, nothing about whether it's recognized
|
||||||
@@ -333,13 +340,15 @@ void TGauge::UpdateValue()
|
|||||||
switch (m_datatype)
|
switch (m_datatype)
|
||||||
{ // to nie jest zbyt optymalne, można by zrobić osobne funkcje
|
{ // to nie jest zbyt optymalne, można by zrobić osobne funkcje
|
||||||
case 'f':
|
case 'f':
|
||||||
m_targetvalue = (*fData);
|
UpdateValue( *fData );
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
m_targetvalue = (*dData);
|
UpdateValue( *dData );
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
m_targetvalue = (*iData);
|
UpdateValue( *iData );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
10
Gauge.h
10
Gauge.h
@@ -27,8 +27,11 @@ class TGauge {
|
|||||||
public:
|
public:
|
||||||
// methods
|
// methods
|
||||||
TGauge() = default;
|
TGauge() = default;
|
||||||
|
explicit TGauge( sound_source const &Soundtemplate );
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void Clear() { *this = TGauge(); }
|
void Clear() {
|
||||||
|
*this = TGauge(); }
|
||||||
void Init(TSubModel *Submodel, TGaugeType Type, float Scale = 1, float Offset = 0, float Friction = 0, float Value = 0, float const Endvalue = -1.0, float const Endscale = -1.0, bool const Interpolate = false );
|
void Init(TSubModel *Submodel, TGaugeType Type, float Scale = 1, float Offset = 0, float Friction = 0, float Value = 0, float const Endvalue = -1.0, float const Endscale = -1.0, bool const Interpolate = false );
|
||||||
bool Load(cParser &Parser, TDynamicObject const *Owner, TModel3d *md1, TModel3d *md2 = nullptr, double mul = 1.0);
|
bool Load(cParser &Parser, TDynamicObject const *Owner, TModel3d *md1, TModel3d *md2 = nullptr, double mul = 1.0);
|
||||||
void UpdateValue( float fNewDesired );
|
void UpdateValue( float fNewDesired );
|
||||||
@@ -73,8 +76,9 @@ private:
|
|||||||
double *dData { nullptr };
|
double *dData { nullptr };
|
||||||
int *iData;
|
int *iData;
|
||||||
};
|
};
|
||||||
sound_source m_soundfxincrease { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // sound associated with increasing control's value
|
sound_source m_soundtemplate { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // shared properties for control's sounds
|
||||||
sound_source m_soundfxdecrease { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // sound associated with decreasing control's value
|
sound_source m_soundfxincrease { m_soundtemplate }; // sound associated with increasing control's value
|
||||||
|
sound_source m_soundfxdecrease { m_soundtemplate }; // sound associated with decreasing control's value
|
||||||
std::map<int, sound_source> m_soundfxvalues; // sounds associated with specific values
|
std::map<int, sound_source> m_soundfxvalues; // sounds associated with specific values
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
27
Globals.cpp
27
Globals.cpp
@@ -316,6 +316,14 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
Parser.getTokens( 1, false );
|
Parser.getTokens( 1, false );
|
||||||
Parser >> ScenarioTimeCurrent;
|
Parser >> ScenarioTimeCurrent;
|
||||||
}
|
}
|
||||||
|
else if( token == "scenario.weather.temperature" ) {
|
||||||
|
// selected device for audio renderer
|
||||||
|
Parser.getTokens();
|
||||||
|
Parser >> AirTemperature;
|
||||||
|
if( false == DebugModeFlag ) {
|
||||||
|
AirTemperature = clamp( AirTemperature, -15.f, 45.f );
|
||||||
|
}
|
||||||
|
}
|
||||||
else if( token == "scalespeculars" ) {
|
else if( token == "scalespeculars" ) {
|
||||||
// whether strength of specular highlights should be adjusted (generally needed for legacy 3d models)
|
// whether strength of specular highlights should be adjusted (generally needed for legacy 3d models)
|
||||||
Parser.getTokens();
|
Parser.getTokens();
|
||||||
@@ -566,6 +574,17 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
Parser.getTokens(1, false);
|
Parser.getTokens(1, false);
|
||||||
Parser >> asLang;
|
Parser >> asLang;
|
||||||
}
|
}
|
||||||
|
else if( token == "pyscreenrendererpriority" )
|
||||||
|
{
|
||||||
|
// old variable, repurposed as update rate of python screen renderer
|
||||||
|
Parser.getTokens();
|
||||||
|
Parser >> token;
|
||||||
|
auto const priority { ToLower( token ) };
|
||||||
|
PythonScreenUpdateRate = (
|
||||||
|
priority == "lower" ? 500 :
|
||||||
|
priority == "lowest" ? 1000 :
|
||||||
|
200 );
|
||||||
|
}
|
||||||
else if( token == "uitextcolor" ) {
|
else if( token == "uitextcolor" ) {
|
||||||
// color of the ui text. NOTE: will be obsolete once the real ui is in place
|
// color of the ui text. NOTE: will be obsolete once the real ui is in place
|
||||||
Parser.getTokens( 3, false );
|
Parser.getTokens( 3, false );
|
||||||
@@ -573,11 +592,9 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
>> UITextColor.r
|
>> UITextColor.r
|
||||||
>> UITextColor.g
|
>> UITextColor.g
|
||||||
>> UITextColor.b;
|
>> UITextColor.b;
|
||||||
UITextColor.r = clamp( UITextColor.r, 0.0f, 255.0f );
|
glm::clamp( UITextColor, 0.f, 255.f );
|
||||||
UITextColor.g = clamp( UITextColor.g, 0.0f, 255.0f );
|
UITextColor = UITextColor / 255.f;
|
||||||
UITextColor.b = clamp( UITextColor.b, 0.0f, 255.0f );
|
UITextColor.a = 1.f;
|
||||||
UITextColor = UITextColor / 255.0f;
|
|
||||||
UITextColor.a = 1.0f;
|
|
||||||
}
|
}
|
||||||
else if( token == "input.gamepad" ) {
|
else if( token == "input.gamepad" ) {
|
||||||
// czy grupować eventy o tych samych nazwach
|
// czy grupować eventy o tych samych nazwach
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ struct global_settings {
|
|||||||
bool DLFont{ false }; // switch indicating presence of basic font
|
bool DLFont{ false }; // switch indicating presence of basic font
|
||||||
bool bActive{ true }; // czy jest aktywnym oknem
|
bool bActive{ true }; // czy jest aktywnym oknem
|
||||||
int iPause{ 0 }; // globalna pauza ruchu: b0=start,b1=klawisz,b2=tło,b3=lagi,b4=wczytywanie
|
int iPause{ 0 }; // globalna pauza ruchu: b0=start,b1=klawisz,b2=tło,b3=lagi,b4=wczytywanie
|
||||||
|
float AirTemperature{ 15.f };
|
||||||
// settings
|
// settings
|
||||||
// filesystem
|
// filesystem
|
||||||
bool bLoadTraction{ true };
|
bool bLoadTraction{ true };
|
||||||
@@ -90,6 +91,7 @@ struct global_settings {
|
|||||||
bool bJoinEvents{ false }; // czy grupować eventy o tych samych nazwach
|
bool bJoinEvents{ false }; // czy grupować eventy o tych samych nazwach
|
||||||
int iHiddenEvents{ 1 }; // czy łączyć eventy z torami poprzez nazwę toru
|
int iHiddenEvents{ 1 }; // czy łączyć eventy z torami poprzez nazwę toru
|
||||||
// ui
|
// ui
|
||||||
|
int PythonScreenUpdateRate { 200 }; // delay between python-based screen updates, in milliseconds
|
||||||
int iTextMode{ 0 }; // tryb pracy wyświetlacza tekstowego
|
int iTextMode{ 0 }; // tryb pracy wyświetlacza tekstowego
|
||||||
int iScreenMode[ 12 ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // numer ekranu wyświetlacza tekstowego
|
int iScreenMode[ 12 ] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // numer ekranu wyświetlacza tekstowego
|
||||||
glm::vec4 UITextColor { glm::vec4( 225.f / 255.f, 225.f / 255.f, 225.f / 255.f, 1.f ) }; // base color of UI text
|
glm::vec4 UITextColor { glm::vec4( 225.f / 255.f, 225.f / 255.f, 225.f / 255.f, 1.f ) }; // base color of UI text
|
||||||
|
|||||||
@@ -637,6 +637,7 @@ struct oil_pump {
|
|||||||
start start_type { start::manual };
|
start start_type { start::manual };
|
||||||
float resource_amount { 1.f };
|
float resource_amount { 1.f };
|
||||||
float pressure_minimum { 0.f }; // lowest acceptable working pressure
|
float pressure_minimum { 0.f }; // lowest acceptable working pressure
|
||||||
|
float pressure_maximum { 0.65f }; // oil pressure at maximum engine revolutions
|
||||||
float pressure_target { 0.f };
|
float pressure_target { 0.f };
|
||||||
float pressure_present { 0.f };
|
float pressure_present { 0.f };
|
||||||
};
|
};
|
||||||
@@ -806,6 +807,7 @@ public:
|
|||||||
double BrakeSlckAdj = 0.0; /*opor nastawiacza skoku tloka, kN*/
|
double BrakeSlckAdj = 0.0; /*opor nastawiacza skoku tloka, kN*/
|
||||||
double BrakeRigEff = 0.0; /*sprawnosc przekladni dzwigniowej*/
|
double BrakeRigEff = 0.0; /*sprawnosc przekladni dzwigniowej*/
|
||||||
double RapidMult = 1.0; /*przelozenie rapidu*/
|
double RapidMult = 1.0; /*przelozenie rapidu*/
|
||||||
|
double RapidVel = 55.0; /*szybkosc przelaczania rapidu*/
|
||||||
int BrakeValveSize = 0;
|
int BrakeValveSize = 0;
|
||||||
std::string BrakeValveParams;
|
std::string BrakeValveParams;
|
||||||
double Spg = 0.0;
|
double Spg = 0.0;
|
||||||
@@ -943,9 +945,11 @@ public:
|
|||||||
double DoorOpenSpeed = 1.0; double DoorCloseSpeed = 1.0; /*predkosc otwierania i zamykania w j.u. */
|
double DoorOpenSpeed = 1.0; double DoorCloseSpeed = 1.0; /*predkosc otwierania i zamykania w j.u. */
|
||||||
double DoorMaxShiftL = 0.5; double DoorMaxShiftR = 0.5; double DoorMaxPlugShift = 0.1;/*szerokosc otwarcia lub kat*/
|
double DoorMaxShiftL = 0.5; double DoorMaxShiftR = 0.5; double DoorMaxPlugShift = 0.1;/*szerokosc otwarcia lub kat*/
|
||||||
int DoorOpenMethod = 2; /*sposob otwarcia - 1: przesuwne, 2: obrotowe, 3: trójelementowe*/
|
int DoorOpenMethod = 2; /*sposob otwarcia - 1: przesuwne, 2: obrotowe, 3: trójelementowe*/
|
||||||
double PlatformSpeed = 0.25; /*szybkosc stopnia*/
|
float DoorCloseDelay { 0.f }; // delay (in seconds) before the door begin closing, once conditions to close are met
|
||||||
double PlatformMaxShift = 0.5; /*wysuniecie stopnia*/
|
double PlatformSpeed = 0.5; /*szybkosc stopnia*/
|
||||||
int PlatformOpenMethod = 1; /*sposob animacji stopnia*/
|
double PlatformMaxShift { 45.0 }; /*wysuniecie stopnia*/
|
||||||
|
int PlatformOpenMethod { 2 }; /*sposob animacji stopnia*/
|
||||||
|
double MirrorMaxShift { 90.0 };
|
||||||
bool ScndS = false; /*Czy jest bocznikowanie na szeregowej*/
|
bool ScndS = false; /*Czy jest bocznikowanie na szeregowej*/
|
||||||
double SpeedCtrlDelay = 2; /*opoznienie dzialania tempomatu z wybieralna predkoscia*/
|
double SpeedCtrlDelay = 2; /*opoznienie dzialania tempomatu z wybieralna predkoscia*/
|
||||||
/*--sekcja zmiennych*/
|
/*--sekcja zmiennych*/
|
||||||
@@ -1064,7 +1068,7 @@ public:
|
|||||||
int DirAbsolute = 0; //zadany kierunek jazdy względem sprzęgów (1=w strone 0,-1=w stronę 1)
|
int DirAbsolute = 0; //zadany kierunek jazdy względem sprzęgów (1=w strone 0,-1=w stronę 1)
|
||||||
int ActiveCab = 0; //numer kabiny, w ktorej jest obsada (zwykle jedna na skład)
|
int ActiveCab = 0; //numer kabiny, w ktorej jest obsada (zwykle jedna na skład)
|
||||||
double LastSwitchingTime = 0.0; /*czas ostatniego przelaczania czegos*/
|
double LastSwitchingTime = 0.0; /*czas ostatniego przelaczania czegos*/
|
||||||
//WarningSignal: byte; {0: nie trabi, 1,2: trabi}
|
int WarningSignal = 0; // 0: nie trabi, 1,2,4: trabi
|
||||||
bool DepartureSignal = false; /*sygnal odjazdu*/
|
bool DepartureSignal = false; /*sygnal odjazdu*/
|
||||||
bool InsideConsist = false;
|
bool InsideConsist = false;
|
||||||
/*-zmienne dla lokomotywy elektrycznej*/
|
/*-zmienne dla lokomotywy elektrycznej*/
|
||||||
@@ -1183,7 +1187,6 @@ public:
|
|||||||
double TotalMassxg = 0.0; /*TotalMass*g*/
|
double TotalMassxg = 0.0; /*TotalMass*g*/
|
||||||
|
|
||||||
Math3D::vector3 vCoulpler[2]; // powtórzenie współrzędnych sprzęgów z DynObj :/
|
Math3D::vector3 vCoulpler[2]; // powtórzenie współrzędnych sprzęgów z DynObj :/
|
||||||
int WarningSignal = 0; // tymczasowo 8bit, ze względu na funkcje w MTools
|
|
||||||
double fBrakeCtrlPos = -2.0; // płynna nastawa hamulca zespolonego
|
double fBrakeCtrlPos = -2.0; // płynna nastawa hamulca zespolonego
|
||||||
bool bPantKurek3 = true; // kurek trójdrogowy (pantografu): true=połączenie z ZG, false=połączenie z małą sprężarką // domyślnie zbiornik pantografu połączony jest ze zbiornikiem głównym
|
bool bPantKurek3 = true; // kurek trójdrogowy (pantografu): true=połączenie z ZG, false=połączenie z małą sprężarką // domyślnie zbiornik pantografu połączony jest ze zbiornikiem głównym
|
||||||
int iProblem = 0; // flagi problemów z taborem, aby AI nie musiało porównywać; 0=może jechać
|
int iProblem = 0; // flagi problemów z taborem, aby AI nie musiało porównywać; 0=może jechać
|
||||||
|
|||||||
@@ -1589,8 +1589,8 @@ void TMoverParameters::FuelPumpCheck( double const Timestep ) {
|
|||||||
FuelPump.is_enabled = ( dizel_startup || Mains );
|
FuelPump.is_enabled = ( dizel_startup || Mains );
|
||||||
}
|
}
|
||||||
FuelPump.is_active = (
|
FuelPump.is_active = (
|
||||||
( true == FuelPump.is_enabled )
|
( true == Battery )
|
||||||
&& ( true == Battery ) );
|
&& ( true == FuelPump.is_enabled ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// oil pump status update
|
// oil pump status update
|
||||||
@@ -1611,10 +1611,9 @@ void TMoverParameters::OilPumpCheck( double const Timestep ) {
|
|||||||
OilPump.pressure_minimum > 0.f ?
|
OilPump.pressure_minimum > 0.f ?
|
||||||
OilPump.pressure_minimum :
|
OilPump.pressure_minimum :
|
||||||
0.15f }; // arbitrary fallback value
|
0.15f }; // arbitrary fallback value
|
||||||
auto const maxpressure { 0.65f }; // arbitrary value
|
|
||||||
|
|
||||||
OilPump.pressure_target = (
|
OilPump.pressure_target = (
|
||||||
enrot > 0.1 ? interpolate( minpressure, maxpressure, static_cast<float>( clamp( enrot / maxrevolutions, 0.0, 1.0 ) ) ) * OilPump.resource_amount :
|
enrot > 0.1 ? interpolate( minpressure, OilPump.pressure_maximum, static_cast<float>( clamp( enrot / maxrevolutions, 0.0, 1.0 ) ) ) * OilPump.resource_amount :
|
||||||
true == OilPump.is_active ? minpressure :
|
true == OilPump.is_active ? minpressure :
|
||||||
0.f );
|
0.f );
|
||||||
|
|
||||||
@@ -6318,6 +6317,8 @@ void TMoverParameters::dizel_Heat( double const dt ) {
|
|||||||
auto const gwmin2 { 400.0 };
|
auto const gwmin2 { 400.0 };
|
||||||
auto const gwmax2 { 4000.0 };
|
auto const gwmax2 { 4000.0 };
|
||||||
|
|
||||||
|
dizel_heat.Te = Global.AirTemperature;
|
||||||
|
|
||||||
auto const engineon { ( Mains ? 1 : 0 ) };
|
auto const engineon { ( Mains ? 1 : 0 ) };
|
||||||
auto const engineoff { ( Mains ? 0 : 1 ) };
|
auto const engineoff { ( Mains ? 0 : 1 ) };
|
||||||
auto const rpm { enrot * 60 };
|
auto const rpm { enrot * 60 };
|
||||||
@@ -6376,7 +6377,7 @@ void TMoverParameters::dizel_Heat( double const dt ) {
|
|||||||
// olej oddaje cieplo do wody gdy krazy przez wymiennik ciepla == wlaczona pompka lub silnik
|
// olej oddaje cieplo do wody gdy krazy przez wymiennik ciepla == wlaczona pompka lub silnik
|
||||||
auto const dTo { (
|
auto const dTo { (
|
||||||
dizel_heat.auxiliary_water_circuit ?
|
dizel_heat.auxiliary_water_circuit ?
|
||||||
( ( dizel_heat.kfo * ( dizel_heat.Ts - dizel_heat.To ) ) - ( dizel_heat.kfs * ( 0.3 ) * ( dizel_heat.To - dizel_heat.Tsr2 ) ) ) / ( gwO * Co ) :
|
( ( dizel_heat.kfo * ( dizel_heat.Ts - dizel_heat.To ) ) - ( dizel_heat.kfo2 * ( dizel_heat.To - dizel_heat.Tsr2 ) ) ) / ( gwO * Co ) :
|
||||||
( ( dizel_heat.kfo * ( dizel_heat.Ts - dizel_heat.To ) ) - ( dizel_heat.kfo2 * ( dizel_heat.To - dizel_heat.Tsr ) ) ) / ( gwO * Co ) ) };
|
( ( dizel_heat.kfo * ( dizel_heat.Ts - dizel_heat.To ) ) - ( dizel_heat.kfo2 * ( dizel_heat.To - dizel_heat.Tsr ) ) ) / ( gwO * Co ) ) };
|
||||||
dizel_heat.To += ( dTo * dt );
|
dizel_heat.To += ( dTo * dt );
|
||||||
|
|
||||||
@@ -6395,12 +6396,12 @@ void TMoverParameters::dizel_Heat( double const dt ) {
|
|||||||
dizel_heat.water_aux.is_warm = (
|
dizel_heat.water_aux.is_warm = (
|
||||||
( true == dizel_heat.cooling )
|
( true == dizel_heat.cooling )
|
||||||
|| ( ( true == Mains )
|
|| ( ( true == Mains )
|
||||||
&& ( BatteryVoltage > 70 ) /* && !bezpompy && !awaria_chlodzenia && !WS10 */
|
&& ( BatteryVoltage > ( 0.75 * NominalBatteryVoltage ) ) /* && !bezpompy && !awaria_chlodzenia && !WS10 */
|
||||||
&& ( dizel_heat.water_aux.config.temp_cooling > 0 )
|
&& ( dizel_heat.water_aux.config.temp_cooling > 0 )
|
||||||
&& ( dizel_heat.temperatura2 > dizel_heat.water_aux.config.temp_cooling - ( dizel_heat.water_aux.is_warm ? 8 : 0 ) ) ) );
|
&& ( dizel_heat.temperatura2 > dizel_heat.water_aux.config.temp_cooling - ( dizel_heat.water_aux.is_warm ? 8 : 0 ) ) ) );
|
||||||
auto const PTC2 { ( dizel_heat.water_aux.is_warm /*or PTC2p*/ ? 1 : 0 ) };
|
auto const PTC2 { ( dizel_heat.water_aux.is_warm /*or PTC2p*/ ? 1 : 0 ) };
|
||||||
dizel_heat.rpmwz2 = PTC2 * 80 * rpm / ( ( 0.5 * rpm ) + 500 );
|
dizel_heat.rpmwz2 = PTC2 * 80 * rpm / ( ( 0.5 * rpm ) + 500 );
|
||||||
dizel_heat.zaluzje2 = ( dizel_heat.water_aux.config.shutters ? PTC2 : true ); // no shutters is an equivalent to having them open
|
dizel_heat.zaluzje2 = ( dizel_heat.water_aux.config.shutters ? ( PTC2 == 1 ) : true ); // no shutters is an equivalent to having them open
|
||||||
auto const zaluzje2 { ( dizel_heat.zaluzje2 ? 1 : 0 ) };
|
auto const zaluzje2 { ( dizel_heat.zaluzje2 ? 1 : 0 ) };
|
||||||
// auxiliary water circuit heat transfer values
|
// auxiliary water circuit heat transfer values
|
||||||
auto const kf2 { kurek07 * ( ( dizel_heat.kw * ( 0.3 + 0.7 * zaluzje2 ) ) * dizel_heat.rpmw2 + ( dizel_heat.kv * ( 0.3 + 0.7 * zaluzje2 ) * Vel / 3.6 ) ) + 2 };
|
auto const kf2 { kurek07 * ( ( dizel_heat.kw * ( 0.3 + 0.7 * zaluzje2 ) ) * dizel_heat.rpmw2 + ( dizel_heat.kv * ( 0.3 + 0.7 * zaluzje2 ) * Vel / 3.6 ) ) + 2 };
|
||||||
@@ -6423,12 +6424,12 @@ void TMoverParameters::dizel_Heat( double const dt ) {
|
|||||||
dizel_heat.water.is_warm = (
|
dizel_heat.water.is_warm = (
|
||||||
( true == dizel_heat.cooling )
|
( true == dizel_heat.cooling )
|
||||||
|| ( ( true == Mains )
|
|| ( ( true == Mains )
|
||||||
&& ( BatteryVoltage > 70 ) /* && !bezpompy && !awaria_chlodzenia && !WS10 */
|
&& ( BatteryVoltage > ( 0.75 * NominalBatteryVoltage ) ) /* && !bezpompy && !awaria_chlodzenia && !WS10 */
|
||||||
&& ( dizel_heat.water.config.temp_cooling > 0 )
|
&& ( dizel_heat.water.config.temp_cooling > 0 )
|
||||||
&& ( dizel_heat.temperatura1 > dizel_heat.water.config.temp_cooling - ( dizel_heat.water.is_warm ? 8 : 0 ) ) ) );
|
&& ( dizel_heat.temperatura1 > dizel_heat.water.config.temp_cooling - ( dizel_heat.water.is_warm ? 8 : 0 ) ) ) );
|
||||||
auto const PTC1 { ( dizel_heat.water.is_warm /*or PTC1p*/ ? 1 : 0 ) };
|
auto const PTC1 { ( dizel_heat.water.is_warm /*or PTC1p*/ ? 1 : 0 ) };
|
||||||
dizel_heat.rpmwz = PTC1 * 80 * rpm / ( ( 0.5 * rpm ) + 500 );
|
dizel_heat.rpmwz = PTC1 * 80 * rpm / ( ( 0.5 * rpm ) + 500 );
|
||||||
dizel_heat.zaluzje1 = ( dizel_heat.water.config.shutters ? PTC1 : true ); // no shutters is an equivalent to having them open
|
dizel_heat.zaluzje1 = ( dizel_heat.water.config.shutters ? ( PTC1 == 1 ) : true ); // no shutters is an equivalent to having them open
|
||||||
auto const zaluzje1 { ( dizel_heat.zaluzje1 ? 1 : 0 ) };
|
auto const zaluzje1 { ( dizel_heat.zaluzje1 ? 1 : 0 ) };
|
||||||
// primary water circuit heat transfer values
|
// primary water circuit heat transfer values
|
||||||
auto const kf { obieg * kurek07 * ( ( dizel_heat.kw * ( 0.3 + 0.7 * zaluzje1 ) ) * dizel_heat.rpmw + ( dizel_heat.kv * ( 0.3 + 0.7 * zaluzje1 ) * Vel / 3.6 ) + 3 ) + 2 };
|
auto const kf { obieg * kurek07 * ( ( dizel_heat.kw * ( 0.3 + 0.7 * zaluzje1 ) ) * dizel_heat.rpmw + ( dizel_heat.kv * ( 0.3 + 0.7 * zaluzje1 ) * Vel / 3.6 ) + 3 ) + 2 };
|
||||||
@@ -6707,14 +6708,14 @@ TMoverParameters::update_autonomous_doors( double const Deltatime ) {
|
|||||||
// the door are closed if their timer goes below 0, or if the vehicle is moving at > 5 km/h
|
// the door are closed if their timer goes below 0, or if the vehicle is moving at > 5 km/h
|
||||||
// NOTE: timer value of 0 is 'special' as it means the door will stay open until vehicle is moving
|
// NOTE: timer value of 0 is 'special' as it means the door will stay open until vehicle is moving
|
||||||
if( true == DoorLeftOpened ) {
|
if( true == DoorLeftOpened ) {
|
||||||
if( ( DoorLeftOpenTimer < 0.0 )
|
if( ( ( DoorStayOpen > 0.0 ) && ( DoorLeftOpenTimer < 0.0 ) )
|
||||||
|| ( Vel > 5.0 ) ) {
|
|| ( Vel > 5.0 ) ) {
|
||||||
// close the door and set the timer to expired state (closing may happen sooner if vehicle starts moving)
|
// close the door and set the timer to expired state (closing may happen sooner if vehicle starts moving)
|
||||||
DoorLeft( false, range::local );
|
DoorLeft( false, range::local );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( true == DoorRightOpened ) {
|
if( true == DoorRightOpened ) {
|
||||||
if( ( DoorRightOpenTimer < 0.0 )
|
if( ( ( DoorStayOpen > 0.0 ) && ( DoorRightOpenTimer < 0.0 ) )
|
||||||
|| ( Vel > 5.0 ) ) {
|
|| ( Vel > 5.0 ) ) {
|
||||||
// close the door and set the timer to expired state (closing may happen sooner if vehicle starts moving)
|
// close the door and set the timer to expired state (closing may happen sooner if vehicle starts moving)
|
||||||
DoorRight( false, range::local );
|
DoorRight( false, range::local );
|
||||||
@@ -7786,6 +7787,7 @@ void TMoverParameters::LoadFIZ_Brake( std::string const &line ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extract_value( RapidMult, "RM", line, "1" );
|
extract_value( RapidMult, "RM", line, "1" );
|
||||||
|
extract_value( RapidVel, "RV", line, "55" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -7859,10 +7861,11 @@ void TMoverParameters::LoadFIZ_Doors( std::string const &line ) {
|
|||||||
|
|
||||||
extract_value( DoorOpenSpeed, "OpenSpeed", line, "" );
|
extract_value( DoorOpenSpeed, "OpenSpeed", line, "" );
|
||||||
extract_value( DoorCloseSpeed, "CloseSpeed", line, "" );
|
extract_value( DoorCloseSpeed, "CloseSpeed", line, "" );
|
||||||
|
extract_value( DoorCloseDelay, "DoorCloseDelay", line, "" );
|
||||||
extract_value( DoorMaxShiftL, "DoorMaxShiftL", line, "" );
|
extract_value( DoorMaxShiftL, "DoorMaxShiftL", line, "" );
|
||||||
extract_value( DoorMaxShiftR, "DoorMaxShiftR", line, "" );
|
extract_value( DoorMaxShiftR, "DoorMaxShiftR", line, "" );
|
||||||
|
extract_value( DoorMaxPlugShift, "DoorMaxShiftPlug", line, "" );
|
||||||
|
|
||||||
DoorOpenMethod = 2; //obrót, default
|
|
||||||
std::string openmethod; extract_value( openmethod, "DoorOpenMethod", line, "" );
|
std::string openmethod; extract_value( openmethod, "DoorOpenMethod", line, "" );
|
||||||
if( openmethod == "Shift" ) { DoorOpenMethod = 1; } //przesuw
|
if( openmethod == "Shift" ) { DoorOpenMethod = 1; } //przesuw
|
||||||
else if( openmethod == "Fold" ) { DoorOpenMethod = 3; } //3 submodele się obracają
|
else if( openmethod == "Fold" ) { DoorOpenMethod = 3; } //3 submodele się obracają
|
||||||
@@ -7874,11 +7877,11 @@ void TMoverParameters::LoadFIZ_Doors( std::string const &line ) {
|
|||||||
std::string doorblocked; extract_value( doorblocked, "DoorBlocked", line, "" );
|
std::string doorblocked; extract_value( doorblocked, "DoorBlocked", line, "" );
|
||||||
DoorBlocked = ( doorblocked == "Yes" );
|
DoorBlocked = ( doorblocked == "Yes" );
|
||||||
|
|
||||||
extract_value( DoorMaxPlugShift, "DoorMaxShiftPlug", line, "" );
|
|
||||||
extract_value( PlatformSpeed, "PlatformSpeed", line, "" );
|
extract_value( PlatformSpeed, "PlatformSpeed", line, "" );
|
||||||
extract_value( PlatformMaxShift, "PlatformMaxSpeed", line, "" );
|
extract_value( PlatformMaxShift, "PlatformMaxShift", line, "" );
|
||||||
|
|
||||||
|
extract_value( MirrorMaxShift, "MirrorMaxShift", line, "" );
|
||||||
|
|
||||||
PlatformOpenMethod = 2; // obrót, default
|
|
||||||
std::string platformopenmethod; extract_value( platformopenmethod, "PlatformOpenMethod", line, "" );
|
std::string platformopenmethod; extract_value( platformopenmethod, "PlatformOpenMethod", line, "" );
|
||||||
if( platformopenmethod == "Shift" ) { PlatformOpenMethod = 1; } // przesuw
|
if( platformopenmethod == "Shift" ) { PlatformOpenMethod = 1; } // przesuw
|
||||||
}
|
}
|
||||||
@@ -8113,9 +8116,9 @@ void TMoverParameters::LoadFIZ_Cntrl( std::string const &line ) {
|
|||||||
else if( autorelay == "Yes" ) { AutoRelayType = 1; }
|
else if( autorelay == "Yes" ) { AutoRelayType = 1; }
|
||||||
else { AutoRelayType = 0; }
|
else { AutoRelayType = 0; }
|
||||||
|
|
||||||
CoupledCtrl = ( extract_value( "CoupledCtrl", line ) == "Yes" );
|
extract_value( CoupledCtrl, "CoupledCtrl", line, "" );
|
||||||
|
|
||||||
ScndS = ( extract_value( "ScndS", line ) == "Yes" ); // brak pozycji rownoleglej przy niskiej nastawie PSR
|
extract_value( ScndS, "ScndS", line, "" ); // brak pozycji rownoleglej przy niskiej nastawie PSR
|
||||||
|
|
||||||
extract_value( InitialCtrlDelay, "IniCDelay", line, "" );
|
extract_value( InitialCtrlDelay, "IniCDelay", line, "" );
|
||||||
extract_value( CtrlDelay, "SCDelay", line, "" );
|
extract_value( CtrlDelay, "SCDelay", line, "" );
|
||||||
@@ -8207,8 +8210,8 @@ void TMoverParameters::LoadFIZ_Blending(std::string const &line) {
|
|||||||
extract_value(MED_Vmin, "MED_Vmin", line, "0");
|
extract_value(MED_Vmin, "MED_Vmin", line, "0");
|
||||||
extract_value(MED_Vref, "MED_Vref", line, to_string(Vmax));
|
extract_value(MED_Vref, "MED_Vref", line, to_string(Vmax));
|
||||||
extract_value(MED_amax, "MED_amax", line, "9.81");
|
extract_value(MED_amax, "MED_amax", line, "9.81");
|
||||||
MED_EPVC = (extract_value("MED_EPVC", line).find("Yes") != std::string::npos);
|
extract_value(MED_EPVC, "MED_EPVC", line, "");
|
||||||
MED_Ncor = (extract_value("MED_Ncor", line).find("Yes") != std::string::npos);
|
extract_value(MED_Ncor, "MED_Ncor", line, "");
|
||||||
|
|
||||||
}
|
}
|
||||||
void TMoverParameters::LoadFIZ_Light( std::string const &line ) {
|
void TMoverParameters::LoadFIZ_Light( std::string const &line ) {
|
||||||
@@ -8239,7 +8242,7 @@ void TMoverParameters::LoadFIZ_Security( std::string const &line ) {
|
|||||||
extract_value( SecuritySystem.AwareMinSpeed, "AwareMinSpeed", line, "" );
|
extract_value( SecuritySystem.AwareMinSpeed, "AwareMinSpeed", line, "" );
|
||||||
extract_value( SecuritySystem.SoundSignalDelay, "SoundSignalDelay", line, "" );
|
extract_value( SecuritySystem.SoundSignalDelay, "SoundSignalDelay", line, "" );
|
||||||
extract_value( SecuritySystem.EmergencyBrakeDelay, "EmergencyBrakeDelay", line, "" );
|
extract_value( SecuritySystem.EmergencyBrakeDelay, "EmergencyBrakeDelay", line, "" );
|
||||||
SecuritySystem.RadioStop = ( extract_value( "RadioStop", line ).find( "Yes" ) != std::string::npos );
|
extract_value( SecuritySystem.RadioStop, "RadioStop", line, "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TMoverParameters::LoadFIZ_Clima( std::string const &line ) {
|
void TMoverParameters::LoadFIZ_Clima( std::string const &line ) {
|
||||||
@@ -8318,7 +8321,6 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
// TODO: unify naming scheme and sort out which diesel engine params are used where and how
|
// TODO: unify naming scheme and sort out which diesel engine params are used where and how
|
||||||
extract_value( nmax, "nmax", Input, "" );
|
extract_value( nmax, "nmax", Input, "" );
|
||||||
nmax /= 60.0;
|
nmax /= 60.0;
|
||||||
// nmax = dizel_nmax; // not sure if this is needed, but just in case
|
|
||||||
extract_value( dizel_nmax_cutoff, "nmax_cutoff", Input, "0.0" );
|
extract_value( dizel_nmax_cutoff, "nmax_cutoff", Input, "0.0" );
|
||||||
dizel_nmax_cutoff /= 60.0;
|
dizel_nmax_cutoff /= 60.0;
|
||||||
extract_value( dizel_AIM, "AIM", Input, "1.0" );
|
extract_value( dizel_AIM, "AIM", Input, "1.0" );
|
||||||
@@ -8336,7 +8338,7 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
hydro_TC = (extract_value("IsTC", Input) == "Yes");
|
extract_value(hydro_TC, "IsTC", Input, "");
|
||||||
if (true == hydro_TC) {
|
if (true == hydro_TC) {
|
||||||
extract_value(hydro_TC_TMMax, "TC_TMMax", Input, "");
|
extract_value(hydro_TC_TMMax, "TC_TMMax", Input, "");
|
||||||
extract_value(hydro_TC_CouplingPoint, "TC_CP", Input, "");
|
extract_value(hydro_TC_CouplingPoint, "TC_CP", Input, "");
|
||||||
@@ -8351,7 +8353,7 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
extract_value(hydro_TC_LockupSpeed, "TC_LS", Input, "");
|
extract_value(hydro_TC_LockupSpeed, "TC_LS", Input, "");
|
||||||
extract_value(hydro_TC_UnlockSpeed, "TC_ULS", Input, "");
|
extract_value(hydro_TC_UnlockSpeed, "TC_ULS", Input, "");
|
||||||
|
|
||||||
hydro_R = (extract_value("IsRetarder", Input) == "Yes");
|
extract_value(hydro_R, "IsRetarder", Input, "");
|
||||||
if (true == hydro_R) {
|
if (true == hydro_R) {
|
||||||
extract_value(hydro_R_Placement, "R_Place", Input, "");
|
extract_value(hydro_R_Placement, "R_Place", Input, "");
|
||||||
extract_value(hydro_R_TorqueInIn, "R_TII", Input, "");
|
extract_value(hydro_R_TorqueInIn, "R_TII", Input, "");
|
||||||
@@ -8362,7 +8364,6 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
extract_value(hydro_R_MinVel, "R_MinVel", Input, "");
|
extract_value(hydro_R_MinVel, "R_MinVel", Input, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extract_value( OilPump.pressure_minimum, "MinOilPressure", Input, "" );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DieselElectric: { //youBy
|
case DieselElectric: { //youBy
|
||||||
@@ -8383,7 +8384,6 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
ImaxHi = 2;
|
ImaxHi = 2;
|
||||||
ImaxLo = 1;
|
ImaxLo = 1;
|
||||||
}
|
}
|
||||||
extract_value( OilPump.pressure_minimum, "OilMinPressure", Input, "" );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ElectricInductionMotor: {
|
case ElectricInductionMotor: {
|
||||||
@@ -8412,7 +8412,7 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
extract_value( eimc[ eimc_p_Imax ], "Imax", Input, "" );
|
extract_value( eimc[ eimc_p_Imax ], "Imax", Input, "" );
|
||||||
extract_value( eimc[ eimc_p_abed ], "abed", Input, "" );
|
extract_value( eimc[ eimc_p_abed ], "abed", Input, "" );
|
||||||
extract_value( eimc[ eimc_p_eped ], "edep", Input, "" );
|
extract_value( eimc[ eimc_p_eped ], "edep", Input, "" );
|
||||||
EIMCLogForce = ( extract_value( "eimclf", Input ) == "Yes" );
|
extract_value( EIMCLogForce, "eimclf", Input, "" );
|
||||||
|
|
||||||
Flat = ( extract_value( "Flat", Input ) == "1" );
|
Flat = ( extract_value( "Flat", Input ) == "1" );
|
||||||
|
|
||||||
@@ -8423,29 +8423,36 @@ void TMoverParameters::LoadFIZ_Engine( std::string const &Input ) {
|
|||||||
}
|
}
|
||||||
} // engine type
|
} // engine type
|
||||||
|
|
||||||
// engine cooling factore
|
// NOTE: elements shared by both diesel engine variants; crude but, eh
|
||||||
extract_value( dizel_heat.kw, "HeatKW", Input, "" );
|
if( ( EngineType == DieselEngine )
|
||||||
extract_value( dizel_heat.kv, "HeatKV", Input, "" );
|
|| ( EngineType == DieselElectric ) ) {
|
||||||
extract_value( dizel_heat.kfe, "HeatKFE", Input, "" );
|
// oil pump
|
||||||
extract_value( dizel_heat.kfs, "HeatKFS", Input, "" );
|
extract_value( OilPump.pressure_minimum, "OilMinPressure", Input, "" );
|
||||||
extract_value( dizel_heat.kfo, "HeatKFO", Input, "" );
|
extract_value( OilPump.pressure_maximum, "OilMaxPressure", Input, "" );
|
||||||
extract_value( dizel_heat.kfo2, "HeatKFO2", Input, "" );
|
// engine cooling factore
|
||||||
// engine cooling systems
|
extract_value( dizel_heat.kw, "HeatKW", Input, "" );
|
||||||
extract_value( dizel_heat.water.config.temp_min, "WaterMinTemperature", Input, "" );
|
extract_value( dizel_heat.kv, "HeatKV", Input, "" );
|
||||||
extract_value( dizel_heat.water.config.temp_max, "WaterMaxTemperature", Input, "" );
|
extract_value( dizel_heat.kfe, "HeatKFE", Input, "" );
|
||||||
extract_value( dizel_heat.water.config.temp_flow, "WaterFlowTemperature", Input, "" );
|
extract_value( dizel_heat.kfs, "HeatKFS", Input, "" );
|
||||||
extract_value( dizel_heat.water.config.temp_cooling, "WaterCoolingTemperature", Input, "" );
|
extract_value( dizel_heat.kfo, "HeatKFO", Input, "" );
|
||||||
extract_value( dizel_heat.water.config.shutters, "WaterShutters", Input, "" );
|
extract_value( dizel_heat.kfo2, "HeatKFO2", Input, "" );
|
||||||
extract_value( dizel_heat.auxiliary_water_circuit, "WaterAuxCircuit", Input, "" );
|
// engine cooling systems
|
||||||
extract_value( dizel_heat.water_aux.config.temp_min, "WaterAuxMinTemperature", Input, "" );
|
extract_value( dizel_heat.water.config.temp_min, "WaterMinTemperature", Input, "" );
|
||||||
extract_value( dizel_heat.water_aux.config.temp_max, "WaterAuxMaxTemperature", Input, "" );
|
extract_value( dizel_heat.water.config.temp_max, "WaterMaxTemperature", Input, "" );
|
||||||
extract_value( dizel_heat.water_aux.config.temp_cooling, "WaterAuxCoolingTemperature", Input, "" );
|
extract_value( dizel_heat.water.config.temp_flow, "WaterFlowTemperature", Input, "" );
|
||||||
extract_value( dizel_heat.water_aux.config.shutters, "WaterAuxShutters", Input, "" );
|
extract_value( dizel_heat.water.config.temp_cooling, "WaterCoolingTemperature", Input, "" );
|
||||||
extract_value( dizel_heat.oil.config.temp_min, "OilMinTemperature", Input, "" );
|
extract_value( dizel_heat.water.config.shutters, "WaterShutters", Input, "" );
|
||||||
extract_value( dizel_heat.oil.config.temp_max, "OilMaxTemperature", Input, "" );
|
extract_value( dizel_heat.auxiliary_water_circuit, "WaterAuxCircuit", Input, "" );
|
||||||
// water heater
|
extract_value( dizel_heat.water_aux.config.temp_min, "WaterAuxMinTemperature", Input, "" );
|
||||||
extract_value( WaterHeater.config.temp_min, "HeaterMinTemperature", Input, "" );
|
extract_value( dizel_heat.water_aux.config.temp_max, "WaterAuxMaxTemperature", Input, "" );
|
||||||
extract_value( WaterHeater.config.temp_max, "HeaterMaxTemperature", Input, "" );
|
extract_value( dizel_heat.water_aux.config.temp_cooling, "WaterAuxCoolingTemperature", Input, "" );
|
||||||
|
extract_value( dizel_heat.water_aux.config.shutters, "WaterAuxShutters", Input, "" );
|
||||||
|
extract_value( dizel_heat.oil.config.temp_min, "OilMinTemperature", Input, "" );
|
||||||
|
extract_value( dizel_heat.oil.config.temp_max, "OilMaxTemperature", Input, "" );
|
||||||
|
// water heater
|
||||||
|
extract_value( WaterHeater.config.temp_min, "HeaterMinTemperature", Input, "" );
|
||||||
|
extract_value( WaterHeater.config.temp_max, "HeaterMaxTemperature", Input, "" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TMoverParameters::LoadFIZ_Switches( std::string const &Input ) {
|
void TMoverParameters::LoadFIZ_Switches( std::string const &Input ) {
|
||||||
@@ -8771,6 +8778,7 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
|
|||||||
WriteLog( "XBT EStED" );
|
WriteLog( "XBT EStED" );
|
||||||
Hamulec = std::make_shared<TEStED>( MaxBrakePress[ 3 ], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA );
|
Hamulec = std::make_shared<TEStED>( MaxBrakePress[ 3 ], BrakeCylRadius, BrakeCylDist, BrakeVVolume, BrakeCylNo, BrakeDelays, BrakeMethod, NAxles, NBpA );
|
||||||
Hamulec->SetRM( RapidMult );
|
Hamulec->SetRM( RapidMult );
|
||||||
|
Hamulec->SetRV( RapidVel );
|
||||||
if( MBPM < 2 ) {
|
if( MBPM < 2 ) {
|
||||||
//jesli przystawka wazaca
|
//jesli przystawka wazaca
|
||||||
Hamulec->SetLP( 0, MaxBrakePress[ 3 ], 0 );
|
Hamulec->SetLP( 0, MaxBrakePress[ 3 ], 0 );
|
||||||
@@ -9298,9 +9306,9 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
}
|
}
|
||||||
else if (Command == "DoorOpen") /*NBMX*/
|
else if (Command == "DoorOpen") /*NBMX*/
|
||||||
{ // Ra: uwzględnić trzeba jeszcze zgodność sprzęgów
|
{ // Ra: uwzględnić trzeba jeszcze zgodność sprzęgów
|
||||||
if( ( DoorCloseCtrl == control::conductor )
|
if( ( DoorOpenCtrl == control::conductor )
|
||||||
|| ( DoorCloseCtrl == control::driver )
|
|| ( DoorOpenCtrl == control::driver )
|
||||||
|| ( DoorCloseCtrl == control::mixed ) ) {
|
|| ( DoorOpenCtrl == control::mixed ) ) {
|
||||||
// ignore remote command if the door is only operated locally
|
// ignore remote command if the door is only operated locally
|
||||||
if( CValue2 > 0 ) {
|
if( CValue2 > 0 ) {
|
||||||
// normalne ustawienie pojazdu
|
// normalne ustawienie pojazdu
|
||||||
|
|||||||
@@ -1514,7 +1514,7 @@ double TEStED::GetPF( double const PP, double const dt, double const Vel )
|
|||||||
Miedzypoj->Flow(dv * dt * 0.15);
|
Miedzypoj->Flow(dv * dt * 0.15);
|
||||||
|
|
||||||
RapidTemp =
|
RapidTemp =
|
||||||
RapidTemp + (RM * int((Vel > 55) && (BrakeDelayFlag == bdelay_R)) - RapidTemp) * dt / 2;
|
RapidTemp + (RM * int((Vel > RV) && (BrakeDelayFlag == bdelay_R)) - RapidTemp) * dt / 2;
|
||||||
temp = Max0R(1 - RapidTemp, 0.001);
|
temp = Max0R(1 - RapidTemp, 0.001);
|
||||||
// if EDFlag then temp:=1000;
|
// if EDFlag then temp:=1000;
|
||||||
// temp:=temp/(1-);
|
// temp:=temp/(1-);
|
||||||
@@ -1636,6 +1636,11 @@ void TEStED::SetLP( double const TM, double const LM, double const TBP )
|
|||||||
TareBP = TBP;
|
TareBP = TBP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TEStED::SetRV(double const RVR)
|
||||||
|
{
|
||||||
|
RV = RVR;
|
||||||
|
}
|
||||||
|
|
||||||
//---DAKO CV1---
|
//---DAKO CV1---
|
||||||
|
|
||||||
void TCV1::CheckState( double const BCP, double &dV1 )
|
void TCV1::CheckState( double const BCP, double &dV1 )
|
||||||
|
|||||||
@@ -204,6 +204,7 @@ class TBrake {
|
|||||||
void Releaser( int const state ); //odluzniacz
|
void Releaser( int const state ); //odluzniacz
|
||||||
virtual void SetEPS( double const nEPS ); //hamulec EP
|
virtual void SetEPS( double const nEPS ); //hamulec EP
|
||||||
virtual void SetRM( double const RMR ) {}; //ustalenie przelozenia rapida
|
virtual void SetRM( double const RMR ) {}; //ustalenie przelozenia rapida
|
||||||
|
virtual void SetRV( double const RVR) {}; //ustalenie przelozenia rapida
|
||||||
virtual void SetLP(double const TM, double const LM, double const TBP) {}; //parametry przystawki wazacej
|
virtual void SetLP(double const TM, double const LM, double const TBP) {}; //parametry przystawki wazacej
|
||||||
virtual void SetLBP(double const P) {}; //cisnienie z hamulca pomocniczego
|
virtual void SetLBP(double const P) {}; //cisnienie z hamulca pomocniczego
|
||||||
virtual void PLC(double const mass) {}; //wspolczynnik cisnienia przystawki wazacej
|
virtual void PLC(double const mass) {}; //wspolczynnik cisnienia przystawki wazacej
|
||||||
@@ -333,6 +334,7 @@ class TLSt : public TESt4R {
|
|||||||
protected:
|
protected:
|
||||||
double LBP = 0.0; //cisnienie hamulca pomocniczego
|
double LBP = 0.0; //cisnienie hamulca pomocniczego
|
||||||
double RM = 0.0; //przelozenie rapida
|
double RM = 0.0; //przelozenie rapida
|
||||||
|
double RV = 0.0;
|
||||||
double EDFlag = 0.0; //luzowanie hamulca z powodu zalaczonego ED
|
double EDFlag = 0.0; //luzowanie hamulca z powodu zalaczonego ED
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -368,6 +370,7 @@ class TEStED : public TLSt { //zawor z EP09 - Est4 z oddzielnym przekladnikiem,
|
|||||||
double GetEDBCP()/*override*/; //cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED
|
double GetEDBCP()/*override*/; //cisnienie tylko z hamulca zasadniczego, uzywane do hamulca ED
|
||||||
void PLC(double const mass); //wspolczynnik cisnienia przystawki wazacej
|
void PLC(double const mass); //wspolczynnik cisnienia przystawki wazacej
|
||||||
void SetLP( double const TM, double const LM, double const TBP ); //parametry przystawki wazacej
|
void SetLP( double const TM, double const LM, double const TBP ); //parametry przystawki wazacej
|
||||||
|
void SetRV(double const RVR); //ustalenie predkosci przelaczenia rapida
|
||||||
|
|
||||||
inline TEStED(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) :
|
inline TEStED(double i_mbp, double i_bcr, double i_bcd, double i_brc, int i_bcn, int i_BD, int i_mat, int i_ba, int i_nbpa) :
|
||||||
TLSt( i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
|
TLSt( i_mbp, i_bcr, i_bcd, i_brc, i_bcn, i_BD, i_mat, i_ba, i_nbpa)
|
||||||
|
|||||||
@@ -1233,12 +1233,16 @@ TSubModel::offset( float const Geometrytestoffsetthreshold ) const {
|
|||||||
bool TModel3d::LoadFromFile(std::string const &FileName, bool dynamic)
|
bool TModel3d::LoadFromFile(std::string const &FileName, bool dynamic)
|
||||||
{
|
{
|
||||||
// wczytanie modelu z pliku
|
// wczytanie modelu z pliku
|
||||||
|
/*
|
||||||
|
// NOTE: disabled, this work is now done by the model manager
|
||||||
std::string name = ToLower(FileName);
|
std::string name = ToLower(FileName);
|
||||||
// trim extension if needed
|
// trim extension if needed
|
||||||
if( name.rfind( '.' ) != std::string::npos )
|
if( name.rfind( '.' ) != std::string::npos )
|
||||||
{
|
{
|
||||||
name.erase(name.rfind('.'));
|
name.erase(name.rfind('.'));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
auto const name { FileName };
|
||||||
|
|
||||||
asBinary = name + ".e3d";
|
asBinary = name + ".e3d";
|
||||||
if (FileExists(asBinary))
|
if (FileExists(asBinary))
|
||||||
@@ -1266,7 +1270,7 @@ bool TModel3d::LoadFromFile(std::string const &FileName, bool dynamic)
|
|||||||
Root ? (iSubModelsCount > 0) : false; // brak pliku albo problem z wczytaniem
|
Root ? (iSubModelsCount > 0) : false; // brak pliku albo problem z wczytaniem
|
||||||
if (false == result)
|
if (false == result)
|
||||||
{
|
{
|
||||||
ErrorLog("Bad model: failed to load 3d model \"" + FileName + "\"");
|
ErrorLog("Bad model: failed to load 3d model \"" + name + "\"");
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|||||||
18
PyInt.cpp
18
PyInt.cpp
@@ -1,6 +1,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "PyInt.h"
|
#include "PyInt.h"
|
||||||
|
|
||||||
|
#include "Globals.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "Model3d.h"
|
#include "Model3d.h"
|
||||||
@@ -456,6 +457,7 @@ void TPythonScreens::init(cParser &parser, TModel3d *model, std::string const &n
|
|||||||
WriteLog( "Python Screen: null renderer for " + pyClassName + " - Ignoring screen" );
|
WriteLog( "Python Screen: null renderer for " + pyClassName + " - Ignoring screen" );
|
||||||
return; // nie mozna utworzyc obiektu Pythonowego
|
return; // nie mozna utworzyc obiektu Pythonowego
|
||||||
}
|
}
|
||||||
|
m_updaterate = Global.PythonScreenUpdateRate;
|
||||||
TPythonScreenRenderer *renderer = new TPythonScreenRenderer(textureId, pyRenderer);
|
TPythonScreenRenderer *renderer = new TPythonScreenRenderer(textureId, pyRenderer);
|
||||||
_screens.push_back(renderer);
|
_screens.push_back(renderer);
|
||||||
WriteLog( "Created python screen " + pyClassName + " on submodel " + subModelName + " (" + std::to_string(textureId) + ")" );
|
WriteLog( "Created python screen " + pyClassName + " on submodel " + subModelName + " (" + std::to_string(textureId) + ")" );
|
||||||
@@ -484,10 +486,6 @@ void TPythonScreens::setLookupPath(std::string const &path)
|
|||||||
TPythonScreens::TPythonScreens()
|
TPythonScreens::TPythonScreens()
|
||||||
{
|
{
|
||||||
TPythonInterpreter::getInstance()->loadClassFile("", "abstractscreenrenderer");
|
TPythonInterpreter::getInstance()->loadClassFile("", "abstractscreenrenderer");
|
||||||
_terminationFlag = false;
|
|
||||||
_renderReadyFlag = false;
|
|
||||||
_cleanupReadyFlag = false;
|
|
||||||
_thread = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TPythonScreens::~TPythonScreens()
|
TPythonScreens::~TPythonScreens()
|
||||||
@@ -511,6 +509,7 @@ void TPythonScreens::run()
|
|||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
m_updatestopwatch.start();
|
||||||
if (_terminationFlag)
|
if (_terminationFlag)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@@ -534,12 +533,17 @@ void TPythonScreens::run()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_renderReadyFlag = true;
|
_renderReadyFlag = true;
|
||||||
|
m_updatestopwatch.stop();
|
||||||
while (!_cleanupReadyFlag && !_terminationFlag)
|
while (!_cleanupReadyFlag && !_terminationFlag)
|
||||||
{
|
{
|
||||||
|
auto const sleeptime {
|
||||||
|
std::max(
|
||||||
|
100,
|
||||||
|
m_updaterate - static_cast<int>( m_updatestopwatch.average() ) ) };
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
Sleep(100);
|
Sleep( sleeptime );
|
||||||
#elif __linux__
|
#elif __linux__
|
||||||
usleep(100*1000);
|
usleep( sleeptime * 1000 );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (_terminationFlag)
|
if (_terminationFlag)
|
||||||
@@ -552,7 +556,7 @@ void TPythonScreens::run()
|
|||||||
|
|
||||||
void TPythonScreens::finish()
|
void TPythonScreens::finish()
|
||||||
{
|
{
|
||||||
_thread = NULL;
|
// nothing to do here, proper clean up takes place afterwards
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreenRendererThread(TPythonScreens* renderer)
|
void ScreenRendererThread(TPythonScreens* renderer)
|
||||||
|
|||||||
26
PyInt.h
26
PyInt.h
@@ -17,6 +17,7 @@
|
|||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#endif
|
#endif
|
||||||
#include "Classes.h"
|
#include "Classes.h"
|
||||||
|
#include "Timer.h"
|
||||||
|
|
||||||
#define PyGetFloat(param) PyFloat_FromDouble(param >= 0 ? param : -param)
|
#define PyGetFloat(param) PyFloat_FromDouble(param >= 0 ? param : -param)
|
||||||
#define PyGetFloatS(param) PyFloat_FromDouble(param)
|
#define PyGetFloatS(param) PyFloat_FromDouble(param)
|
||||||
@@ -25,34 +26,21 @@
|
|||||||
#define PyGetBool(param) param ? Py_True : Py_False
|
#define PyGetBool(param) param ? Py_True : Py_False
|
||||||
#define PyGetString(param) PyString_FromString(param)
|
#define PyGetString(param) PyString_FromString(param)
|
||||||
|
|
||||||
struct ltstr
|
|
||||||
{
|
|
||||||
bool operator()(const char *s1, const char *s2) const
|
|
||||||
{
|
|
||||||
return strcmp(s1, s2) < 0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class TPythonInterpreter
|
class TPythonInterpreter
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
TPythonInterpreter();
|
TPythonInterpreter();
|
||||||
~TPythonInterpreter() {}
|
~TPythonInterpreter() {}
|
||||||
static TPythonInterpreter *_instance;
|
static TPythonInterpreter *_instance;
|
||||||
// std::set<const char *, ltstr> _classes;
|
|
||||||
std::set<std::string> _classes;
|
std::set<std::string> _classes;
|
||||||
PyObject *_main;
|
PyObject *_main;
|
||||||
PyObject *_stdErr;
|
PyObject *_stdErr;
|
||||||
// FILE *_getFile(const char *lookupPath, const char *className);
|
|
||||||
FILE *_getFile( std::string const &lookupPath, std::string const &className );
|
FILE *_getFile( std::string const &lookupPath, std::string const &className );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static TPythonInterpreter *getInstance();
|
static TPythonInterpreter *getInstance();
|
||||||
static void killInstance();
|
static void killInstance();
|
||||||
/* bool loadClassFile(const char *lookupPath, const char *className);
|
bool loadClassFile( std::string const &lookupPath, std::string const &className );
|
||||||
PyObject *newClass(const char *className);
|
|
||||||
PyObject *newClass(const char *className, PyObject *argsTuple);
|
|
||||||
*/ bool loadClassFile( std::string const &lookupPath, std::string const &className );
|
|
||||||
PyObject *newClass( std::string const &className );
|
PyObject *newClass( std::string const &className );
|
||||||
PyObject *newClass( std::string const &className, PyObject *argsTuple );
|
PyObject *newClass( std::string const &className, PyObject *argsTuple );
|
||||||
void handleError();
|
void handleError();
|
||||||
@@ -78,16 +66,18 @@ class TPythonScreenRenderer
|
|||||||
class TPythonScreens
|
class TPythonScreens
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
bool _cleanupReadyFlag;
|
bool _cleanupReadyFlag{ false };
|
||||||
bool _renderReadyFlag;
|
bool _renderReadyFlag{ false };
|
||||||
bool _terminationFlag;
|
bool _terminationFlag{ false };
|
||||||
std::thread *_thread;
|
std::thread *_thread{ nullptr };
|
||||||
std::vector<TPythonScreenRenderer *> _screens;
|
std::vector<TPythonScreenRenderer *> _screens;
|
||||||
std::string _lookupPath;
|
std::string _lookupPath;
|
||||||
void *_train;
|
void *_train;
|
||||||
void _cleanup();
|
void _cleanup();
|
||||||
void _freeTrainState();
|
void _freeTrainState();
|
||||||
PyObject *_trainState;
|
PyObject *_trainState;
|
||||||
|
int m_updaterate { 200 };
|
||||||
|
Timer::stopwatch m_updatestopwatch;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void reset(void *train);
|
void reset(void *train);
|
||||||
|
|||||||
280
Train.cpp
280
Train.cpp
@@ -23,6 +23,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "MdlMngr.h"
|
#include "MdlMngr.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Driver.h"
|
#include "Driver.h"
|
||||||
|
#include "mtable.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
|
||||||
@@ -309,6 +310,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
|||||||
{ user_command::departureannounce, &TTrain::OnCommand_departureannounce },
|
{ user_command::departureannounce, &TTrain::OnCommand_departureannounce },
|
||||||
{ user_command::hornlowactivate, &TTrain::OnCommand_hornlowactivate },
|
{ user_command::hornlowactivate, &TTrain::OnCommand_hornlowactivate },
|
||||||
{ user_command::hornhighactivate, &TTrain::OnCommand_hornhighactivate },
|
{ user_command::hornhighactivate, &TTrain::OnCommand_hornhighactivate },
|
||||||
|
{ user_command::whistleactivate, &TTrain::OnCommand_whistleactivate },
|
||||||
{ user_command::radiotoggle, &TTrain::OnCommand_radiotoggle },
|
{ user_command::radiotoggle, &TTrain::OnCommand_radiotoggle },
|
||||||
{ user_command::radiochannelincrease, &TTrain::OnCommand_radiochannelincrease },
|
{ user_command::radiochannelincrease, &TTrain::OnCommand_radiochannelincrease },
|
||||||
{ user_command::radiochanneldecrease, &TTrain::OnCommand_radiochanneldecrease },
|
{ user_command::radiochanneldecrease, &TTrain::OnCommand_radiochanneldecrease },
|
||||||
@@ -387,25 +389,18 @@ TTrain::~TTrain()
|
|||||||
|
|
||||||
bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d)
|
bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d)
|
||||||
{ // powiązanie ręcznego sterowania kabiną z pojazdem
|
{ // powiązanie ręcznego sterowania kabiną z pojazdem
|
||||||
// Global.pUserDynamic=NewDynamicObject; //pojazd renderowany bez trzęsienia
|
if( NewDynamicObject->Mechanik == nullptr ) {
|
||||||
|
ErrorLog( "Bad config: can't take control of inactive vehicle \"" + NewDynamicObject->asName + "\"" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
DynamicSet(NewDynamicObject);
|
DynamicSet(NewDynamicObject);
|
||||||
if (!e3d)
|
if (!e3d)
|
||||||
if (DynamicObject->Mechanik == NULL)
|
if (DynamicObject->Mechanik == NULL)
|
||||||
return false;
|
return false;
|
||||||
// if (DynamicObject->Mechanik->AIControllFlag==AIdriver)
|
|
||||||
// return false;
|
|
||||||
DynamicObject->MechInside = true;
|
DynamicObject->MechInside = true;
|
||||||
|
|
||||||
/* iPozSzereg=28;
|
|
||||||
for (int i=1; i<mvControlled->MainCtrlPosNo; i++)
|
|
||||||
{
|
|
||||||
if (mvControlled->RList[i].Bn>1)
|
|
||||||
{
|
|
||||||
iPozSzereg=i-1;
|
|
||||||
i=mvControlled->MainCtrlPosNo+1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
MechSpring.Init(125.0);
|
MechSpring.Init(125.0);
|
||||||
vMechVelocity = Math3D::vector3(0, 0, 0);
|
vMechVelocity = Math3D::vector3(0, 0, 0);
|
||||||
pMechOffset = Math3D::vector3( 0, 0, 0 );
|
pMechOffset = Math3D::vector3( 0, 0, 0 );
|
||||||
@@ -421,25 +416,6 @@ bool TTrain::Init(TDynamicObject *NewDynamicObject, bool e3d)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// McZapkie: w razie wykolejenia
|
|
||||||
// dsbDerailment=TSoundsManager::GetFromName("derail.wav");
|
|
||||||
// McZapkie: jazda luzem:
|
|
||||||
// dsbRunningNoise=TSoundsManager::GetFromName("runningnoise.wav");
|
|
||||||
|
|
||||||
// McZapkie? - dzwieki slyszalne tylko wewnatrz kabiny - generowane przez
|
|
||||||
// obiekt sterowany:
|
|
||||||
|
|
||||||
// McZapkie-080302 sWentylatory.Init("wenton.wav","went.wav","wentoff.wav");
|
|
||||||
// McZapkie-010302
|
|
||||||
// sCompressor.Init("compressor-start.wav","compressor.wav","compressor-stop.wav");
|
|
||||||
|
|
||||||
// sHorn1.Init("horn1.wav",0.3);
|
|
||||||
// sHorn2.Init("horn2.wav",0.3);
|
|
||||||
|
|
||||||
// sHorn1.Init("horn1-start.wav","horn1.wav","horn1-stop.wav");
|
|
||||||
// sHorn2.Init("horn2-start.wav","horn2.wav","horn2-stop.wav");
|
|
||||||
|
|
||||||
// sConverter.Init("converter.wav",1.5); //NBMX obsluga przez AdvSound
|
|
||||||
iCabn = 0;
|
iCabn = 0;
|
||||||
// Ra: taka proteza - przesłanie kierunku do członów connected
|
// Ra: taka proteza - przesłanie kierunku do członów connected
|
||||||
if (mvControlled->ActiveDir > 0)
|
if (mvControlled->ActiveDir > 0)
|
||||||
@@ -460,7 +436,7 @@ PyObject *TTrain::GetTrainState() {
|
|||||||
auto const &mover = DynamicObject->MoverParameters;
|
auto const &mover = DynamicObject->MoverParameters;
|
||||||
auto *dict = PyDict_New();
|
auto *dict = PyDict_New();
|
||||||
if( ( dict == nullptr )
|
if( ( dict == nullptr )
|
||||||
|| ( mover == nullptr ) ) {
|
|| ( mover == nullptr ) ) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,14 +456,14 @@ PyObject *TTrain::GetTrainState() {
|
|||||||
PyDict_SetItemString( dict, "scnd_ctrl_actual_pos", PyGetInt( mover->ScndCtrlActualPos ) );
|
PyDict_SetItemString( dict, "scnd_ctrl_actual_pos", PyGetInt( mover->ScndCtrlActualPos ) );
|
||||||
// brakes
|
// brakes
|
||||||
PyDict_SetItemString( dict, "manual_brake", PyGetBool( mvOccupied->ManualBrakePos > 0 ) );
|
PyDict_SetItemString( dict, "manual_brake", PyGetBool( mvOccupied->ManualBrakePos > 0 ) );
|
||||||
bool const bEP = ( mvControlled->LocHandle->GetCP()>0.2 ) || ( fEIMParams[ 0 ][ 2 ]>0.01 );
|
bool const bEP = ( mvControlled->LocHandle->GetCP() > 0.2 ) || ( fEIMParams[ 0 ][ 2 ] > 0.01 );
|
||||||
PyDict_SetItemString( dict, "dir_brake", PyGetBool( bEP ) );
|
PyDict_SetItemString( dict, "dir_brake", PyGetBool( bEP ) );
|
||||||
bool bPN;
|
bool bPN;
|
||||||
if( ( typeid( *mvControlled->Hamulec ) == typeid( TLSt ) )
|
if( ( typeid( *mvControlled->Hamulec ) == typeid( TLSt ) )
|
||||||
|| ( typeid( *mvControlled->Hamulec ) == typeid( TEStED ) ) ) {
|
|| ( typeid( *mvControlled->Hamulec ) == typeid( TEStED ) ) ) {
|
||||||
|
|
||||||
TBrake* temp_ham = mvControlled->Hamulec.get();
|
TBrake* temp_ham = mvControlled->Hamulec.get();
|
||||||
bPN = ( static_cast<TLSt*>( temp_ham )->GetEDBCP()>0.2 );
|
bPN = ( static_cast<TLSt*>( temp_ham )->GetEDBCP() > 0.2 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bPN = false;
|
bPN = false;
|
||||||
@@ -502,13 +478,13 @@ PyObject *TTrain::GetTrainState() {
|
|||||||
PyDict_SetItemString( dict, "velocity", PyGetFloat( mover->Vel ) );
|
PyDict_SetItemString( dict, "velocity", PyGetFloat( mover->Vel ) );
|
||||||
PyDict_SetItemString( dict, "tractionforce", PyGetFloat( mover->Ft ) );
|
PyDict_SetItemString( dict, "tractionforce", PyGetFloat( mover->Ft ) );
|
||||||
PyDict_SetItemString( dict, "slipping_wheels", PyGetBool( mover->SlippingWheels ) );
|
PyDict_SetItemString( dict, "slipping_wheels", PyGetBool( mover->SlippingWheels ) );
|
||||||
PyDict_SetItemString( dict, "sanding", PyGetBool( mover->SandDose ));
|
PyDict_SetItemString( dict, "sanding", PyGetBool( mover->SandDose ) );
|
||||||
// electric current data
|
// electric current data
|
||||||
PyDict_SetItemString( dict, "traction_voltage", PyGetFloat( mover->RunningTraction.TractionVoltage ) );
|
PyDict_SetItemString( dict, "traction_voltage", PyGetFloat( mover->RunningTraction.TractionVoltage ) );
|
||||||
PyDict_SetItemString( dict, "voltage", PyGetFloat( mover->Voltage ) );
|
PyDict_SetItemString( dict, "voltage", PyGetFloat( mover->Voltage ) );
|
||||||
PyDict_SetItemString( dict, "im", PyGetFloat( mover->Im ) );
|
PyDict_SetItemString( dict, "im", PyGetFloat( mover->Im ) );
|
||||||
PyDict_SetItemString( dict, "fuse", PyGetBool( mover->FuseFlag ) );
|
PyDict_SetItemString( dict, "fuse", PyGetBool( mover->FuseFlag ) );
|
||||||
PyDict_SetItemString( dict, "epfuse", PyGetBool( mover->EpFuse ));
|
PyDict_SetItemString( dict, "epfuse", PyGetBool( mover->EpFuse ) );
|
||||||
// induction motor state data
|
// induction motor state data
|
||||||
char const *TXTT[ 10 ] = { "fd", "fdt", "fdb", "pd", "pdt", "pdb", "itothv", "1", "2", "3" };
|
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" };
|
char const *TXTC[ 10 ] = { "fr", "frt", "frb", "pr", "prt", "prb", "im", "vm", "ihv", "uhv" };
|
||||||
@@ -517,23 +493,24 @@ PyObject *TTrain::GetTrainState() {
|
|||||||
PyDict_SetItemString( dict, ( std::string( "eimp_t_" ) + std::string( TXTT[ j ] ) ).c_str(), PyGetFloatS( fEIMParams[ 0 ][ j ] ) );
|
PyDict_SetItemString( dict, ( std::string( "eimp_t_" ) + std::string( TXTT[ j ] ) ).c_str(), PyGetFloatS( fEIMParams[ 0 ][ j ] ) );
|
||||||
for( int i = 0; i < 8; ++i ) {
|
for( int i = 0; i < 8; ++i ) {
|
||||||
for( int j = 0; j < 10; ++j )
|
for( int j = 0; j < 10; ++j )
|
||||||
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_" ) + std::string( TXTC[ j ] ) ).c_str(), PyGetFloatS( fEIMParams[ i + 1 ][ j ] ) );
|
PyDict_SetItemString( dict, ( "eimp_c" + std::to_string( i + 1 ) + "_" + std::string( TXTC[ j ] ) ).c_str(), PyGetFloatS( fEIMParams[ i + 1 ][ j ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_ms" ) ).c_str(), PyGetBool( bMains[ i ] ) );
|
|
||||||
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_cv" ) ).c_str(), PyGetFloatS( fCntVol[ i ] ) );
|
PyDict_SetItemString( dict, ( "eimp_c" + std::to_string( i + 1 ) + "_ms" ).c_str(), PyGetBool( bMains[ i ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "eimp_u" ) + std::to_string( i + 1 ) + std::string( "_pf" ) ).c_str(), PyGetBool( bPants[ i ][ 0 ] ) );
|
PyDict_SetItemString( dict, ( "eimp_c" + std::to_string( i + 1 ) + "_cv" ).c_str(), PyGetFloatS( fCntVol[ i ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "eimp_u" ) + std::to_string( i + 1 ) + std::string( "_pr" ) ).c_str(), PyGetBool( bPants[ i ][ 1 ] ) );
|
PyDict_SetItemString( dict, ( "eimp_u" + std::to_string( i + 1 ) + "_pf" ).c_str(), PyGetBool( bPants[ i ][ 0 ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_fuse" ) ).c_str(), PyGetBool( bFuse[ i ] ) );
|
PyDict_SetItemString( dict, ( "eimp_u" + std::to_string( i + 1 ) + "_pr" ).c_str(), PyGetBool( bPants[ i ][ 1 ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_batt" ) ).c_str(), PyGetBool( bBatt[ i ] ) );
|
PyDict_SetItemString( dict, ( "eimp_c" + std::to_string( i + 1 ) + "_fuse" ).c_str(), PyGetBool( bFuse[ i ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_conv" ) ).c_str(), PyGetBool( bConv[ i ] ) );
|
PyDict_SetItemString( dict, ( "eimp_c" + std::to_string( i + 1 ) + "_batt" ).c_str(), PyGetBool( bBatt[ i ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "eimp_u" ) + std::to_string( i + 1 ) + std::string( "_comp_a" ) ).c_str(), PyGetBool( bComp[ i ][ 0 ] ) );
|
PyDict_SetItemString( dict, ( "eimp_c" + std::to_string( i + 1 ) + "_conv" ).c_str(), PyGetBool( bConv[ i ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "eimp_u" ) + std::to_string( i + 1 ) + std::string( "_comp_w" ) ).c_str(), PyGetBool( bComp[ i ][ 1 ] ) );
|
PyDict_SetItemString( dict, ( "eimp_u" + std::to_string( i + 1 ) + "_comp_a" ).c_str(), PyGetBool( bComp[ i ][ 0 ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "eimp_c" ) + std::to_string( i + 1 ) + std::string( "_heat" ) ).c_str(), PyGetBool( bHeat[ i ] ) );
|
PyDict_SetItemString( dict, ( "eimp_u" + std::to_string( i + 1 ) + "_comp_w" ).c_str(), PyGetBool( bComp[ i ][ 1 ] ) );
|
||||||
|
PyDict_SetItemString( dict, ( "eimp_c" + std::to_string( i + 1 ) + "_heat" ).c_str(), PyGetBool( bHeat[ i ] ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
for( int i = 0; i < 20; ++i ) {
|
for( int i = 0; i < 20; ++i ) {
|
||||||
for( int j = 0; j < 3; ++j )
|
for( int j = 0; j < 3; ++j )
|
||||||
PyDict_SetItemString( dict, ( std::string( "eimp_pn" ) + std::to_string( i + 1 ) + std::string( "_" ) + std::string( TXTP[ j ] ) ).c_str(),
|
PyDict_SetItemString( dict, ( "eimp_pn" + std::to_string( i + 1 ) + "_" + TXTP[ j ] ).c_str(),
|
||||||
PyGetFloatS( fPress[ i ][ j ] ) );
|
PyGetFloatS( fPress[ i ][ j ] ) );
|
||||||
}
|
}
|
||||||
// multi-unit state data
|
// multi-unit state data
|
||||||
PyDict_SetItemString( dict, "car_no", PyGetInt( iCarNo ) );
|
PyDict_SetItemString( dict, "car_no", PyGetInt( iCarNo ) );
|
||||||
@@ -541,17 +518,16 @@ PyObject *TTrain::GetTrainState() {
|
|||||||
PyDict_SetItemString( dict, "unit_no", PyGetInt( iUnitNo ) );
|
PyDict_SetItemString( dict, "unit_no", PyGetInt( iUnitNo ) );
|
||||||
|
|
||||||
for( int i = 0; i < 20; i++ ) {
|
for( int i = 0; i < 20; i++ ) {
|
||||||
PyDict_SetItemString( dict, ( std::string( "doors_" ) + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 0 ] ) );
|
PyDict_SetItemString( dict, ( "doors_" + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 0 ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "doors_r_" ) + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 1 ] ) );
|
PyDict_SetItemString( dict, ( "doors_r_" + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 1 ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "doors_l_" ) + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 2 ] ) );
|
PyDict_SetItemString( dict, ( "doors_l_" + std::to_string( i + 1 ) ).c_str(), PyGetFloatS( bDoors[ i ][ 2 ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "doors_no_" ) + std::to_string( i + 1 ) ).c_str(), PyGetInt( iDoorNo[ i ] ) );
|
PyDict_SetItemString( dict, ( "doors_no_" + std::to_string( i + 1 ) ).c_str(), PyGetInt( iDoorNo[ i ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "code_" ) + std::to_string( i + 1 ) ).c_str(), PyGetString( std::string( std::to_string( iUnits[ i ] ) +
|
PyDict_SetItemString( dict, ( "code_" + std::to_string( i + 1 ) ).c_str(), PyGetString( ( std::to_string( iUnits[ i ] ) + cCode[ i ] ).c_str() ) );
|
||||||
cCode[ i ] ).c_str() ) );
|
PyDict_SetItemString( dict, ( "car_name" + std::to_string( i + 1 ) ).c_str(), PyGetString( asCarName[ i ].c_str() ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "car_name" ) + std::to_string( i + 1 ) ).c_str(), PyGetString( asCarName[ i ].c_str() ) );
|
PyDict_SetItemString( dict, ( "slip_" + std::to_string( i + 1 ) ).c_str(), PyGetBool( bSlip[ i ] ) );
|
||||||
PyDict_SetItemString( dict, ( std::string( "slip_" ) + std::to_string( i + 1 )).c_str(), PyGetBool( bSlip[i]) );
|
|
||||||
}
|
}
|
||||||
// ai state data
|
// ai state data
|
||||||
auto const &driver = DynamicObject->Mechanik;
|
auto const *driver = DynamicObject->Mechanik;
|
||||||
|
|
||||||
PyDict_SetItemString( dict, "velocity_desired", PyGetFloat( driver->VelDesired ) );
|
PyDict_SetItemString( dict, "velocity_desired", PyGetFloat( driver->VelDesired ) );
|
||||||
PyDict_SetItemString( dict, "velroad", PyGetFloat( driver->VelRoad ) );
|
PyDict_SetItemString( dict, "velroad", PyGetFloat( driver->VelRoad ) );
|
||||||
@@ -560,11 +536,32 @@ PyObject *TTrain::GetTrainState() {
|
|||||||
PyDict_SetItemString( dict, "velsignalnext", PyGetFloat( driver->VelSignalNext ) );
|
PyDict_SetItemString( dict, "velsignalnext", PyGetFloat( driver->VelSignalNext ) );
|
||||||
PyDict_SetItemString( dict, "velnext", PyGetFloat( driver->VelNext ) );
|
PyDict_SetItemString( dict, "velnext", PyGetFloat( driver->VelNext ) );
|
||||||
PyDict_SetItemString( dict, "actualproximitydist", PyGetFloat( driver->ActualProximityDist ) );
|
PyDict_SetItemString( dict, "actualproximitydist", PyGetFloat( driver->ActualProximityDist ) );
|
||||||
|
// train data
|
||||||
PyDict_SetItemString( dict, "trainnumber", PyGetString( driver->TrainName().c_str() ) );
|
PyDict_SetItemString( dict, "trainnumber", PyGetString( driver->TrainName().c_str() ) );
|
||||||
|
PyDict_SetItemString( dict, "train_stationindex", PyGetInt( driver->StationIndex() ) );
|
||||||
|
auto const stationcount { driver->StationCount() };
|
||||||
|
PyDict_SetItemString( dict, "train_stationcount", PyGetInt( stationcount ) );
|
||||||
|
if( stationcount > 0 ) {
|
||||||
|
// timetable stations data, if there's any
|
||||||
|
auto const *timetable { driver->TrainTimetable() };
|
||||||
|
for( auto stationidx = 1; stationidx <= stationcount; ++stationidx ) {
|
||||||
|
auto const stationlabel { "train_station" + std::to_string( stationidx ) + "_" };
|
||||||
|
auto const &timetableline { timetable->TimeTable[ stationidx ] };
|
||||||
|
PyDict_SetItemString( dict, ( stationlabel + "name" ).c_str(), PyGetString( Bezogonkow( timetableline.StationName ).c_str() ) );
|
||||||
|
PyDict_SetItemString( dict, ( stationlabel + "fclt" ).c_str(), PyGetString( Bezogonkow( timetableline.StationWare ).c_str() ) );
|
||||||
|
PyDict_SetItemString( dict, ( stationlabel + "lctn" ).c_str(), PyGetFloat( timetableline.km ) );
|
||||||
|
PyDict_SetItemString( dict, ( stationlabel + "vmax" ).c_str(), PyGetInt( timetableline.vmax ) );
|
||||||
|
PyDict_SetItemString( dict, ( stationlabel + "ah" ).c_str(), PyGetInt( timetableline.Ah ) );
|
||||||
|
PyDict_SetItemString( dict, ( stationlabel + "am" ).c_str(), PyGetInt( timetableline.Am ) );
|
||||||
|
PyDict_SetItemString( dict, ( stationlabel + "dh" ).c_str(), PyGetInt( timetableline.Dh ) );
|
||||||
|
PyDict_SetItemString( dict, ( stationlabel + "dm" ).c_str(), PyGetInt( timetableline.Dm ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
// world state data
|
// world state data
|
||||||
PyDict_SetItemString( dict, "hours", PyGetInt( simulation::Time.data().wHour ) );
|
PyDict_SetItemString( dict, "hours", PyGetInt( simulation::Time.data().wHour ) );
|
||||||
PyDict_SetItemString( dict, "minutes", PyGetInt( simulation::Time.data().wMinute ) );
|
PyDict_SetItemString( dict, "minutes", PyGetInt( simulation::Time.data().wMinute ) );
|
||||||
PyDict_SetItemString( dict, "seconds", PyGetInt( simulation::Time.second() ) );
|
PyDict_SetItemString( dict, "seconds", PyGetInt( simulation::Time.second() ) );
|
||||||
|
PyDict_SetItemString( dict, "air_temperature", PyGetInt( Global.AirTemperature ) );
|
||||||
|
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
@@ -3898,6 +3895,32 @@ void TTrain::OnCommand_hornhighactivate( TTrain *Train, command_data const &Comm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TTrain::OnCommand_whistleactivate( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
|
if( Train->ggWhistleButton.SubModel == nullptr ) {
|
||||||
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
WriteLog( "Whistle button is missing, or wasn't defined" );
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( Command.action == GLFW_PRESS ) {
|
||||||
|
// only need to react to press, sound will continue until stopped
|
||||||
|
if( false == TestFlag( Train->mvOccupied->WarningSignal, 4 ) ) {
|
||||||
|
// turn on
|
||||||
|
Train->mvOccupied->WarningSignal |= 4;
|
||||||
|
// visual feedback
|
||||||
|
Train->ggWhistleButton.UpdateValue( 1.0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
|
// turn off
|
||||||
|
Train->mvOccupied->WarningSignal &= ~4;
|
||||||
|
// visual feedback
|
||||||
|
Train->ggWhistleButton.UpdateValue( 0.0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TTrain::OnCommand_radiotoggle( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_radiotoggle( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
if( Train->ggRadioButton.SubModel == nullptr ) {
|
if( Train->ggRadioButton.SubModel == nullptr ) {
|
||||||
@@ -4374,7 +4397,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
asCarName[i] = p->name();
|
asCarName[i] = p->name();
|
||||||
bPants[iUnitNo - 1][0] = (bPants[iUnitNo - 1][0] || p->MoverParameters->PantFrontUp);
|
bPants[iUnitNo - 1][0] = (bPants[iUnitNo - 1][0] || p->MoverParameters->PantFrontUp);
|
||||||
bPants[iUnitNo - 1][1] = (bPants[iUnitNo - 1][1] || p->MoverParameters->PantRearUp);
|
bPants[iUnitNo - 1][1] = (bPants[iUnitNo - 1][1] || p->MoverParameters->PantRearUp);
|
||||||
bComp[iUnitNo - 1][0] = (bComp[iUnitNo - 1][0] || p->MoverParameters->CompressorAllow);
|
bComp[iUnitNo - 1][0] = (bComp[iUnitNo - 1][0] || p->MoverParameters->CompressorAllow || (p->MoverParameters->CompressorStart == start::automatic));
|
||||||
bSlip[i] = p->MoverParameters->SlippingWheels;
|
bSlip[i] = p->MoverParameters->SlippingWheels;
|
||||||
if (p->MoverParameters->CompressorSpeed > 0.00001)
|
if (p->MoverParameters->CompressorSpeed > 0.00001)
|
||||||
{
|
{
|
||||||
@@ -4533,30 +4556,34 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) &&
|
if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) &&
|
||||||
(mvOccupied->ActiveCab == -1))
|
(mvOccupied->ActiveCab == -1))
|
||||||
tmp = DynamicObject->PrevConnected;
|
tmp = DynamicObject->PrevConnected;
|
||||||
if (tmp)
|
if( tmp ) {
|
||||||
if (tmp->MoverParameters->Power > 0)
|
if( tmp->MoverParameters->Power > 0 ) {
|
||||||
{
|
if( ggI1B.SubModel ) {
|
||||||
if (ggI1B.SubModel)
|
ggI1B.UpdateValue( tmp->MoverParameters->ShowCurrent( 1 ) );
|
||||||
{
|
|
||||||
ggI1B.UpdateValue(tmp->MoverParameters->ShowCurrent(1));
|
|
||||||
ggI1B.Update();
|
ggI1B.Update();
|
||||||
}
|
}
|
||||||
if (ggI2B.SubModel)
|
if( ggI2B.SubModel ) {
|
||||||
{
|
ggI2B.UpdateValue( tmp->MoverParameters->ShowCurrent( 2 ) );
|
||||||
ggI2B.UpdateValue(tmp->MoverParameters->ShowCurrent(2));
|
|
||||||
ggI2B.Update();
|
ggI2B.Update();
|
||||||
}
|
}
|
||||||
if (ggI3B.SubModel)
|
if( ggI3B.SubModel ) {
|
||||||
{
|
ggI3B.UpdateValue( tmp->MoverParameters->ShowCurrent( 3 ) );
|
||||||
ggI3B.UpdateValue(tmp->MoverParameters->ShowCurrent(3));
|
|
||||||
ggI3B.Update();
|
ggI3B.Update();
|
||||||
}
|
}
|
||||||
if (ggItotalB.SubModel)
|
if( ggItotalB.SubModel ) {
|
||||||
{
|
ggItotalB.UpdateValue( tmp->MoverParameters->ShowCurrent( 0 ) );
|
||||||
ggItotalB.UpdateValue(tmp->MoverParameters->ShowCurrent(0));
|
|
||||||
ggItotalB.Update();
|
ggItotalB.Update();
|
||||||
}
|
}
|
||||||
|
if( ggWater1TempB.SubModel ) {
|
||||||
|
ggWater1TempB.UpdateValue( tmp->MoverParameters->dizel_heat.temperatura1 );
|
||||||
|
ggWater1TempB.Update();
|
||||||
|
}
|
||||||
|
if( ggOilPressB.SubModel ) {
|
||||||
|
ggOilPressB.UpdateValue( tmp->MoverParameters->OilPump.pressure_present );
|
||||||
|
ggOilPressB.Update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// McZapkie-300302: zegarek
|
// McZapkie-300302: zegarek
|
||||||
if (ggClockMInd.SubModel)
|
if (ggClockMInd.SubModel)
|
||||||
@@ -5212,6 +5239,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
ggHornButton.Update();
|
ggHornButton.Update();
|
||||||
ggHornLowButton.Update();
|
ggHornLowButton.Update();
|
||||||
ggHornHighButton.Update();
|
ggHornHighButton.Update();
|
||||||
|
ggWhistleButton.Update();
|
||||||
for( auto &universal : ggUniversals ) {
|
for( auto &universal : ggUniversals ) {
|
||||||
universal.Update();
|
universal.Update();
|
||||||
}
|
}
|
||||||
@@ -5585,7 +5613,13 @@ TTrain::update_sounds( double const Deltatime ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( fTachoCount > 3.f ) {
|
if( fTachoCount > 3.f ) {
|
||||||
dsbHasler.play( sound_flags::exclusive | sound_flags::looping );
|
auto const frequency { (
|
||||||
|
true == dsbHasler.is_combined() ?
|
||||||
|
fTachoVelocity * 0.01 :
|
||||||
|
1.0 ) };
|
||||||
|
dsbHasler
|
||||||
|
.pitch( frequency )
|
||||||
|
.play( sound_flags::exclusive | sound_flags::looping );
|
||||||
}
|
}
|
||||||
else if( fTachoCount < 1.f ) {
|
else if( fTachoCount < 1.f ) {
|
||||||
dsbHasler.stop();
|
dsbHasler.stop();
|
||||||
@@ -6145,8 +6179,10 @@ TTrain::radio_message( sound_source *Message, int const Channel ) {
|
|||||||
// skip message playback if the radio isn't able to receive it
|
// skip message playback if the radio isn't able to receive it
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto const radiorange { 7500 * 7500 };
|
auto const soundrange { Message->range() };
|
||||||
if( glm::length2( Message->location() - glm::dvec3 { DynamicObject->GetPosition() } ) > radiorange ) {
|
if( ( soundrange > 0 )
|
||||||
|
&& ( glm::length2( Message->location() - glm::dvec3 { DynamicObject->GetPosition() } ) > ( soundrange * soundrange ) ) ) {
|
||||||
|
// skip message playback if the receiver is outside of the emitter's range
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6233,6 +6269,7 @@ void TTrain::clear_cab_controls()
|
|||||||
ggHornButton.Clear();
|
ggHornButton.Clear();
|
||||||
ggHornLowButton.Clear();
|
ggHornLowButton.Clear();
|
||||||
ggHornHighButton.Clear();
|
ggHornHighButton.Clear();
|
||||||
|
ggWhistleButton.Clear();
|
||||||
ggNextCurrentButton.Clear();
|
ggNextCurrentButton.Clear();
|
||||||
for( auto &universal : ggUniversals ) {
|
for( auto &universal : ggUniversals ) {
|
||||||
universal.Clear();
|
universal.Clear();
|
||||||
@@ -6270,6 +6307,8 @@ void TTrain::clear_cab_controls()
|
|||||||
ggI2B.Clear();
|
ggI2B.Clear();
|
||||||
ggI3B.Clear();
|
ggI3B.Clear();
|
||||||
ggItotalB.Clear();
|
ggItotalB.Clear();
|
||||||
|
ggOilPressB.Clear();
|
||||||
|
ggWater1TempB.Clear();
|
||||||
|
|
||||||
ggClockSInd.Clear();
|
ggClockSInd.Clear();
|
||||||
ggClockMInd.Clear();
|
ggClockMInd.Clear();
|
||||||
@@ -6385,44 +6424,60 @@ void TTrain::set_cab_controls() {
|
|||||||
ggRadioChannelSelector.PutValue( iRadioChannel - 1 );
|
ggRadioChannelSelector.PutValue( iRadioChannel - 1 );
|
||||||
// pantographs
|
// pantographs
|
||||||
if( mvOccupied->PantSwitchType != "impulse" ) {
|
if( mvOccupied->PantSwitchType != "impulse" ) {
|
||||||
ggPantFrontButton.PutValue(
|
if( ggPantFrontButton.SubModel ) {
|
||||||
( mvControlled->PantFrontUp ?
|
ggPantFrontButton.PutValue(
|
||||||
1.0 :
|
( mvControlled->PantFrontUp ?
|
||||||
0.0 ) );
|
1.0 :
|
||||||
ggPantFrontButtonOff.PutValue(
|
0.0 ) );
|
||||||
( mvControlled->PantFrontUp ?
|
}
|
||||||
0.0 :
|
if( ggPantFrontButtonOff.SubModel ) {
|
||||||
1.0 ) );
|
ggPantFrontButtonOff.PutValue(
|
||||||
|
( mvControlled->PantFrontUp ?
|
||||||
|
0.0 :
|
||||||
|
1.0 ) );
|
||||||
|
}
|
||||||
// NOTE: currently we animate the selectable pantograph control for both pantographs
|
// NOTE: currently we animate the selectable pantograph control for both pantographs
|
||||||
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
ggPantSelectedButton.PutValue(
|
if( ggPantSelectedButton.SubModel ) {
|
||||||
( mvControlled->PantFrontUp ?
|
ggPantSelectedButton.PutValue(
|
||||||
1.0 :
|
( mvControlled->PantFrontUp ?
|
||||||
0.0 ) );
|
1.0 :
|
||||||
ggPantSelectedDownButton.PutValue(
|
0.0 ) );
|
||||||
( mvControlled->PantFrontUp ?
|
}
|
||||||
0.0 :
|
if( ggPantSelectedDownButton.SubModel ) {
|
||||||
1.0 ) );
|
ggPantSelectedDownButton.PutValue(
|
||||||
|
( mvControlled->PantFrontUp ?
|
||||||
|
0.0 :
|
||||||
|
1.0 ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( mvOccupied->PantSwitchType != "impulse" ) {
|
if( mvOccupied->PantSwitchType != "impulse" ) {
|
||||||
ggPantRearButton.PutValue(
|
if( ggPantRearButton.SubModel ) {
|
||||||
( mvControlled->PantRearUp ?
|
ggPantRearButton.PutValue(
|
||||||
1.0 :
|
( mvControlled->PantRearUp ?
|
||||||
0.0 ) );
|
1.0 :
|
||||||
ggPantRearButtonOff.PutValue(
|
0.0 ) );
|
||||||
( mvControlled->PantRearUp ?
|
}
|
||||||
0.0 :
|
if( ggPantRearButtonOff.SubModel ) {
|
||||||
1.0 ) );
|
ggPantRearButtonOff.PutValue(
|
||||||
|
( mvControlled->PantRearUp ?
|
||||||
|
0.0 :
|
||||||
|
1.0 ) );
|
||||||
|
}
|
||||||
// NOTE: currently we animate the selectable pantograph control for both pantographs
|
// NOTE: currently we animate the selectable pantograph control for both pantographs
|
||||||
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
ggPantSelectedButton.PutValue(
|
if( ggPantSelectedButton.SubModel ) {
|
||||||
( mvControlled->PantRearUp ?
|
ggPantSelectedButton.PutValue(
|
||||||
1.0 :
|
( mvControlled->PantRearUp ?
|
||||||
0.0 ) );
|
1.0 :
|
||||||
ggPantSelectedDownButton.PutValue(
|
0.0 ) );
|
||||||
( mvControlled->PantRearUp ?
|
}
|
||||||
0.0 :
|
if( ggPantSelectedDownButton.SubModel ) {
|
||||||
1.0 ) );
|
ggPantSelectedDownButton.PutValue(
|
||||||
|
( mvControlled->PantRearUp ?
|
||||||
|
0.0 :
|
||||||
|
1.0 ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// auxiliary compressor
|
// auxiliary compressor
|
||||||
ggPantCompressorValve.PutValue(
|
ggPantCompressorValve.PutValue(
|
||||||
@@ -6739,6 +6794,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
{ "horn_bt:", ggHornButton },
|
{ "horn_bt:", ggHornButton },
|
||||||
{ "hornlow_bt:", ggHornLowButton },
|
{ "hornlow_bt:", ggHornLowButton },
|
||||||
{ "hornhigh_bt:", ggHornHighButton },
|
{ "hornhigh_bt:", ggHornHighButton },
|
||||||
|
{ "whistle_bt:", ggWhistleButton },
|
||||||
{ "fuse_bt:", ggFuseButton },
|
{ "fuse_bt:", ggFuseButton },
|
||||||
{ "converterfuse_bt:", ggConverterFuseButton },
|
{ "converterfuse_bt:", ggConverterFuseButton },
|
||||||
{ "stlinoff_bt:", ggStLinOffButton },
|
{ "stlinoff_bt:", ggStLinOffButton },
|
||||||
@@ -6767,9 +6823,11 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
{ "waterpump_sw:", ggWaterPumpButton },
|
{ "waterpump_sw:", ggWaterPumpButton },
|
||||||
{ "waterheaterbreaker_sw:", ggWaterHeaterBreakerButton },
|
{ "waterheaterbreaker_sw:", ggWaterHeaterBreakerButton },
|
||||||
{ "waterheater_sw:", ggWaterHeaterButton },
|
{ "waterheater_sw:", ggWaterHeaterButton },
|
||||||
|
{ "water1tempb:", ggWater1TempB },
|
||||||
{ "watercircuitslink_sw:", ggWaterCircuitsLinkButton },
|
{ "watercircuitslink_sw:", ggWaterCircuitsLinkButton },
|
||||||
{ "fuelpump_sw:", ggFuelPumpButton },
|
{ "fuelpump_sw:", ggFuelPumpButton },
|
||||||
{ "oilpump_sw:", ggOilPumpButton },
|
{ "oilpump_sw:", ggOilPumpButton },
|
||||||
|
{ "oilpressb:", ggOilPressB },
|
||||||
{ "radio_sw:", ggRadioButton },
|
{ "radio_sw:", ggRadioButton },
|
||||||
{ "radiochannel_sw:", ggRadioChannelSelector },
|
{ "radiochannel_sw:", ggRadioChannelSelector },
|
||||||
{ "radiochannelprev_sw:", ggRadioChannelPrevious },
|
{ "radiochannelprev_sw:", ggRadioChannelPrevious },
|
||||||
|
|||||||
5
Train.h
5
Train.h
@@ -301,6 +301,7 @@ class TTrain
|
|||||||
static void OnCommand_departureannounce( TTrain *Train, command_data const &Command );
|
static void OnCommand_departureannounce( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_hornlowactivate( TTrain *Train, command_data const &Command );
|
static void OnCommand_hornlowactivate( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_hornhighactivate( TTrain *Train, command_data const &Command );
|
static void OnCommand_hornhighactivate( TTrain *Train, command_data const &Command );
|
||||||
|
static void OnCommand_whistleactivate( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_radiotoggle( TTrain *Train, command_data const &Command );
|
static void OnCommand_radiotoggle( TTrain *Train, command_data const &Command );
|
||||||
static void OnCommand_radiochannelincrease( 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_radiochanneldecrease( TTrain *Train, command_data const &Command );
|
||||||
@@ -338,6 +339,9 @@ public: // reszta może by?publiczna
|
|||||||
TGauge ggI3B;
|
TGauge ggI3B;
|
||||||
TGauge ggItotalB;
|
TGauge ggItotalB;
|
||||||
|
|
||||||
|
TGauge ggOilPressB;
|
||||||
|
TGauge ggWater1TempB;
|
||||||
|
|
||||||
// McZapkie: definicje regulatorow
|
// McZapkie: definicje regulatorow
|
||||||
TGauge ggMainCtrl;
|
TGauge ggMainCtrl;
|
||||||
TGauge ggMainCtrlAct;
|
TGauge ggMainCtrlAct;
|
||||||
@@ -397,6 +401,7 @@ public: // reszta może by?publiczna
|
|||||||
TGauge ggHornButton;
|
TGauge ggHornButton;
|
||||||
TGauge ggHornLowButton;
|
TGauge ggHornLowButton;
|
||||||
TGauge ggHornHighButton;
|
TGauge ggHornHighButton;
|
||||||
|
TGauge ggWhistleButton;
|
||||||
TGauge ggNextCurrentButton;
|
TGauge ggNextCurrentButton;
|
||||||
|
|
||||||
std::array<TGauge, 10> ggUniversals; // NOTE: temporary arrangement until we have dynamically built control table
|
std::array<TGauge, 10> ggUniversals; // NOTE: temporary arrangement until we have dynamically built control table
|
||||||
|
|||||||
@@ -227,8 +227,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
|
|||||||
{ // jeśli przekroczenie toru od strony Point2
|
{ // jeśli przekroczenie toru od strony Point2
|
||||||
bCanSkip = ( bPrimary && pCurrentTrack->CheckDynamicObject( Owner ) );
|
bCanSkip = ( bPrimary && pCurrentTrack->CheckDynamicObject( Owner ) );
|
||||||
if (bCanSkip) // tylko główna oś przenosi pojazd do innego toru
|
if (bCanSkip) // tylko główna oś przenosi pojazd do innego toru
|
||||||
Owner->MyTrack->RemoveDynamicObject(
|
Owner->MyTrack->RemoveDynamicObject(Owner); // zdejmujemy pojazd z dotychczasowego toru
|
||||||
Owner); // zdejmujemy pojazd z dotychczasowego toru
|
|
||||||
fDistance = s - pCurrentSegment->GetLength();
|
fDistance = s - pCurrentSegment->GetLength();
|
||||||
dir = fDirection;
|
dir = fDirection;
|
||||||
if (pCurrentTrack->eType == tt_Cross)
|
if (pCurrentTrack->eType == tt_Cross)
|
||||||
@@ -236,8 +235,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
|
|||||||
if (!SetCurrentTrack(pCurrentTrack->Connected(iSegment, fDirection), 1))
|
if (!SetCurrentTrack(pCurrentTrack->Connected(iSegment, fDirection), 1))
|
||||||
return false; // wyjście z błędem
|
return false; // wyjście z błędem
|
||||||
}
|
}
|
||||||
else if (!SetCurrentTrack(pCurrentTrack->Connected(1, fDirection),
|
else if (!SetCurrentTrack(pCurrentTrack->Connected(1, fDirection), 1)) // ustawia fDirection
|
||||||
1)) // ustawia fDirection
|
|
||||||
return false; // wyjście z błędem
|
return false; // wyjście z błędem
|
||||||
if (dir != fDirection) //(pCurrentTrack->iNextDirection)
|
if (dir != fDirection) //(pCurrentTrack->iNextDirection)
|
||||||
{ // gdy zmiana kierunku toru (Point2->Point2)
|
{ // gdy zmiana kierunku toru (Point2->Point2)
|
||||||
@@ -249,8 +247,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
|
|||||||
if (bCanSkip)
|
if (bCanSkip)
|
||||||
{ // jak główna oś, to dodanie pojazdu do nowego toru
|
{ // jak główna oś, to dodanie pojazdu do nowego toru
|
||||||
pCurrentTrack->AddDynamicObject(Owner);
|
pCurrentTrack->AddDynamicObject(Owner);
|
||||||
iEventFlag =
|
iEventFlag = 3; // McZapkie-020602: umozliwienie uruchamiania event1,2 po zmianie toru
|
||||||
3; // McZapkie-020602: umozliwienie uruchamiania event1,2 po zmianie toru
|
|
||||||
iEventallFlag = 3;
|
iEventallFlag = 3;
|
||||||
if (!Owner->MyTrack)
|
if (!Owner->MyTrack)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -280,6 +280,7 @@ bool TWorld::Init( GLFWwindow *Window ) {
|
|||||||
FreeFlyModeFlag = true; // Ra: automatycznie włączone latanie
|
FreeFlyModeFlag = true; // Ra: automatycznie włączone latanie
|
||||||
Controlled = NULL;
|
Controlled = NULL;
|
||||||
mvControlled = NULL;
|
mvControlled = NULL;
|
||||||
|
SafeDelete( Train );
|
||||||
Camera.Type = tp_Free;
|
Camera.Type = tp_Free;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ buffer_manager::find_buffer( std::string const &Buffername ) const {
|
|||||||
std::string
|
std::string
|
||||||
buffer_manager::find_file( std::string const &Filename ) const {
|
buffer_manager::find_file( std::string const &Filename ) const {
|
||||||
|
|
||||||
std::vector<std::string> const extensions { ".wav", ".WAV", ".flac", ".ogg" };
|
std::vector<std::string> const extensions { ".ogg", ".flac", ".wav" };
|
||||||
|
|
||||||
for( auto const &extension : extensions ) {
|
for( auto const &extension : extensions ) {
|
||||||
if( FileExists( Filename + extension ) ) {
|
if( FileExists( Filename + extension ) ) {
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ commanddescription_sequence Commands_descriptions = {
|
|||||||
{ "alerteracknowledge", command_target::vehicle },
|
{ "alerteracknowledge", command_target::vehicle },
|
||||||
{ "hornlowactivate", command_target::vehicle },
|
{ "hornlowactivate", command_target::vehicle },
|
||||||
{ "hornhighactivate", command_target::vehicle },
|
{ "hornhighactivate", command_target::vehicle },
|
||||||
|
{ "whistleactivate", command_target::vehicle },
|
||||||
{ "radiotoggle", command_target::vehicle },
|
{ "radiotoggle", command_target::vehicle },
|
||||||
{ "radiochannelincrease", command_target::vehicle },
|
{ "radiochannelincrease", command_target::vehicle },
|
||||||
{ "radiochanneldecrease", command_target::vehicle },
|
{ "radiochanneldecrease", command_target::vehicle },
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ enum class user_command {
|
|||||||
alerteracknowledge,
|
alerteracknowledge,
|
||||||
hornlowactivate,
|
hornlowactivate,
|
||||||
hornhighactivate,
|
hornhighactivate,
|
||||||
|
whistleactivate,
|
||||||
radiotoggle,
|
radiotoggle,
|
||||||
radiochannelincrease,
|
radiochannelincrease,
|
||||||
radiochanneldecrease,
|
radiochanneldecrease,
|
||||||
|
|||||||
@@ -358,7 +358,9 @@ keyboard_input::default_bindings() {
|
|||||||
// hornlowactivate
|
// hornlowactivate
|
||||||
{ GLFW_KEY_A },
|
{ GLFW_KEY_A },
|
||||||
// hornhighactivate
|
// hornhighactivate
|
||||||
{ GLFW_KEY_A | keymodifier::shift },
|
{ GLFW_KEY_S },
|
||||||
|
// whistleactivate
|
||||||
|
{ GLFW_KEY_Z },
|
||||||
// radiotoggle
|
// radiotoggle
|
||||||
{ GLFW_KEY_R | keymodifier::control },
|
{ GLFW_KEY_R | keymodifier::control },
|
||||||
// radiochannelincrease
|
// radiochannelincrease
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ WyslijObsadzone()
|
|||||||
r.fPar[ 16 * i + 6 ] = vehicle->GetPosition().z;
|
r.fPar[ 16 * i + 6 ] = vehicle->GetPosition().z;
|
||||||
r.iPar[ 16 * i + 7 ] = vehicle->Mechanik->GetAction();
|
r.iPar[ 16 * i + 7 ] = vehicle->Mechanik->GetAction();
|
||||||
strcpy( r.cString + 64 * i + 32, vehicle->GetTrack()->IsolatedName().c_str() );
|
strcpy( r.cString + 64 * i + 32, vehicle->GetTrack()->IsolatedName().c_str() );
|
||||||
strcpy( r.cString + 64 * i + 48, vehicle->Mechanik->Timetable()->TrainName.c_str() );
|
strcpy( r.cString + 64 * i + 48, vehicle->Mechanik->TrainName().c_str() );
|
||||||
i++;
|
i++;
|
||||||
if( i > 30 ) break;
|
if( i > 30 ) break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -291,6 +291,9 @@ mouse_input::default_bindings() {
|
|||||||
{ "hornhigh_bt:", {
|
{ "hornhigh_bt:", {
|
||||||
user_command::hornhighactivate,
|
user_command::hornhighactivate,
|
||||||
user_command::none } },
|
user_command::none } },
|
||||||
|
{ "whistle_bt:", {
|
||||||
|
user_command::whistleactivate,
|
||||||
|
user_command::none } },
|
||||||
{ "fuse_bt:", {
|
{ "fuse_bt:", {
|
||||||
user_command::motoroverloadrelayreset,
|
user_command::motoroverloadrelayreset,
|
||||||
user_command::none } },
|
user_command::none } },
|
||||||
|
|||||||
61
mtable.cpp
61
mtable.cpp
@@ -13,26 +13,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "utilities.h"
|
#include "utilities.h"
|
||||||
|
|
||||||
double CompareTime(double t1h, double t1m, double t2h, double t2m) /*roznica czasu w minutach*/
|
|
||||||
// zwraca różnicę czasu
|
|
||||||
// jeśli pierwsza jest aktualna, a druga rozkładowa, to ujemna oznacza opóżnienie
|
|
||||||
// na dłuższą metę trzeba uwzględnić datę, jakby opóżnienia miały przekraczać 12h (towarowych)
|
|
||||||
{
|
|
||||||
double t;
|
|
||||||
|
|
||||||
if ((t2h < 0))
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
t = (t2h - t1h) * 60 + t2m - t1m; // jeśli t2=00:05, a t1=23:50, to różnica wyjdzie ujemna
|
|
||||||
if ((t < -720)) // jeśli różnica przekracza 12h na minus
|
|
||||||
t = t + 1440; // to dodanie doby minut;else
|
|
||||||
if ((t > 720)) // jeśli przekracza 12h na plus
|
|
||||||
t = t - 1440; // to odjęcie doby minut
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double TTrainParameters::CheckTrainLatency()
|
double TTrainParameters::CheckTrainLatency()
|
||||||
{
|
{
|
||||||
if ((LastStationLatency > 1.0) || (LastStationLatency < 0))
|
if ((LastStationLatency > 1.0) || (LastStationLatency < 0))
|
||||||
@@ -177,18 +157,7 @@ void TTrainParameters::NewName(std::string const &NewTrainName)
|
|||||||
Relation2 = "";
|
Relation2 = "";
|
||||||
for (int i = 0; i < MaxTTableSize + 1; ++i)
|
for (int i = 0; i < MaxTTableSize + 1; ++i)
|
||||||
{
|
{
|
||||||
TMTableLine *t = &TimeTable[i];
|
TimeTable[ i ] = TMTableLine();
|
||||||
t->km = 0;
|
|
||||||
t->vmax = -1;
|
|
||||||
t->StationName = "nowhere";
|
|
||||||
t->StationWare = "";
|
|
||||||
t->TrackNo = 1;
|
|
||||||
t->Ah = -1;
|
|
||||||
t->Am = -1;
|
|
||||||
t->Dh = -1;
|
|
||||||
t->Dm = -1;
|
|
||||||
t->tm = 0;
|
|
||||||
t->WaitTime = 0;
|
|
||||||
}
|
}
|
||||||
TTVmax = 100; /*wykasowac*/
|
TTVmax = 100; /*wykasowac*/
|
||||||
BrakeRatio = 0;
|
BrakeRatio = 0;
|
||||||
@@ -386,15 +355,12 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
|||||||
{
|
{
|
||||||
if (s.find(hrsd) != std::string::npos)
|
if (s.find(hrsd) != std::string::npos)
|
||||||
{
|
{
|
||||||
record->Ah = atoi(
|
record->Ah = atoi( s.substr(0, s.find(hrsd)).c_str()); // godzina przyjazdu
|
||||||
s.substr(0, s.find(hrsd)).c_str()); // godzina przyjazdu
|
record->Am = atoi(s.substr(s.find(hrsd) + 1, s.length()).c_str()); // minuta przyjazdu
|
||||||
record->Am = atoi(s.substr(s.find(hrsd) + 1, s.length())
|
|
||||||
.c_str()); // minuta przyjazdu
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
record->Ah = TimeTable[StationCount - 1]
|
record->Ah = TimeTable[StationCount - 1].Ah; // godzina z poprzedniej pozycji
|
||||||
.Ah; // godzina z poprzedniej pozycji
|
|
||||||
record->Am = atoi(s.c_str()); // bo tylko minuty podane
|
record->Am = atoi(s.c_str()); // bo tylko minuty podane
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -439,29 +405,20 @@ bool TTrainParameters::LoadTTfile(std::string scnpath, int iPlus, double vmax)
|
|||||||
{
|
{
|
||||||
if (s.find(hrsd) != std::string::npos)
|
if (s.find(hrsd) != std::string::npos)
|
||||||
{
|
{
|
||||||
record->Dh =
|
record->Dh = atoi(s.substr(0, s.find(hrsd)).c_str()); // godzina odjazdu
|
||||||
atoi(s.substr(0, s.find(hrsd)).c_str()); // godzina odjazdu
|
record->Dm = atoi(s.substr(s.find(hrsd) + 1, s.length()).c_str()); // minuta odjazdu
|
||||||
record->Dm = atoi(s.substr(s.find(hrsd) + 1, s.length())
|
|
||||||
.c_str()); // minuta odjazdu
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
record->Dh = TimeTable[StationCount - 1]
|
record->Dh = TimeTable[StationCount - 1].Dh; // godzina z poprzedniej pozycji
|
||||||
.Dh; // godzina z poprzedniej pozycji
|
|
||||||
record->Dm = atoi(s.c_str()); // bo tylko minuty podane
|
record->Dm = atoi(s.c_str()); // bo tylko minuty podane
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
record->Dh = record->Ah; // odjazd o tej samej, co przyjazd (dla
|
record->Dh = record->Ah; // odjazd o tej samej, co przyjazd (dla ostatniego też)
|
||||||
// ostatniego też)
|
record->Dm = record->Am; // bo są używane do wyliczenia opóźnienia po dojechaniu
|
||||||
record->Dm = record->Am; // bo są używane do wyliczenia opóźnienia
|
|
||||||
// po dojechaniu
|
|
||||||
}
|
}
|
||||||
if ((record->Ah >= 0))
|
|
||||||
record->WaitTime = (int)(CompareTime(record->Ah, record->Am,
|
|
||||||
record->Dh, record->Dm) +
|
|
||||||
0.1);
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
fin >> s;
|
fin >> s;
|
||||||
|
|||||||
5
mtable.h
5
mtable.h
@@ -35,15 +35,14 @@ struct TMTableLine
|
|||||||
int Dh;
|
int Dh;
|
||||||
int Dm; // godz. i min. odjazdu
|
int Dm; // godz. i min. odjazdu
|
||||||
double tm; // czas jazdy do tej stacji w min. (z kolumny)
|
double tm; // czas jazdy do tej stacji w min. (z kolumny)
|
||||||
int WaitTime; // czas postoju (liczony plus 6 sekund)
|
|
||||||
TMTableLine()
|
TMTableLine()
|
||||||
{
|
{
|
||||||
km = 0;
|
km = 0;
|
||||||
vmax = -1;
|
vmax = -1;
|
||||||
StationName = "nowhere", StationWare = "";
|
StationName = "nowhere", StationWare = "";
|
||||||
TrackNo = 1;
|
TrackNo = 1;
|
||||||
Ah, Am, Dh, Dm = -1;
|
Ah = Am = Dh = Dm = -1;
|
||||||
WaitTime, tm = 0;
|
tm = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
36
renderer.cpp
36
renderer.cpp
@@ -1959,6 +1959,38 @@ opengl_renderer::Render( cell_sequence::iterator First, cell_sequence::iterator
|
|||||||
|
|
||||||
++first;
|
++first;
|
||||||
}
|
}
|
||||||
|
#ifdef EU07_USE_DEBUG_SOUNDEMITTERS
|
||||||
|
// sound emitters
|
||||||
|
if( DebugModeFlag ) {
|
||||||
|
switch( m_renderpass.draw_mode ) {
|
||||||
|
case rendermode::color: {
|
||||||
|
|
||||||
|
::glPushAttrib( GL_ENABLE_BIT );
|
||||||
|
::glDisable( GL_TEXTURE_2D );
|
||||||
|
::glColor3f( 0.36f, 0.75f, 0.35f );
|
||||||
|
|
||||||
|
for( auto const &audiosource : audio::renderer.m_sources ) {
|
||||||
|
|
||||||
|
::glPushMatrix();
|
||||||
|
auto const position = audiosource.properties.location - m_renderpass.camera.position();
|
||||||
|
::glTranslated( position.x, position.y, position.z );
|
||||||
|
|
||||||
|
::gluSphere( m_quadric, 0.1, 4, 2 );
|
||||||
|
|
||||||
|
::glPopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
::glPopAttrib();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2471,7 +2503,9 @@ opengl_renderer::Render( TSubModel *Submodel ) {
|
|||||||
// kąt większy niż maksymalny stożek swiatła
|
// kąt większy niż maksymalny stożek swiatła
|
||||||
float lightlevel = 1.f; // TODO, TBD: parameter to control light strength
|
float lightlevel = 1.f; // TODO, TBD: parameter to control light strength
|
||||||
// view angle attenuation
|
// view angle attenuation
|
||||||
float const anglefactor = ( Submodel->fCosViewAngle - Submodel->fCosFalloffAngle ) / ( 1.0f - Submodel->fCosFalloffAngle );
|
float const anglefactor = clamp(
|
||||||
|
( Submodel->fCosViewAngle - Submodel->fCosFalloffAngle ) / ( Submodel->fCosHotspotAngle - Submodel->fCosFalloffAngle ),
|
||||||
|
0.f, 1.f );
|
||||||
// distance attenuation. NOTE: since it's fixed pipeline with built-in gamma correction we're using linear attenuation
|
// distance attenuation. NOTE: since it's fixed pipeline with built-in gamma correction we're using linear attenuation
|
||||||
// we're capping how much effect the distance attenuation can have, otherwise the lights get too tiny at regular distances
|
// 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 );
|
float const distancefactor = std::max( 0.5f, ( Submodel->fSquareMaxDist - TSubModel::fSquareDist ) / Submodel->fSquareMaxDist );
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
//#define EU07_USE_DEBUG_SHADOWMAP
|
//#define EU07_USE_DEBUG_SHADOWMAP
|
||||||
//#define EU07_USE_DEBUG_CABSHADOWMAP
|
//#define EU07_USE_DEBUG_CABSHADOWMAP
|
||||||
//#define EU07_USE_DEBUG_CAMERA
|
//#define EU07_USE_DEBUG_CAMERA
|
||||||
|
//#define EU07_USE_DEBUG_SOUNDEMITTERS
|
||||||
|
|
||||||
struct opengl_light : public basic_light {
|
struct opengl_light : public basic_light {
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
namespace scene {
|
namespace scene {
|
||||||
|
|
||||||
std::string const EU07_FILEEXTENSION_REGION { ".sbt" };
|
std::string const EU07_FILEEXTENSION_REGION { ".sbt" };
|
||||||
|
std::uint32_t const EU07_FILEVERSION_REGION { MAKE_ID4( 'S', 'B', 'T', 1 ) };
|
||||||
|
|
||||||
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
// legacy method, finds and assigns traction piece to specified pantograph of provided vehicle
|
||||||
void
|
void
|
||||||
@@ -883,7 +884,7 @@ basic_region::serialize( std::string const &Scenariofile ) const {
|
|||||||
// region file version 1
|
// region file version 1
|
||||||
// header: EU07SBT + version (0-255)
|
// header: EU07SBT + version (0-255)
|
||||||
sn_utils::ls_uint32( output, MAKE_ID4( 'E', 'U', '0', '7' ) );
|
sn_utils::ls_uint32( output, MAKE_ID4( 'E', 'U', '0', '7' ) );
|
||||||
sn_utils::ls_uint32( output, MAKE_ID4( 'S', 'B', 'T', 1 ) );
|
sn_utils::ls_uint32( output, EU07_FILEVERSION_REGION );
|
||||||
// sections
|
// sections
|
||||||
// TBD, TODO: build table of sections and file offsets, if we postpone section loading until they're within range
|
// TBD, TODO: build table of sections and file offsets, if we postpone section loading until they're within range
|
||||||
std::uint32_t sectioncount { 0 };
|
std::uint32_t sectioncount { 0 };
|
||||||
@@ -928,7 +929,7 @@ basic_region::deserialize( std::string const &Scenariofile ) {
|
|||||||
uint32_t headertype { sn_utils::ld_uint32( input ) };
|
uint32_t headertype { sn_utils::ld_uint32( input ) };
|
||||||
|
|
||||||
if( ( headermain != MAKE_ID4( 'E', 'U', '0', '7' )
|
if( ( headermain != MAKE_ID4( 'E', 'U', '0', '7' )
|
||||||
|| ( headertype != MAKE_ID4( 'S', 'B', 'T', 1 ) ) ) ) {
|
|| ( headertype != EU07_FILEVERSION_REGION ) ) ) {
|
||||||
// wrong file type
|
// wrong file type
|
||||||
WriteLog( "Bad file: \"" + filename + "\" is of either unrecognized type or version" );
|
WriteLog( "Bad file: \"" + filename + "\" is of either unrecognized type or version" );
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -723,11 +723,13 @@ state_manager::deserialize_model( cParser &Input, scene::scratch_data &Scratchpa
|
|||||||
auto *instance = new TAnimModel( Nodedata );
|
auto *instance = new TAnimModel( Nodedata );
|
||||||
instance->RaAnglesSet( Scratchpad.location.rotation + rotation ); // dostosowanie do pochylania linii
|
instance->RaAnglesSet( Scratchpad.location.rotation + rotation ); // dostosowanie do pochylania linii
|
||||||
|
|
||||||
if( false == instance->Load( &Input, false ) ) {
|
if( instance->Load( &Input, false ) ) {
|
||||||
|
instance->location( transform( location, Scratchpad ) );
|
||||||
|
}
|
||||||
|
else {
|
||||||
// model nie wczytał się - ignorowanie node
|
// model nie wczytał się - ignorowanie node
|
||||||
SafeDelete( instance );
|
SafeDelete( instance );
|
||||||
}
|
}
|
||||||
instance->location( transform( location, Scratchpad ) );
|
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|||||||
38
sound.cpp
38
sound.cpp
@@ -135,6 +135,14 @@ sound_source::deserialize( cParser &Input, sound_type const Legacytype, int cons
|
|||||||
// restore parser behaviour
|
// restore parser behaviour
|
||||||
Input.autoclear( inputautoclear );
|
Input.autoclear( inputautoclear );
|
||||||
|
|
||||||
|
// catch and correct oddball cases with the same sample assigned as all parts of multipart sound
|
||||||
|
if( m_sounds[ begin ].buffer == m_sounds[ main ].buffer ) {
|
||||||
|
m_sounds[ begin ].buffer = null_handle;
|
||||||
|
}
|
||||||
|
if( m_sounds[ end ].buffer == m_sounds[ main ].buffer ) {
|
||||||
|
m_sounds[ end ].buffer = null_handle;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,7 +217,7 @@ sound_source::deserialize_mapping( cParser &Input ) {
|
|||||||
auto const pitch { Input.getToken<float>( false, "\n\r\t ,;" ) };
|
auto const pitch { Input.getToken<float>( false, "\n\r\t ,;" ) };
|
||||||
for( auto &chunk : m_soundchunks ) {
|
for( auto &chunk : m_soundchunks ) {
|
||||||
if( chunk.second.threshold == index ) {
|
if( chunk.second.threshold == index ) {
|
||||||
chunk.second.pitch = pitch;
|
chunk.second.pitch = ( pitch > 0.f ? pitch : 1.f );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -380,8 +388,9 @@ sound_source::play_combined() {
|
|||||||
if( soundpoint < soundchunk.second.fadein ) { break; }
|
if( soundpoint < soundchunk.second.fadein ) { break; }
|
||||||
if( soundpoint >= soundchunk.second.fadeout ) { continue; }
|
if( soundpoint >= soundchunk.second.fadeout ) { continue; }
|
||||||
|
|
||||||
if( ( soundchunk.first.playing > 0 )
|
if( ( soundchunk.first.buffer == null_handle )
|
||||||
|| ( soundchunk.first.buffer == null_handle ) ) {
|
|| ( ( ( m_flags & ( sound_flags::exclusive | sound_flags::looping ) ) != 0 )
|
||||||
|
&& ( soundchunk.first.playing > 0 ) ) ) {
|
||||||
// combined sounds only play looped, single copy of each activated chunk
|
// combined sounds only play looped, single copy of each activated chunk
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -606,13 +615,15 @@ sound_source::update_combined( audio::openal_source &Source ) {
|
|||||||
*/
|
*/
|
||||||
if( ( soundhandle & sound_id::chunk ) != 0 ) {
|
if( ( soundhandle & sound_id::chunk ) != 0 ) {
|
||||||
// for sound chunks, test whether the chunk should still be active given current value of the controlling variable
|
// for sound chunks, test whether the chunk should still be active given current value of the controlling variable
|
||||||
auto const soundpoint { compute_combined_point() };
|
if( ( m_flags & ( sound_flags::exclusive | sound_flags::looping ) ) != 0 ) {
|
||||||
auto const &soundchunk { m_soundchunks[ soundhandle ^ sound_id::chunk ] };
|
auto const soundpoint { compute_combined_point() };
|
||||||
if( ( soundpoint < soundchunk.second.fadein )
|
auto const &soundchunk { m_soundchunks[ soundhandle ^ sound_id::chunk ] };
|
||||||
|| ( soundpoint >= soundchunk.second.fadeout ) ) {
|
if( ( soundpoint < soundchunk.second.fadein )
|
||||||
Source.stop();
|
|| ( soundpoint >= soundchunk.second.fadeout ) ) {
|
||||||
update_counter( soundhandle, -1 );
|
Source.stop();
|
||||||
return;
|
update_counter( soundhandle, -1 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -832,6 +843,13 @@ sound_source::location() const {
|
|||||||
+ m_owner->VectorFront() * m_offset.z };
|
+ m_owner->VectorFront() * m_offset.z };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns defined range of the sound
|
||||||
|
float const
|
||||||
|
sound_source::range() const {
|
||||||
|
|
||||||
|
return m_range;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sound_source::update_counter( sound_handle const Sound, int const Value ) {
|
sound_source::update_counter( sound_handle const Sound, int const Value ) {
|
||||||
|
|
||||||
|
|||||||
7
sound.h
7
sound.h
@@ -30,8 +30,8 @@ enum sound_parameters {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum sound_flags {
|
enum sound_flags {
|
||||||
looping = 0x1, // the main sample will be looping; implied for multi-sounds
|
looping = 0x1, // the main sample will be looping
|
||||||
exclusive = 0x2, // the source won't dispatch more than one active instance of the sound; implied for multi-sounds
|
exclusive = 0x2, // the source won't dispatch more than one active instance of the sound
|
||||||
event = 0x80 // sound was activated by an event; we should keep note of the activation state for the update() calls it may receive
|
event = 0x80 // sound was activated by an event; we should keep note of the activation state for the update() calls it may receive
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -111,6 +111,9 @@ public:
|
|||||||
// returns location of the sound source in simulation region space
|
// returns location of the sound source in simulation region space
|
||||||
glm::dvec3 const
|
glm::dvec3 const
|
||||||
location() const;
|
location() const;
|
||||||
|
// returns defined range of the sound
|
||||||
|
float const
|
||||||
|
range() const;
|
||||||
|
|
||||||
// members
|
// members
|
||||||
float m_amplitudefactor { 1.f }; // helper, value potentially used by gain calculation
|
float m_amplitudefactor { 1.f }; // helper, value potentially used by gain calculation
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ static std::unordered_map<std::string, std::string> m_cabcontrols = {
|
|||||||
{ "horn_bt:", "horn" },
|
{ "horn_bt:", "horn" },
|
||||||
{ "hornlow_bt:", "low tone horn" },
|
{ "hornlow_bt:", "low tone horn" },
|
||||||
{ "hornhigh_bt:", "high tone horn" },
|
{ "hornhigh_bt:", "high tone horn" },
|
||||||
|
{ "whistle_bt:", "whistle" },
|
||||||
{ "fuse_bt:", "motor overload relay reset" },
|
{ "fuse_bt:", "motor overload relay reset" },
|
||||||
{ "converterfuse_bt:", "converter overload relay reset" },
|
{ "converterfuse_bt:", "converter overload relay reset" },
|
||||||
{ "stlinoff_bt:", "motor connectors" },
|
{ "stlinoff_bt:", "motor connectors" },
|
||||||
|
|||||||
2
uart.cpp
2
uart.cpp
@@ -160,7 +160,7 @@ void uart_input::poll()
|
|||||||
auto const bit { std::get<std::size_t>( entry ) % 8 };
|
auto const bit { std::get<std::size_t>( entry ) % 8 };
|
||||||
|
|
||||||
bool const state { ( ( buffer[ byte ] & ( 1 << bit ) ) != 0 ) };
|
bool const state { ( ( buffer[ byte ] & ( 1 << bit ) ) != 0 ) };
|
||||||
bool const changed { ( ( old_packet[ byte ] & ( 1 << bit ) ) != state ) };
|
bool const changed { ( ( ( old_packet[ byte ] & ( 1 << bit ) ) != 0 ) != state ) };
|
||||||
|
|
||||||
if( false == changed ) { continue; }
|
if( false == changed ) { continue; }
|
||||||
|
|
||||||
|
|||||||
110
uilayer.cpp
110
uilayer.cpp
@@ -202,13 +202,15 @@ ui_layer::on_key( int const Key, int const Action ) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GLFW_KEY_F11: {
|
case GLFW_KEY_F11: {
|
||||||
if (Action == GLFW_PRESS)
|
// scenario inspector
|
||||||
ui_log->enabled = !ui_log->enabled;
|
Global.iTextMode = Key;
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GLFW_KEY_F12: {
|
case GLFW_KEY_F12: {
|
||||||
|
if (Action == GLFW_PRESS)
|
||||||
|
ui_log->enabled = !ui_log->enabled;
|
||||||
// coś tam jeszcze
|
// coś tam jeszcze
|
||||||
Global.iTextMode = Key;
|
Global.iTextMode = Key;
|
||||||
return true;
|
return true;
|
||||||
@@ -341,7 +343,7 @@ ui_layer::update() {
|
|||||||
vehicle->ctOwner );
|
vehicle->ctOwner );
|
||||||
if( owner == nullptr ){ break; }
|
if( owner == nullptr ){ break; }
|
||||||
|
|
||||||
auto const table = owner->Timetable();
|
auto const *table = owner->TrainTimetable();
|
||||||
if( table == nullptr ) { break; }
|
if( table == nullptr ) { break; }
|
||||||
|
|
||||||
auto const &time = simulation::Time.data();
|
auto const &time = simulation::Time.data();
|
||||||
@@ -354,7 +356,7 @@ ui_layer::update() {
|
|||||||
uitextline1 += " (paused)";
|
uitextline1 += " (paused)";
|
||||||
}
|
}
|
||||||
|
|
||||||
uitextline2 = Bezogonkow( owner->Relation(), true ) + " (" + Bezogonkow( owner->Timetable()->TrainName, true ) + ")";
|
uitextline2 = Bezogonkow( owner->Relation(), true ) + " (" + Bezogonkow( owner->TrainName(), true ) + ")";
|
||||||
auto const nextstation = Bezogonkow( owner->NextStop(), true );
|
auto const nextstation = Bezogonkow( owner->NextStop(), true );
|
||||||
if( !nextstation.empty() ) {
|
if( !nextstation.empty() ) {
|
||||||
// jeśli jest podana relacja, to dodajemy punkt następnego zatrzymania
|
// jeśli jest podana relacja, to dodajemy punkt następnego zatrzymania
|
||||||
@@ -369,37 +371,62 @@ ui_layer::update() {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// header
|
// header
|
||||||
UITable->text_lines.emplace_back( "+----------------------------+-------+-------+-----+", Global.UITextColor );
|
UITable->text_lines.emplace_back( "+-----+------------------------------------+-------+-----+", Global.UITextColor );
|
||||||
|
|
||||||
TMTableLine *tableline;
|
TMTableLine const *tableline;
|
||||||
for( int i = owner->iStationStart; i <= std::min( owner->iStationStart + 15, table->StationCount ); ++i ) {
|
for( int i = owner->iStationStart; i <= std::min( owner->iStationStart + 10, table->StationCount ); ++i ) {
|
||||||
// wyświetlenie pozycji z rozkładu
|
// wyświetlenie pozycji z rozkładu
|
||||||
tableline = table->TimeTable + i; // linijka rozkładu
|
tableline = table->TimeTable + i; // linijka rozkładu
|
||||||
|
|
||||||
std::string station =
|
|
||||||
( tableline->StationName + " " ).substr( 0, 26 );
|
|
||||||
std::string arrival =
|
|
||||||
( tableline->Ah >= 0 ?
|
|
||||||
to_string( int( 100 + tableline->Ah ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Am ) ).substr( 1, 2 ) :
|
|
||||||
" " );
|
|
||||||
std::string departure =
|
|
||||||
( tableline->Dh >= 0 ?
|
|
||||||
to_string( int( 100 + tableline->Dh ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Dm ) ).substr( 1, 2 ) :
|
|
||||||
" " );
|
|
||||||
std::string vmax =
|
std::string vmax =
|
||||||
" "
|
" "
|
||||||
+ to_string( tableline->vmax, 0 );
|
+ to_string( tableline->vmax, 0 );
|
||||||
vmax = vmax.substr( vmax.length() - 3, 3 ); // z wyrównaniem do prawej
|
vmax = vmax.substr( vmax.size() - 3, 3 ); // z wyrównaniem do prawej
|
||||||
|
std::string const station = (
|
||||||
|
Bezogonkow( tableline->StationName, true )
|
||||||
|
+ " " )
|
||||||
|
.substr( 0, 34 );
|
||||||
|
std::string const location = (
|
||||||
|
( tableline->km > 0.0 ?
|
||||||
|
to_string( tableline->km, 2 ) :
|
||||||
|
"" )
|
||||||
|
+ " " )
|
||||||
|
.substr( 0, 34 - tableline->StationWare.size() );
|
||||||
|
std::string const arrival = (
|
||||||
|
tableline->Ah >= 0 ?
|
||||||
|
to_string( int( 100 + tableline->Ah ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Am ) ).substr( 1, 2 ) :
|
||||||
|
" | " );
|
||||||
|
std::string const departure = (
|
||||||
|
tableline->Dh >= 0 ?
|
||||||
|
to_string( int( 100 + tableline->Dh ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Dm ) ).substr( 1, 2 ) :
|
||||||
|
" | " );
|
||||||
|
auto const candeparture = (
|
||||||
|
( owner->iStationStart < table->StationIndex )
|
||||||
|
&& ( i < table->StationIndex )
|
||||||
|
&& ( ( time.wHour * 60 + time.wMinute ) >= ( tableline->Dh * 60 + tableline->Dm ) ) );
|
||||||
|
auto traveltime =
|
||||||
|
" "
|
||||||
|
+ ( i < 2 ? "" :
|
||||||
|
tableline->Ah >= 0 ? to_string( CompareTime( table->TimeTable[ i - 1 ].Dh, table->TimeTable[ i - 1 ].Dm, tableline->Ah, tableline->Am ), 0 ) :
|
||||||
|
to_string( std::max( 0.0, CompareTime( table->TimeTable[ i - 1 ].Dh, table->TimeTable[ i - 1 ].Dm, tableline->Dh, tableline->Dm ) - 0.5 ), 0 ) );
|
||||||
|
traveltime = traveltime.substr( traveltime.size() - 3, 3 ); // z wyrównaniem do prawej
|
||||||
|
|
||||||
UITable->text_lines.emplace_back(
|
UITable->text_lines.emplace_back(
|
||||||
Bezogonkow( "| " + station + " | " + arrival + " | " + departure + " | " + vmax + " | " + tableline->StationWare, true ),
|
( "| " + vmax + " | " + station + " | " + arrival + " | " + traveltime + " |" ),
|
||||||
( ( owner->iStationStart < table->StationIndex )
|
( candeparture ?
|
||||||
&& ( i < table->StationIndex )
|
glm::vec4( 0.0f, 1.0f, 0.0f, 1.0f ) :// czas minął i odjazd był, to nazwa stacji będzie na zielono
|
||||||
&& ( ( time.wHour * 60 + time.wMinute ) >= ( tableline->Dh * 60 + tableline->Dm ) ) ?
|
Global.UITextColor ) );
|
||||||
|
UITable->text_lines.emplace_back(
|
||||||
|
( "| | " + location + tableline->StationWare + " | " + departure + " | |" ),
|
||||||
|
( candeparture ?
|
||||||
glm::vec4( 0.0f, 1.0f, 0.0f, 1.0f ) :// czas minął i odjazd był, to nazwa stacji będzie na zielono
|
glm::vec4( 0.0f, 1.0f, 0.0f, 1.0f ) :// czas minął i odjazd był, to nazwa stacji będzie na zielono
|
||||||
Global.UITextColor ) );
|
Global.UITextColor ) );
|
||||||
// divider/footer
|
// divider/footer
|
||||||
UITable->text_lines.emplace_back( "+----------------------------+-------+-------+-----+", Global.UITextColor );
|
UITable->text_lines.emplace_back( "+-----+------------------------------------+-------+-----+", Global.UITextColor );
|
||||||
|
}
|
||||||
|
if( owner->iStationStart + 10 < table->StationCount ) {
|
||||||
|
// if we can't display entire timetable, add a scrolling indicator at the bottom
|
||||||
|
UITable->text_lines.emplace_back( " ... ", Global.UITextColor );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -458,7 +485,7 @@ ui_layer::update() {
|
|||||||
|
|
||||||
auto const train { Global.pWorld->train() };
|
auto const train { Global.pWorld->train() };
|
||||||
if( ( train != nullptr ) && ( train->Dynamic() == vehicle ) ) {
|
if( ( train != nullptr ) && ( train->Dynamic() == vehicle ) ) {
|
||||||
uitextline2 += " R: " + std::to_string( train->RadioChannel() );
|
uitextline2 += ( vehicle->MoverParameters->Radio ? " R: " : " r: " ) + std::to_string( train->RadioChannel() );
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
uitextline2 +=
|
uitextline2 +=
|
||||||
@@ -661,7 +688,34 @@ ui_layer::update() {
|
|||||||
|
|
||||||
case( GLFW_KEY_F10 ) : {
|
case( GLFW_KEY_F10 ) : {
|
||||||
|
|
||||||
uitextline1 = ( "Press [Y] key to quit / Aby zakonczyc program, przycisnij klawisz [Y]." );
|
uitextline1 = "Press [Y] key to quit / Aby zakonczyc program, przycisnij klawisz [Y].";
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case( GLFW_KEY_F11 ): {
|
||||||
|
// scenario inspector
|
||||||
|
auto const time { Timer::GetTime() };
|
||||||
|
auto const *event { simulation::Events.begin() };
|
||||||
|
auto eventtableindex{ 0 };
|
||||||
|
while( ( event != nullptr )
|
||||||
|
&& ( eventtableindex < 30 ) ) {
|
||||||
|
|
||||||
|
if( ( false == event->m_ignored )
|
||||||
|
&& ( true == event->bEnabled ) ) {
|
||||||
|
|
||||||
|
auto const delay { " " + to_string( std::max( 0.0, event->fStartTime - time ), 1 ) };
|
||||||
|
auto const eventline =
|
||||||
|
"Delay: " + delay.substr( delay.length() - 6 )
|
||||||
|
+ ", Event: " + event->asName
|
||||||
|
+ ( event->Activator ? " (by: " + event->Activator->asName + ")" : "" )
|
||||||
|
+ ( event->evJoined ? " (joint event)" : "" );
|
||||||
|
|
||||||
|
UITable->text_lines.emplace_back( eventline, Global.UITextColor );
|
||||||
|
++eventtableindex;
|
||||||
|
}
|
||||||
|
event = event->evNext;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,6 +58,26 @@ std::string Now() {
|
|||||||
return converter.str();
|
return converter.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// zwraca różnicę czasu
|
||||||
|
// jeśli pierwsza jest aktualna, a druga rozkładowa, to ujemna oznacza opóżnienie
|
||||||
|
// na dłuższą metę trzeba uwzględnić datę, jakby opóżnienia miały przekraczać 12h (towarowych)
|
||||||
|
double CompareTime(double t1h, double t1m, double t2h, double t2m) {
|
||||||
|
|
||||||
|
double t;
|
||||||
|
|
||||||
|
if ((t2h < 0))
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t = (t2h - t1h) * 60 + t2m - t1m; // jeśli t2=00:05, a t1=23:50, to różnica wyjdzie ujemna
|
||||||
|
if ((t < -720)) // jeśli różnica przekracza 12h na minus
|
||||||
|
t = t + 1440; // to dodanie doby minut;else
|
||||||
|
if ((t > 720)) // jeśli przekracza 12h na plus
|
||||||
|
t = t - 1440; // to odjęcie doby minut
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SetFlag( int &Flag, int const Value ) {
|
bool SetFlag( int &Flag, int const Value ) {
|
||||||
|
|
||||||
if( Value > 0 ) {
|
if( Value > 0 ) {
|
||||||
|
|||||||
@@ -78,6 +78,8 @@ inline double BorlandTime()
|
|||||||
|
|
||||||
std::string Now();
|
std::string Now();
|
||||||
|
|
||||||
|
double CompareTime( double t1h, double t1m, double t2h, double t2m );
|
||||||
|
|
||||||
/*funkcje logiczne*/
|
/*funkcje logiczne*/
|
||||||
inline bool TestFlag( int const Flag, int const Value ) { return ( ( Flag & Value ) == Value ); }
|
inline bool TestFlag( int const Flag, int const Value ) { return ( ( Flag & Value ) == Value ); }
|
||||||
bool SetFlag( int &Flag, int const Value);
|
bool SetFlag( int &Flag, int const Value);
|
||||||
|
|||||||
Reference in New Issue
Block a user