mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 10:29:19 +02:00
basic isolated track section hierarchy, track vertical radius property, ai passenger stop logic tweaks, ai signal speed limit tracking logic tweaks
This commit is contained in:
77
Driver.cpp
77
Driver.cpp
@@ -812,6 +812,8 @@ void TController::TableCheck(double fDistance)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto const passengerstopmaxdistance { 400.0 }; // maximum allowed distance between passenger stop point and consist head
|
||||||
|
|
||||||
TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc)
|
TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc)
|
||||||
{ // ustalenie parametrów, zwraca typ komendy, jeśli sygnał podaje prędkość do jazdy
|
{ // ustalenie parametrów, zwraca typ komendy, jeśli sygnał podaje prędkość do jazdy
|
||||||
// fVelDes - prędkość zadana
|
// fVelDes - prędkość zadana
|
||||||
@@ -826,14 +828,17 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
TCommandType go = TCommandType::cm_Unknown;
|
TCommandType go = TCommandType::cm_Unknown;
|
||||||
eSignNext = NULL;
|
eSignNext = NULL;
|
||||||
// te flagi są ustawiane tutaj, w razie potrzeby
|
// te flagi są ustawiane tutaj, w razie potrzeby
|
||||||
iDrivigFlags &= ~(moveTrackEnd | moveSwitchFound | moveSemaphorFound | moveSpeedLimitFound);
|
iDrivigFlags &= ~(moveTrackEnd | moveSwitchFound | moveSemaphorFound | /*moveSpeedLimitFound*/ moveStopPointFound );
|
||||||
|
|
||||||
for( std::size_t i = 0; i < sSpeedTable.size(); ++i )
|
for( std::size_t i = 0; i < sSpeedTable.size(); ++i )
|
||||||
{ // sprawdzenie rekordów od (iFirst) do (iLast), o ile są istotne
|
{ // sprawdzenie rekordów od (iFirst) do (iLast), o ile są istotne
|
||||||
if (sSpeedTable[i].iFlags & spEnabled) // badanie istotności
|
if (sSpeedTable[i].iFlags & spEnabled) // badanie istotności
|
||||||
{ // o ile dana pozycja tabelki jest istotna
|
{ // o ile dana pozycja tabelki jest istotna
|
||||||
if (sSpeedTable[i].iFlags & spPassengerStopPoint)
|
if (sSpeedTable[i].iFlags & spPassengerStopPoint) {
|
||||||
{ // jeśli przystanek, trzeba obsłużyć wg rozkładu
|
// jeśli przystanek, trzeba obsłużyć wg rozkładu
|
||||||
|
iDrivigFlags |= moveStopPointFound;
|
||||||
|
// stop points are irrelevant when not in one of the basic modes
|
||||||
|
if( ( OrderCurrentGet() & ( Obey_train | Shunt ) ) == 0 ) { continue; }
|
||||||
// first 19 chars of the command is expected to be "PassengerStopPoint:" so we skip them
|
// first 19 chars of the command is expected to be "PassengerStopPoint:" so we skip them
|
||||||
if ( ToLower(sSpeedTable[i].evEvent->CommandGet()).compare( 19, sizeof(asNextStop), ToLower(asNextStop)) != 0 )
|
if ( ToLower(sSpeedTable[i].evEvent->CommandGet()).compare( 19, sizeof(asNextStop), ToLower(asNextStop)) != 0 )
|
||||||
{ // jeśli nazwa nie jest zgodna
|
{ // jeśli nazwa nie jest zgodna
|
||||||
@@ -858,7 +863,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
{ // jeśli nie ma tu postoju
|
{ // jeśli nie ma tu postoju
|
||||||
sSpeedTable[i].fVelNext = -1; // maksymalna prędkość w tym miejscu
|
sSpeedTable[i].fVelNext = -1; // maksymalna prędkość w tym miejscu
|
||||||
// przy 160km/h jedzie 44m/s, to da dokładność rzędu 5 sekund
|
// przy 160km/h jedzie 44m/s, to da dokładność rzędu 5 sekund
|
||||||
if (sSpeedTable[i].fDist < 200.0) {
|
if (sSpeedTable[i].fDist < passengerstopmaxdistance * 0.5 ) {
|
||||||
// zaliczamy posterunek w pewnej odległości przed (choć W4 nie zasłania już semafora)
|
// zaliczamy posterunek w pewnej odległości przed (choć W4 nie zasłania już semafora)
|
||||||
#if LOGSTOPS
|
#if LOGSTOPS
|
||||||
WriteLog(
|
WriteLog(
|
||||||
@@ -880,8 +885,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
} // koniec obsługi przelotu na W4
|
} // koniec obsługi przelotu na W4
|
||||||
else {
|
else {
|
||||||
// zatrzymanie na W4
|
// zatrzymanie na W4
|
||||||
if ( ( false == sSpeedTable[i].bMoved )
|
if ( false == sSpeedTable[i].bMoved ) {
|
||||||
&& ( ( OrderCurrentGet() & ( Obey_train | Shunt ) ) != 0 ) ) {
|
|
||||||
// potentially shift the stop point in accordance with its defined parameters
|
// potentially shift the stop point in accordance with its defined parameters
|
||||||
/*
|
/*
|
||||||
// https://rainsted.com/pl/Wersja/18.2.133#Okr.C4.99gi_dla_W4_i_W32
|
// https://rainsted.com/pl/Wersja/18.2.133#Okr.C4.99gi_dla_W4_i_W32
|
||||||
@@ -910,16 +914,17 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
isatpassengerstop = (
|
isatpassengerstop = (
|
||||||
|
( sSpeedTable[ i ].fDist <= passengerstopmaxdistance )
|
||||||
// Ra 2F1I: odległość plus długość pociągu musi być mniejsza od długości
|
// Ra 2F1I: odległość plus długość pociągu musi być mniejsza od długości
|
||||||
// peronu, chyba że pociąg jest dłuższy, to wtedy minimalna.
|
// peronu, chyba że pociąg jest dłuższy, to wtedy minimalna.
|
||||||
// jeśli długość peronu ((sSpeedTable[i].evEvent->ValueGet(2)) nie podana,
|
// jeśli długość peronu ((sSpeedTable[i].evEvent->ValueGet(2)) nie podana,
|
||||||
// przyjąć odległość fMinProximityDist
|
// przyjąć odległość fMinProximityDist
|
||||||
( iDrivigFlags & moveStopCloser ) ?
|
&& ( ( iDrivigFlags & moveStopCloser ) != 0 ?
|
||||||
( sSpeedTable[ i ].fDist + fLength ) <=
|
sSpeedTable[ i ].fDist + fLength <=
|
||||||
std::max(
|
std::max(
|
||||||
std::abs( sSpeedTable[ i ].evEvent->ValueGet( 2 ) ),
|
std::abs( sSpeedTable[ i ].evEvent->ValueGet( 2 ) ),
|
||||||
2.0 * fMaxProximityDist + fLength ) : // fmaxproximitydist typically equals ~50 m
|
2.0 * fMaxProximityDist + fLength ) : // fmaxproximitydist typically equals ~50 m
|
||||||
sSpeedTable[ i ].fDist < d_to_next_sem );
|
sSpeedTable[ i ].fDist < d_to_next_sem ) );
|
||||||
|
|
||||||
if( !eSignNext ) {
|
if( !eSignNext ) {
|
||||||
//jeśli nie widzi następnego sygnału ustawia dotychczasową
|
//jeśli nie widzi następnego sygnału ustawia dotychczasową
|
||||||
@@ -928,8 +933,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
if( mvOccupied->Vel > 0.3 ) {
|
if( mvOccupied->Vel > 0.3 ) {
|
||||||
// jeśli jedzie (nie trzeba czekać, aż się drgania wytłumią - drzwi zamykane od 1.0) to będzie zatrzymanie
|
// jeśli jedzie (nie trzeba czekać, aż się drgania wytłumią - drzwi zamykane od 1.0) to będzie zatrzymanie
|
||||||
sSpeedTable[ i ].fVelNext = 0;
|
sSpeedTable[ i ].fVelNext = 0;
|
||||||
}
|
} else if( true == isatpassengerstop ) {
|
||||||
else if( true == isatpassengerstop ) {
|
|
||||||
// jeśli się zatrzymał przy W4, albo stał w momencie zobaczenia W4
|
// jeśli się zatrzymał przy W4, albo stał w momencie zobaczenia W4
|
||||||
if( !AIControllFlag ) {
|
if( !AIControllFlag ) {
|
||||||
// w razie przełączenia na AI ma nie podciągać do W4, gdy użytkownik zatrzymał za daleko
|
// w razie przełączenia na AI ma nie podciągać do W4, gdy użytkownik zatrzymał za daleko
|
||||||
@@ -1069,7 +1073,11 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
iDrivigFlags |= moveStopHere | moveStartHorn;
|
iDrivigFlags |= moveStopHere | moveStartHorn;
|
||||||
continue; // nie analizować prędkości
|
continue; // nie analizować prędkości
|
||||||
} // koniec obsługi ostatniej stacji
|
} // koniec obsługi ostatniej stacji
|
||||||
} // if (MoverParameters->Vel==0.0)
|
} // vel 0, at passenger stop
|
||||||
|
else {
|
||||||
|
// HACK: momentarily deactivate W4 to trick the controller into moving closer
|
||||||
|
sSpeedTable[ i ].fVelNext = -1;
|
||||||
|
} // vel 0, outside of passenger stop
|
||||||
} // koniec obsługi zatrzymania na W4
|
} // koniec obsługi zatrzymania na W4
|
||||||
} // koniec warunku pomijania W4 podczas zmiany czoła
|
} // koniec warunku pomijania W4 podczas zmiany czoła
|
||||||
else
|
else
|
||||||
@@ -1121,15 +1129,11 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
if (sSpeedTable[i].iFlags & spOutsideStation)
|
if (sSpeedTable[i].iFlags & spOutsideStation)
|
||||||
{ // jeśli W5, to reakcja zależna od trybu jazdy
|
{ // jeśli W5, to reakcja zależna od trybu jazdy
|
||||||
if (OrderCurrentGet() & Obey_train)
|
if (OrderCurrentGet() & Obey_train)
|
||||||
{ // w trybie pociągowym: można przyspieszyć do wskazanej prędkości (po
|
{ // w trybie pociągowym: można przyspieszyć do wskazanej prędkości (po zjechaniu z rozjazdów)
|
||||||
// zjechaniu z rozjazdów)
|
|
||||||
v = -1.0; // ignorować?
|
v = -1.0; // ignorować?
|
||||||
//TODO trzeba zmienić przypisywanie VelSignal na VelSignalLast
|
|
||||||
if (sSpeedTable[i].fDist < 0.0) // jeśli wskaźnik został minięty
|
if (sSpeedTable[i].fDist < 0.0) // jeśli wskaźnik został minięty
|
||||||
{
|
{
|
||||||
VelSignalLast = v; //ustawienie prędkości na -1
|
VelSignalLast = v; //ustawienie prędkości na -1
|
||||||
// iStationStart=TrainParams->StationIndex; //zaktualizować
|
|
||||||
// wyświetlanie rozkładu
|
|
||||||
}
|
}
|
||||||
else if (!(iDrivigFlags & moveSwitchFound)) // jeśli rozjazdy już minięte
|
else if (!(iDrivigFlags & moveSwitchFound)) // jeśli rozjazdy już minięte
|
||||||
VelSignalLast = v; //!!! to też koniec ograniczenia
|
VelSignalLast = v; //!!! to też koniec ograniczenia
|
||||||
@@ -1174,7 +1178,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
iDrivigFlags |= moveSemaphorFound; //jeśli z przodu to dajemy falgę, że jest
|
iDrivigFlags |= moveSemaphorFound; //jeśli z przodu to dajemy falgę, że jest
|
||||||
d_to_next_sem = Min0R(sSpeedTable[i].fDist, d_to_next_sem);
|
d_to_next_sem = std::min(sSpeedTable[i].fDist, d_to_next_sem);
|
||||||
}
|
}
|
||||||
if( sSpeedTable[ i ].fDist <= d_to_next_sem )
|
if( sSpeedTable[ i ].fDist <= d_to_next_sem )
|
||||||
{
|
{
|
||||||
@@ -1338,7 +1342,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
&& ( true == TestFlag( sSpeedTable[ i ].iFlags, ( spEnabled | spEvent | spPassengerStopPoint ) ) )
|
&& ( true == TestFlag( sSpeedTable[ i ].iFlags, ( spEnabled | spEvent | spPassengerStopPoint ) ) )
|
||||||
&& ( false == isatpassengerstop ) ) {
|
&& ( false == isatpassengerstop ) ) {
|
||||||
// ma podjechać bliżej - czy na pewno w tym miejscu taki warunek?
|
// ma podjechać bliżej - czy na pewno w tym miejscu taki warunek?
|
||||||
a = ( ( ( iDrivigFlags & moveStopCloser ) != 0 ) ?
|
a = ( ( d > passengerstopmaxdistance ) || ( ( iDrivigFlags & moveStopCloser ) != 0 ) ?
|
||||||
fAcc :
|
fAcc :
|
||||||
0.0 );
|
0.0 );
|
||||||
}
|
}
|
||||||
@@ -1409,9 +1413,12 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
} // if (sSpeedTable[i].iFlags&1)
|
} // if (sSpeedTable[i].iFlags&1)
|
||||||
} // for
|
} // for
|
||||||
|
|
||||||
if (VelSignalLast >= 0.0 && !(iDrivigFlags & (moveSemaphorFound | moveSwitchFound)) &&
|
// jeśli mieliśmy ograniczenie z semafora i nie ma przed nami
|
||||||
(OrderCurrentGet() & Obey_train))
|
if( ( VelSignalLast >= 0.0 )
|
||||||
VelSignalLast = -1.0; // jeśli mieliśmy ograniczenie z semafora i nie ma przed nami
|
&& ( ( iDrivigFlags & ( moveSemaphorFound | moveSwitchFound | moveStopPointFound ) ) == 0 )
|
||||||
|
&& ( true == TestFlag( OrderCurrentGet(), Obey_train ) ) ) {
|
||||||
|
VelSignalLast = -1.0;
|
||||||
|
}
|
||||||
|
|
||||||
//analiza spisanych z tabelki ograniczeń i nadpisanie aktualnego
|
//analiza spisanych z tabelki ograniczeń i nadpisanie aktualnego
|
||||||
if( ( true == isatpassengerstop ) && ( mvOccupied->Vel < 0.01 ) ) {
|
if( ( true == isatpassengerstop ) && ( mvOccupied->Vel < 0.01 ) ) {
|
||||||
@@ -2562,8 +2569,9 @@ bool TController::ReleaseEngine() {
|
|||||||
eAction = TAction::actSleep; //śpi (wygaszony)
|
eAction = TAction::actSleep; //śpi (wygaszony)
|
||||||
|
|
||||||
OrderNext(Wait_for_orders); //żeby nie próbował coś robić dalej
|
OrderNext(Wait_for_orders); //żeby nie próbował coś robić dalej
|
||||||
TableClear(); // zapominamy ograniczenia
|
|
||||||
iDrivigFlags &= ~moveActive; // ma nie skanować sygnałów i nie reagować na komendy
|
iDrivigFlags &= ~moveActive; // ma nie skanować sygnałów i nie reagować na komendy
|
||||||
|
TableClear(); // zapominamy ograniczenia
|
||||||
|
VelSignalLast = -1.0;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@@ -3332,10 +3340,10 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
|
|||||||
iStationStart = TrainParams->StationIndex;
|
iStationStart = TrainParams->StationIndex;
|
||||||
asNextStop = TrainParams->NextStop();
|
asNextStop = TrainParams->NextStop();
|
||||||
iDrivigFlags |= movePrimary; // skoro dostał rozkład, to jest teraz głównym
|
iDrivigFlags |= movePrimary; // skoro dostał rozkład, to jest teraz głównym
|
||||||
NewCommand = Global.asCurrentSceneryPath + NewCommand;
|
// NewCommand = Global.asCurrentSceneryPath + NewCommand;
|
||||||
auto lookup =
|
auto lookup =
|
||||||
FileExists(
|
FileExists(
|
||||||
{ NewCommand },
|
{ Global.asCurrentSceneryPath + NewCommand, szSoundPath + NewCommand },
|
||||||
{ ".ogg", ".flac", ".wav" } );
|
{ ".ogg", ".flac", ".wav" } );
|
||||||
if( false == lookup.first.empty() ) {
|
if( false == lookup.first.empty() ) {
|
||||||
// wczytanie dźwięku odjazdu podawanego bezpośrenido
|
// wczytanie dźwięku odjazdu podawanego bezpośrenido
|
||||||
@@ -3343,9 +3351,10 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
|
|||||||
iGuardRadio = 0; // nie przez radio
|
iGuardRadio = 0; // nie przez radio
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
NewCommand += "radio";
|
||||||
auto lookup =
|
auto lookup =
|
||||||
FileExists(
|
FileExists(
|
||||||
{ NewCommand + "radio" },
|
{ Global.asCurrentSceneryPath + NewCommand, szSoundPath + NewCommand },
|
||||||
{ ".ogg", ".flac", ".wav" } );
|
{ ".ogg", ".flac", ".wav" } );
|
||||||
if( false == lookup.first.empty() ) {
|
if( false == lookup.first.empty() ) {
|
||||||
// wczytanie dźwięku odjazdu w wersji radiowej (słychać tylko w kabinie)
|
// wczytanie dźwięku odjazdu w wersji radiowej (słychać tylko w kabinie)
|
||||||
@@ -4051,10 +4060,12 @@ TController::UpdateSituation(double dt) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// route scan
|
// route scan
|
||||||
double routescanrange = (
|
auto const routescanrange {
|
||||||
mvOccupied->Vel > 5.0 ?
|
std::max(
|
||||||
400 + fBrakeDist :
|
750.0,
|
||||||
30.0 * fDriverDist ); // 1500m dla stojących pociągów;
|
mvOccupied->Vel > 5.0 ?
|
||||||
|
400 + fBrakeDist :
|
||||||
|
30.0 * fDriverDist ) }; // 1500m dla stojących pociągów;
|
||||||
// Ra 2015-01: przy dłuższej drodze skanowania AI jeździ spokojniej
|
// Ra 2015-01: przy dłuższej drodze skanowania AI jeździ spokojniej
|
||||||
// 2. Sprawdzić, czy tabelka pokrywa założony odcinek (nie musi, jeśli jest STOP).
|
// 2. Sprawdzić, czy tabelka pokrywa założony odcinek (nie musi, jeśli jest STOP).
|
||||||
// 3. Sprawdzić, czy trajektoria ruchu przechodzi przez zwrotnice - jeśli tak, to sprawdzić,
|
// 3. Sprawdzić, czy trajektoria ruchu przechodzi przez zwrotnice - jeśli tak, to sprawdzić,
|
||||||
|
|||||||
3
Driver.h
3
Driver.h
@@ -52,9 +52,12 @@ enum TMovementStatus
|
|||||||
moveDoorOpened = 0x20000, // drzwi zostały otwarte - doliczyć czas na zamknięcie
|
moveDoorOpened = 0x20000, // drzwi zostały otwarte - doliczyć czas na zamknięcie
|
||||||
movePushPull = 0x40000, // zmiana czoła przez zmianę kabiny - nie odczepiać przy zmianie kierunku
|
movePushPull = 0x40000, // zmiana czoła przez zmianę kabiny - nie odczepiać przy zmianie kierunku
|
||||||
moveSemaphorFound = 0x80000, // na drodze skanowania został znaleziony semafor
|
moveSemaphorFound = 0x80000, // na drodze skanowania został znaleziony semafor
|
||||||
|
moveStopPointFound = 0x100000 // stop point detected ahead
|
||||||
|
/*
|
||||||
moveSemaphorWasElapsed = 0x100000, // minięty został semafor
|
moveSemaphorWasElapsed = 0x100000, // minięty został semafor
|
||||||
moveTrainInsideStation = 0x200000, // pociąg między semaforem a rozjazdami lub następnym semaforem
|
moveTrainInsideStation = 0x200000, // pociąg między semaforem a rozjazdami lub następnym semaforem
|
||||||
moveSpeedLimitFound = 0x400000 // pociąg w ograniczeniu z podaną jego długością
|
moveSpeedLimitFound = 0x400000 // pociąg w ograniczeniu z podaną jego długością
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TStopReason
|
enum TStopReason
|
||||||
|
|||||||
89
Track.cpp
89
Track.cpp
@@ -68,12 +68,12 @@ TSwitchExtension::TSwitchExtension(TTrack *owner, int const what)
|
|||||||
TSwitchExtension::~TSwitchExtension()
|
TSwitchExtension::~TSwitchExtension()
|
||||||
{ // nie ma nic do usuwania
|
{ // nie ma nic do usuwania
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
TIsolated::TIsolated()
|
TIsolated::TIsolated()
|
||||||
{ // utworznie pustego
|
{ // utworznie pustego
|
||||||
TIsolated("none", NULL);
|
TIsolated("none", NULL);
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
TIsolated::TIsolated(std::string const &n, TIsolated *i) :
|
TIsolated::TIsolated(std::string const &n, TIsolated *i) :
|
||||||
asName( n ), pNext( i )
|
asName( n ), pNext( i )
|
||||||
{
|
{
|
||||||
@@ -102,6 +102,15 @@ TIsolated * TIsolated::Find(std::string const &n)
|
|||||||
return pRoot;
|
return pRoot;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
TIsolated::AssignEvents() {
|
||||||
|
|
||||||
|
evBusy = simulation::Events.FindEvent( asName + ":busy" );
|
||||||
|
evFree = simulation::Events.FindEvent( asName + ":free" );
|
||||||
|
|
||||||
|
return ( evBusy != nullptr ) && ( evFree != nullptr );
|
||||||
|
}
|
||||||
|
|
||||||
void TIsolated::Modify(int i, TDynamicObject *o)
|
void TIsolated::Modify(int i, TDynamicObject *o)
|
||||||
{ // dodanie lub odjęcie osi
|
{ // dodanie lub odjęcie osi
|
||||||
if (iAxles)
|
if (iAxles)
|
||||||
@@ -131,6 +140,10 @@ void TIsolated::Modify(int i, TDynamicObject *o)
|
|||||||
pMemCell->UpdateValues( "", 0, int( pMemCell->Value2() ) | 1, update_memval2 ); // zmieniamy ostatnią wartość na nieparzystą
|
pMemCell->UpdateValues( "", 0, int( pMemCell->Value2() ) | 1, update_memval2 ); // zmieniamy ostatnią wartość na nieparzystą
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// pass the event to the parent
|
||||||
|
if( pParent != nullptr ) {
|
||||||
|
pParent->Modify( i, o );
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// tworzenie nowego odcinka ruchu
|
// tworzenie nowego odcinka ruchu
|
||||||
@@ -851,6 +864,12 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin)
|
|||||||
iAction |= 0x40; // flaga opuszczenia pantografu (tor uwzględniany w skanowaniu jako
|
iAction |= 0x40; // flaga opuszczenia pantografu (tor uwzględniany w skanowaniu jako
|
||||||
// ograniczenie dla pantografujących)
|
// ograniczenie dla pantografujących)
|
||||||
}
|
}
|
||||||
|
else if( str == "vradius" ) {
|
||||||
|
// y-axis track radius
|
||||||
|
// NOTE: not used/implemented
|
||||||
|
parser->getTokens();
|
||||||
|
*parser >> fVerticalRadius;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ErrorLog("Unknown property: \"" + str + "\" in track \"" + m_name + "\"");
|
ErrorLog("Unknown property: \"" + str + "\" in track \"" + m_name + "\"");
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
@@ -954,19 +973,6 @@ std::string TTrack::IsolatedName()
|
|||||||
return "";
|
return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TTrack::IsolatedEventsAssign(TEvent *busy, TEvent *free)
|
|
||||||
{ // ustawia zdarzenia dla odcinka izolowanego
|
|
||||||
if (pIsolated)
|
|
||||||
{
|
|
||||||
if (busy)
|
|
||||||
pIsolated->evBusy = busy;
|
|
||||||
if (free)
|
|
||||||
pIsolated->evFree = free;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ABu: przeniesione z Path.h i poprawione!!!
|
// ABu: przeniesione z Path.h i poprawione!!!
|
||||||
bool TTrack::AddDynamicObject(TDynamicObject *Dynamic)
|
bool TTrack::AddDynamicObject(TDynamicObject *Dynamic)
|
||||||
{ // dodanie pojazdu do trajektorii
|
{ // dodanie pojazdu do trajektorii
|
||||||
@@ -2764,7 +2770,7 @@ TTrack::export_as_text_( std::ostream &Output ) const {
|
|||||||
eEnvironment == e_canyon ? "canyon" :
|
eEnvironment == e_canyon ? "canyon" :
|
||||||
eEnvironment == e_mountains ? "mountains" :
|
eEnvironment == e_mountains ? "mountains" :
|
||||||
"none" )
|
"none" )
|
||||||
<< ' ';
|
<< ' ';
|
||||||
// visibility
|
// visibility
|
||||||
// NOTE: 'invis' would be less wrong than 'unvis', but potentially incompatible with old 3rd party tools
|
// NOTE: 'invis' would be less wrong than 'unvis', but potentially incompatible with old 3rd party tools
|
||||||
Output << ( m_visible ? "vis" : "unvis" ) << ' ';
|
Output << ( m_visible ? "vis" : "unvis" ) << ' ';
|
||||||
@@ -2772,8 +2778,8 @@ TTrack::export_as_text_( std::ostream &Output ) const {
|
|||||||
// texture parameters are supplied only if the path is set as visible
|
// texture parameters are supplied only if the path is set as visible
|
||||||
auto texturefile { (
|
auto texturefile { (
|
||||||
m_material1 != null_handle ?
|
m_material1 != null_handle ?
|
||||||
GfxRenderer.Material( m_material1 ).name :
|
GfxRenderer.Material( m_material1 ).name :
|
||||||
"none" ) };
|
"none" ) };
|
||||||
if( texturefile.find( szTexturePath ) == 0 ) {
|
if( texturefile.find( szTexturePath ) == 0 ) {
|
||||||
// don't include 'textures/' in the path
|
// don't include 'textures/' in the path
|
||||||
texturefile.erase( 0, std::string{ szTexturePath }.size() );
|
texturefile.erase( 0, std::string{ szTexturePath }.size() );
|
||||||
@@ -2784,8 +2790,8 @@ TTrack::export_as_text_( std::ostream &Output ) const {
|
|||||||
|
|
||||||
texturefile = (
|
texturefile = (
|
||||||
m_material2 != null_handle ?
|
m_material2 != null_handle ?
|
||||||
GfxRenderer.Material( m_material2 ).name :
|
GfxRenderer.Material( m_material2 ).name :
|
||||||
"none" );
|
"none" );
|
||||||
if( texturefile.find( szTexturePath ) == 0 ) {
|
if( texturefile.find( szTexturePath ) == 0 ) {
|
||||||
// don't include 'textures/' in the path
|
// don't include 'textures/' in the path
|
||||||
texturefile.erase( 0, std::string{ szTexturePath }.size() );
|
texturefile.erase( 0, std::string{ szTexturePath }.size() );
|
||||||
@@ -2828,11 +2834,14 @@ TTrack::export_as_text_( std::ostream &Output ) const {
|
|||||||
|
|
||||||
for( auto &eventsequence : eventsequences ) {
|
for( auto &eventsequence : eventsequences ) {
|
||||||
for( auto &event : *( eventsequence.second ) ) {
|
for( auto &event : *( eventsequence.second ) ) {
|
||||||
if( false == event.first.empty() ) {
|
// NOTE: actual event name can be potentially different from its cached name, if it was renamed in the editor
|
||||||
Output
|
// therefore on export we pull the name from the event itself, if the binding isn't broken
|
||||||
<< eventsequence.first << ' '
|
Output
|
||||||
<< event.first << ' ';
|
<< eventsequence.first << ' '
|
||||||
}
|
<< ( event.second != nullptr ?
|
||||||
|
event.second->asName :
|
||||||
|
event.first )
|
||||||
|
<< ' ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( ( SwitchExtension )
|
if( ( SwitchExtension )
|
||||||
@@ -2850,6 +2859,9 @@ TTrack::export_as_text_( std::ostream &Output ) const {
|
|||||||
if( fOverhead != -1.0 ) {
|
if( fOverhead != -1.0 ) {
|
||||||
Output << "overhead " << fOverhead << ' ';
|
Output << "overhead " << fOverhead << ' ';
|
||||||
}
|
}
|
||||||
|
if( fVerticalRadius != 0.f ) {
|
||||||
|
Output << "vradius " << fVerticalRadius << ' ';
|
||||||
|
}
|
||||||
// footer
|
// footer
|
||||||
Output
|
Output
|
||||||
<< "endtrack"
|
<< "endtrack"
|
||||||
@@ -3091,15 +3103,6 @@ path_table::InitTracks() {
|
|||||||
}
|
}
|
||||||
} // switch
|
} // switch
|
||||||
|
|
||||||
// pobranie nazwy odcinka izolowanego
|
|
||||||
auto const isolatedname { track->IsolatedName() };
|
|
||||||
if( false == isolatedname.empty() ) {
|
|
||||||
// jeśli została zwrócona nazwa
|
|
||||||
track->IsolatedEventsAssign(
|
|
||||||
simulation::Events.FindEvent( isolatedname + ":busy" ),
|
|
||||||
simulation::Events.FindEvent( isolatedname + ":free" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ( trackname[ 0 ] == '*' )
|
if( ( trackname[ 0 ] == '*' )
|
||||||
&& ( !track->CurrentPrev() && track->CurrentNext() ) ) {
|
&& ( !track->CurrentPrev() && track->CurrentNext() ) ) {
|
||||||
// możliwy portal, jeśli nie podłączony od strony 1
|
// możliwy portal, jeśli nie podłączony od strony 1
|
||||||
@@ -3108,25 +3111,25 @@ path_table::InitTracks() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TIsolated *isolated = TIsolated::Root();
|
auto *isolated = TIsolated::Root();
|
||||||
while( isolated ) {
|
while( isolated ) {
|
||||||
// jeśli się znajdzie, to podać wskaźnik
|
|
||||||
|
isolated->AssignEvents();
|
||||||
|
|
||||||
auto *memorycell = simulation::Memory.find( isolated->asName ); // czy jest komóka o odpowiedniej nazwie
|
auto *memorycell = simulation::Memory.find( isolated->asName ); // czy jest komóka o odpowiedniej nazwie
|
||||||
if( memorycell != nullptr ) {
|
if( memorycell == nullptr ) {
|
||||||
// przypisanie powiązanej komórki
|
|
||||||
isolated->pMemCell = memorycell;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// utworzenie automatycznej komórki
|
// utworzenie automatycznej komórki
|
||||||
// TODO: determine suitable location for this one, create and add world reference node
|
// TODO: determine suitable location for this one, create and add world reference node
|
||||||
scene::node_data nodedata;
|
scene::node_data nodedata;
|
||||||
nodedata.name = isolated->asName;
|
nodedata.name = isolated->asName;
|
||||||
auto *memorycell = new TMemCell( nodedata ); // to nie musi mieć nazwy, nazwa w wyszukiwarce wystarczy
|
memorycell = new TMemCell( nodedata ); // to nie musi mieć nazwy, nazwa w wyszukiwarce wystarczy
|
||||||
// NOTE: autogenerated cells aren't exported; they'll be autogenerated anew when exported file is loaded
|
// NOTE: autogenerated cells aren't exported; they'll be autogenerated anew when exported file is loaded
|
||||||
memorycell->is_exportable = false;
|
memorycell->is_exportable = false;
|
||||||
simulation::Memory.insert( memorycell );
|
simulation::Memory.insert( memorycell );
|
||||||
isolated->pMemCell = memorycell; // wskaźnik komóki przekazany do odcinka izolowanego
|
|
||||||
}
|
}
|
||||||
|
// przypisanie powiązanej komórki
|
||||||
|
isolated->pMemCell = memorycell;
|
||||||
|
|
||||||
isolated = isolated->Next();
|
isolated = isolated->Next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
31
Track.h
31
Track.h
@@ -99,18 +99,32 @@ class TIsolated
|
|||||||
{ // obiekt zbierający zajętości z kilku odcinków
|
{ // obiekt zbierający zajętości z kilku odcinków
|
||||||
public:
|
public:
|
||||||
// constructors
|
// constructors
|
||||||
TIsolated();
|
|
||||||
TIsolated(const std::string &n, TIsolated *i);
|
TIsolated(const std::string &n, TIsolated *i);
|
||||||
// methods
|
// methods
|
||||||
static void DeleteAll();
|
static void DeleteAll();
|
||||||
static TIsolated * Find(const std::string &n); // znalezienie obiektu albo utworzenie nowego
|
static TIsolated * Find(const std::string &n); // znalezienie obiektu albo utworzenie nowego
|
||||||
|
bool AssignEvents();
|
||||||
void Modify(int i, TDynamicObject *o); // dodanie lub odjęcie osi
|
void Modify(int i, TDynamicObject *o); // dodanie lub odjęcie osi
|
||||||
bool Busy() {
|
inline
|
||||||
return (iAxles > 0); };
|
bool
|
||||||
static TIsolated * Root() {
|
Busy() {
|
||||||
return (pRoot); };
|
return (iAxles > 0); };
|
||||||
TIsolated * Next() {
|
inline
|
||||||
return (pNext); };
|
static TIsolated *
|
||||||
|
Root() {
|
||||||
|
return (pRoot); };
|
||||||
|
inline
|
||||||
|
TIsolated *
|
||||||
|
Next() {
|
||||||
|
return (pNext); };
|
||||||
|
inline
|
||||||
|
void
|
||||||
|
parent( TIsolated *Parent ) {
|
||||||
|
pParent = Parent; }
|
||||||
|
inline
|
||||||
|
TIsolated *
|
||||||
|
parent() const {
|
||||||
|
return pParent; }
|
||||||
// members
|
// members
|
||||||
std::string asName; // nazwa obiektu, baza do nazw eventów
|
std::string asName; // nazwa obiektu, baza do nazw eventów
|
||||||
TEvent *evBusy { nullptr }; // zdarzenie wyzwalane po zajęciu grupy
|
TEvent *evBusy { nullptr }; // zdarzenie wyzwalane po zajęciu grupy
|
||||||
@@ -120,6 +134,7 @@ private:
|
|||||||
// members
|
// members
|
||||||
int iAxles { 0 }; // ilość osi na odcinkach obsługiwanych przez obiekt
|
int iAxles { 0 }; // ilość osi na odcinkach obsługiwanych przez obiekt
|
||||||
TIsolated *pNext { nullptr }; // odcinki izolowane są trzymane w postaci listy jednikierunkowej
|
TIsolated *pNext { nullptr }; // odcinki izolowane są trzymane w postaci listy jednikierunkowej
|
||||||
|
TIsolated *pParent { nullptr }; // optional parent piece, collecting data from its children
|
||||||
static TIsolated *pRoot; // początek listy
|
static TIsolated *pRoot; // początek listy
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -140,6 +155,7 @@ private:
|
|||||||
// McZapkie-070402: dodalem zmienne opisujace rozmiary tekstur
|
// McZapkie-070402: dodalem zmienne opisujace rozmiary tekstur
|
||||||
int iTrapezoid = 0; // 0-standard, 1-przechyłka, 2-trapez, 3-oba
|
int iTrapezoid = 0; // 0-standard, 1-przechyłka, 2-trapez, 3-oba
|
||||||
double fRadiusTable[ 2 ] = { 0.0, 0.0 }; // dwa promienie, drugi dla zwrotnicy
|
double fRadiusTable[ 2 ] = { 0.0, 0.0 }; // dwa promienie, drugi dla zwrotnicy
|
||||||
|
float fVerticalRadius { 0.f }; // y-axis track radius (currently not supported)
|
||||||
float fTexLength = 4.0f; // długość powtarzania tekstury w metrach
|
float fTexLength = 4.0f; // długość powtarzania tekstury w metrach
|
||||||
float fTexRatio1 = 1.0f; // proporcja boków tekstury nawierzchni (żeby zaoszczędzić na rozmiarach tekstur...)
|
float fTexRatio1 = 1.0f; // proporcja boków tekstury nawierzchni (żeby zaoszczędzić na rozmiarach tekstur...)
|
||||||
float fTexRatio2 = 1.0f; // proporcja boków tekstury chodnika (żeby zaoszczędzić na rozmiarach tekstur...)
|
float fTexRatio2 = 1.0f; // proporcja boków tekstury chodnika (żeby zaoszczędzić na rozmiarach tekstur...)
|
||||||
@@ -265,7 +281,6 @@ public:
|
|||||||
if (pIsolated)
|
if (pIsolated)
|
||||||
pIsolated->Modify(i, o); }; // dodanie lub odjęcie osi
|
pIsolated->Modify(i, o); }; // dodanie lub odjęcie osi
|
||||||
std::string IsolatedName();
|
std::string IsolatedName();
|
||||||
bool IsolatedEventsAssign(TEvent *busy, TEvent *free);
|
|
||||||
double WidthTotal();
|
double WidthTotal();
|
||||||
bool IsGroupable();
|
bool IsGroupable();
|
||||||
int TestPoint( Math3D::vector3 *Point);
|
int TestPoint( Math3D::vector3 *Point);
|
||||||
|
|||||||
@@ -251,9 +251,10 @@ timetable_panel::update() {
|
|||||||
to_string( int( 100 + tableline->Dh ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Dm ) ).substr( 1, 2 ) :
|
to_string( int( 100 + tableline->Dh ) ).substr( 1, 2 ) + ":" + to_string( int( 100 + tableline->Dm ) ).substr( 1, 2 ) :
|
||||||
" | " );
|
" | " );
|
||||||
auto const candeparture = (
|
auto const candeparture = (
|
||||||
( owner->iStationStart < table->StationIndex )
|
( owner->iStationStart < table->StationIndex )
|
||||||
&& ( i < table->StationIndex )
|
&& ( i < table->StationIndex )
|
||||||
&& ( ( time.wHour * 60 + time.wMinute ) >= ( tableline->Dh * 60 + tableline->Dm ) ) );
|
&& ( ( tableline->Ah < 0 ) // pass-through, always valid
|
||||||
|
|| ( time.wHour * 60 + time.wMinute >= tableline->Dh * 60 + tableline->Dm ) ) );
|
||||||
auto traveltime =
|
auto traveltime =
|
||||||
" "
|
" "
|
||||||
+ ( i < 2 ? "" :
|
+ ( i < 2 ? "" :
|
||||||
@@ -726,7 +727,7 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
|
|||||||
textline =
|
textline =
|
||||||
"Acceleration:\n desired: " + to_string( mechanik.AccDesired, 2 )
|
"Acceleration:\n desired: " + to_string( mechanik.AccDesired, 2 )
|
||||||
+ ", corrected: " + to_string( mechanik.AccDesired * mechanik.BrakeAccFactor(), 2 )
|
+ ", corrected: " + to_string( mechanik.AccDesired * mechanik.BrakeAccFactor(), 2 )
|
||||||
+ "\n current: " + to_string( mechanik.AbsAccS_pub, 2 )
|
+ "\n current: " + to_string( mechanik.AbsAccS_pub + 0.001f, 2 )
|
||||||
+ ", slope: " + to_string( mechanik.fAccGravity + 0.001f, 2 ) + " (" + ( mechanik.fAccGravity > 0.01 ? "\\" : ( mechanik.fAccGravity < -0.01 ? "/" : "-" ) ) + ")"
|
+ ", slope: " + to_string( mechanik.fAccGravity + 0.001f, 2 ) + " (" + ( mechanik.fAccGravity > 0.01 ? "\\" : ( mechanik.fAccGravity < -0.01 ? "/" : "-" ) ) + ")"
|
||||||
+ "\n brake threshold: " + to_string( mechanik.fAccThreshold, 2 )
|
+ "\n brake threshold: " + to_string( mechanik.fAccThreshold, 2 )
|
||||||
+ ", delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 )
|
+ ", delays: " + to_string( mechanik.fBrake_a0[ 0 ], 2 )
|
||||||
@@ -744,7 +745,7 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
|
|||||||
std::vector<std::string> const drivingflagnames {
|
std::vector<std::string> const drivingflagnames {
|
||||||
"StopCloser", "StopPoint", "Active", "Press", "Connect", "Primary", "Late", "StopHere",
|
"StopCloser", "StopPoint", "Active", "Press", "Connect", "Primary", "Late", "StopHere",
|
||||||
"StartHorn", "StartHornNow", "StartHornDone", "Oerlikons", "IncSpeed", "TrackEnd", "SwitchFound", "GuardSignal",
|
"StartHorn", "StartHornNow", "StartHornDone", "Oerlikons", "IncSpeed", "TrackEnd", "SwitchFound", "GuardSignal",
|
||||||
"Visibility", "DoorOpened", "PushPull", "SemaphorFound", "SemaphorWasElapsed", "TrainInsideStation", "SpeedLimitFound" };
|
"Visibility", "DoorOpened", "PushPull", "SemaphorFound", "StopPointFound" /*"SemaphorWasElapsed", "TrainInsideStation", "SpeedLimitFound"*/ };
|
||||||
|
|
||||||
textline = "Driving flags:";
|
textline = "Driving flags:";
|
||||||
for( int idx = 0, flagbit = 1; idx < drivingflagnames.size(); ++idx, flagbit <<= 1 ) {
|
for( int idx = 0, flagbit = 1; idx < drivingflagnames.size(); ++idx, flagbit <<= 1 ) {
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
|
|||||||
textline += ", ";
|
textline += ", ";
|
||||||
}
|
}
|
||||||
textline += (
|
textline += (
|
||||||
event.second ?
|
event.second != nullptr ?
|
||||||
event.second->asName :
|
event.second->asName :
|
||||||
event.first + " (missing)" );
|
event.first + " (missing)" );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ std::string cParser::readToken( bool ToLower, const char *Break ) {
|
|||||||
// update line counter
|
// update line counter
|
||||||
++mLine;
|
++mLine;
|
||||||
}
|
}
|
||||||
} while( token == "" && mStream->peek() != EOF ); // double check to deal with trailing spaces
|
} while( token == "" && mStream->peek() != EOF ); // double check in case of consecutive separators
|
||||||
}
|
}
|
||||||
|
|
||||||
if( false == parameters.empty() ) {
|
if( false == parameters.empty() ) {
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ state_serializer::deserialize( cParser &Input, scene::scratch_data &Scratchpad )
|
|||||||
std::pair<
|
std::pair<
|
||||||
std::string,
|
std::string,
|
||||||
deserializefunction> > functionlist = {
|
deserializefunction> > functionlist = {
|
||||||
|
{ "area", &state_serializer::deserialize_area },
|
||||||
{ "atmo", &state_serializer::deserialize_atmo },
|
{ "atmo", &state_serializer::deserialize_atmo },
|
||||||
{ "camera", &state_serializer::deserialize_camera },
|
{ "camera", &state_serializer::deserialize_camera },
|
||||||
{ "config", &state_serializer::deserialize_config },
|
{ "config", &state_serializer::deserialize_config },
|
||||||
@@ -125,6 +126,20 @@ state_serializer::deserialize( cParser &Input, scene::scratch_data &Scratchpad )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
state_serializer::deserialize_area( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
// first parameter specifies name of parent piece...
|
||||||
|
auto token { Input.getToken<std::string>() };
|
||||||
|
auto *groupowner { TIsolated::Find( token ) };
|
||||||
|
// ...followed by list of its children
|
||||||
|
while( ( false == ( token = Input.getToken<std::string>() ).empty() )
|
||||||
|
&& ( token != "endarea" ) ) {
|
||||||
|
// bind the children with their parent
|
||||||
|
auto *isolated { TIsolated::Find( token ) };
|
||||||
|
isolated->parent( groupowner );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_serializer::deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad ) {
|
state_serializer::deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad ) {
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ private:
|
|||||||
// methods
|
// methods
|
||||||
// restores class data from provided stream
|
// restores class data from provided stream
|
||||||
void deserialize( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
|
void deserialize_area( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_atmo( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_camera( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_camera( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_config( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_config( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
|
|||||||
Reference in New Issue
Block a user