diff --git a/Driver.cpp b/Driver.cpp index 099e3054..557819e8 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -179,7 +179,8 @@ void TSpeedPos::CommandCheck() // inna komenda w evencie skanowanym powoduje zatrzymanie i wysłanie tej komendy iFlags &= ~(spShuntSemaphor | spPassengerStopPoint | spStopOnSBL); // nie manewrowa, nie przystanek, nie zatrzymać na SBL - fVelNext = 0; // jak nieznana komenda w komórce sygnałowej, to ma stać + fVelNext = -1.0; // jak nieznana komenda w komórce sygnałowej, to pokazujemy w tabelce ale + // ignorujemy } }; @@ -359,12 +360,15 @@ bool TController::TableAddNew() bool TController::TableNotFound(TEvent *e) { // sprawdzenie, czy nie został już dodany do tabelki (np. podwójne W4 robi problemy) - int i, j = (iLast + 1) % iSpeedTableSize; // j, aby sprawdzić też ostatnią pozycję - for (i = iFirst; i != j; i = (i + 1) % iSpeedTableSize) - if ((sSpeedTable[i].iFlags & (spEnabled | spEvent)) == spEnabled | - spEvent) // o ile używana pozycja - if (sSpeedTable[i].evEvent == e) - return false; // już jest, drugi raz dodawać nie ma po co + int j = (iLast + 1) % iSpeedTableSize; // j, aby sprawdzić też ostatnią pozycję + for (int i = iFirst; i != j; i = (i + 1) % iSpeedTableSize) + if ((sSpeedTable[i].iFlags & (spEnabled | spEvent)) == (spEnabled | + spEvent)) // o ile używana pozycja + if (sSpeedTable[i].evEvent == e) + { + WriteLog("TableNotFound: Event already in SpeedTable: " + sSpeedTable[i].evEvent->asName); + return false; // już jest, drugi raz dodawać nie ma po co + } return true; // nie ma, czyli można dodać }; @@ -399,7 +403,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) } else { // kontynuacja skanowania od ostatnio sprawdzonego toru (w ostatniej pozycji zawsze jest tor) - if (sSpeedTable[iLast].iFlags & 0x10000) // zatkanie + if (sSpeedTable[iLast].iFlags & spEndOfTable) // zatkanie { // jeśli zapełniła się tabelka if ((iLast + 1) % iSpeedTableSize == iFirst) // jeśli nadal jest zapełniona return; // nic się nie da zrobić @@ -415,7 +419,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle) pTrack = sSpeedTable[iLast].trTrack; // ostatnio sprawdzony tor if (!pTrack) return; // koniec toru, to nie ma co sprawdzać (nie ma prawa tak być) - fLastDir = sSpeedTable[iLast].iFlags & 4 ? + fLastDir = sSpeedTable[iLast].iFlags & spReverse ? -1.0 : 1.0; // flaga ustawiona, gdy Point2 toru jest bliżej fCurrentDistance = sSpeedTable[iLast].fDist; // aktualna odległość do jego Point1 @@ -584,27 +588,40 @@ void TController::TableCheck(double fDistance) double len = 0.0; // odległość będziemy zliczać narastająco for (int i = iFirst; i != iLast; i = (i + 1) % iSpeedTableSize) { // aktualizacja rekordów z wyjątkiem ostatniego - if (sSpeedTable[i].iFlags & 1) // jeśli pozycja istotna + if (sSpeedTable[i].iFlags & spEnabled) // jeśli pozycja istotna { if (sSpeedTable[i].Update(&pos, &dir, len)) { - iLast = i; // wykryta zmiana zwrotnicy - konieczne ponowne przeskanowanie - // dalszej części - break; // nie kontynuujemy pętli, trzeba doskanować ciąg dalszy + int k = (iLast + 1) % iSpeedTableSize; // skanujemy razem z ostatnią pozycją + for (int j = (i+1) % iSpeedTableSize; j != k; j = (j + 1) % iSpeedTableSize) + { // kasowanie wszystkich rekordów za zmienioną zwrotnicą + //if (sSpeedTable[j].iFlags & spTrack) + // WriteLog("TableCheck: Switch change. Delete from table: " + sSpeedTable[j].trTrack->NameGet()); + //else if (sSpeedTable[j].iFlags & spEvent) + // WriteLog("TableCheck: Switch change. Delete from table: " + sSpeedTable[j].evEvent->asName); + sSpeedTable[j].iFlags = 0; + } + TablePurger(); + iLast = i; // pokazujemy gdzie jest ostatni kawałek + break; // nie kontynuujemy pętli, trzeba doskanować ciąg dalszy } - if (sSpeedTable[i].iFlags & 2) // jeśli odcinek + if (sSpeedTable[i].iFlags & spTrack) // jeśli odcinek { if (sSpeedTable[i].fDist < -fLength) // a skład wyjechał całą długością poza { // degradacja pozycji - sSpeedTable[i].iFlags &= ~1; // nie liczy się + // WriteLog( "TableCheck: Track is behind. Delete from table: " + sSpeedTable[i].trTrack->NameGet()); + sSpeedTable[i].iFlags &= ~spEnabled; // nie liczy się } else if ((sSpeedTable[i].iFlags & 0xF0000028) == - 0x20) // jest z tyłu (najechany) i nie jest zwrotnicą ani skrzyżowaniem - if (sSpeedTable[i].fVelNext < 0) // a nie ma ograniczenia prędkości - sSpeedTable[i].iFlags = - 0; // to nie ma go po co trzymać (odtykacz usunie ze środka) + spElapsed) // jest z tyłu (najechany) i nie jest zwrotnicą ani skrzyżowaniem + if (sSpeedTable[i].fVelNext < 0) // a nie ma ograniczenia prędkości + { + sSpeedTable[i].iFlags = + 0; // to nie ma go po co trzymać (odtykacz usunie ze środka) + // WriteLog("TableCheck: Track without speed limit is under train . Delete from table: " + sSpeedTable[i].trTrack->NameGet()); + } } - else if (sSpeedTable[i].iFlags & 0x100) // jeśli event + else if (sSpeedTable[i].iFlags & spEvent) // jeśli event { if (sSpeedTable[i].fDist < (sSpeedTable[i].evEvent->Type == tp_PutValues ? -fLength : @@ -613,9 +630,10 @@ void TController::TableCheck(double fDistance) sSpeedTable[i].fDist < -fLength) { // pociąg staje zawsze, a samochód tylko jeśli nie przejedzie całą // długością (może być zaskoczony zmianą) - sSpeedTable[i].iFlags &= ~1; // degradacja pozycji dla samochodu; + // WriteLog("TableCheck: Event is behind. Delete from table: " + sSpeedTable[i].evEvent->asName); + sSpeedTable[i].iFlags &= ~1; // degradacja pozycji dla samochodu; // semafory usuwane tylko przy sprawdzaniu, - // bo wysyłają komendy + // bo wysyłają komendy } } // if (sSpeedTable[i].fDist<-20.0*fLength) //jeśli to coś jest 20 razy dalej niż @@ -1112,7 +1130,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN else // event trzyma tylko jeśli VelNext=0, nawet po przejechaniu (nie powinno // dotyczyć samochodów?) a = (v == 0.0 ? -1.0 : fAcc); // ruszanie albo hamowanie - if (a < fAcc) + if (a < fAcc && v == Min0R(v, fNext)) { // mniejsze przyspieszenie to mniejsza możliwość rozpędzenia się albo konieczność // hamowania // jeśli droga wolna, to może być a>1.0 i się tu nie załapuje @@ -1143,12 +1161,13 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN if (VelSignalLast >= 0.0 && !(iDrivigFlags & (moveSemaphorFound | moveSwitchFound)) && (OrderCurrentGet() & Obey_train)) VelSignalLast = -1.0; // jeśli mieliśmy ograniczenie z semafora i nie ma przed nami - if (fVelDes > VelSignalLast) //analiza spisanych z tabelki ograniczeń i nadpisanie aktualnego - fVelDes = VelSignalLast; - if (fVelDes > VelLimitLast) - fVelDes = VelLimitLast; - if (fVelDes > VelRoad) - fVelDes = VelRoad; + + if (VelSignalLast >= 0.0) //analiza spisanych z tabelki ograniczeń i nadpisanie aktualnego + fVelDes = Min0R(fVelDes, VelSignalLast); + if (VelLimitLast >= 0.0) + fVelDes = Min0R(fVelDes, VelLimitLast); + if (VelRoad >= 0.0) + fVelDes = Min0R(fVelDes, VelRoad); // nastepnego semafora albo zwrotnicy to uznajemy, że mijamy W5 return go; }; @@ -1161,14 +1180,14 @@ void TController::TablePurger() k += iSpeedTableSize; // ilość pozycji do przeanalizowania for (i = iFirst; k > 0; --k, i = (i + 1) % iSpeedTableSize) { // sprawdzenie rekordów od (iFirst) do (iLast), o ile są istotne - if ((sSpeedTable[i].iFlags & 1) ? + if ((sSpeedTable[i].iFlags & spEnabled) ? (sSpeedTable[i].fVelNext < 0) && ((sSpeedTable[i].iFlags & 0xAB) == 0xA3) : true) { // jeśli jest to minięty (0x20) tor (0x03) do liczenia cięciw (0x80), a nie zwrotnica // (0x08) - for (; k > 0; --k, i = (i + 1) % iSpeedTableSize) - sSpeedTable[i] = sSpeedTable[(i + 1) % iSpeedTableSize]; // skopiowanie - // WriteLog("Odtykacz usuwa pozycję"); + for (; k > 0; --k, i = (i + 1) % iSpeedTableSize) + sSpeedTable[i] = sSpeedTable[(i + 1) % iSpeedTableSize]; // skopiowanie + //WriteLog("Odtykacz usuwa pozycję"); iLast = (iLast - 1 + iSpeedTableSize) % iSpeedTableSize; // cofnięcie z zawinięciem return; } @@ -3258,7 +3277,7 @@ bool TController::UpdateSituation(double dt) // double scanmax=(mvOccupied->Vel>0.0)?3*fDriverDist+fBrakeDist:10.0*fDriverDist; double scanmax = (mvOccupied->Vel > 5.0) ? 400 + fBrakeDist : - 50.0 * fDriverDist; // 1000m dla stojących pociągów; Ra 2015-01: przy + 30.0 * fDriverDist; // 1500m dla stojących pociągów; 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). // 3. Sprawdzić, czy trajektoria ruchu przechodzi przez zwrotnice - jeśli tak, to sprawdzić, @@ -3779,7 +3798,7 @@ bool TController::UpdateSituation(double dt) if (VelNext == 0.0) break; // ale jak coś z przodu zamyka, to ma stać if (iDrivigFlags & moveStopCloser) - VelSignal = VelDesired; // niech jedzie, jak W4 puściło - nie, ma czekać na + VelSignal = -1.0; // niech jedzie, jak W4 puściło - nie, ma czekać na // sygnał z sygnalizatora! case cm_SetVelocity: // od wersji 357 semafor nie budzi wyłączonej lokomotywy if (!(OrderList[OrderPos] & diff --git a/Globals.cpp b/Globals.cpp index 005e3768..3ff2842f 100644 --- a/Globals.cpp +++ b/Globals.cpp @@ -49,9 +49,9 @@ double Global::fLuminance = 1.0; // jasno int Global::iReCompile = 0; // zwiększany, gdy trzeba odświeżyć siatki HWND Global::hWnd = NULL; // uchwyt okna int Global::iCameraLast = -1; -AnsiString Global::asRelease = "15.3.1169.472"; +AnsiString Global::asRelease = "15.4.1170.473"; AnsiString Global::asVersion = - "Compilation 2015-04-14, release " + Global::asRelease + "."; // tutaj, bo wysyłany + "Compilation 2015-11-06, release " + Global::asRelease + "."; // tutaj, bo wysyłany int Global::iViewMode = 0; // co aktualnie widać: 0-kabina, 1-latanie, 2-sprzęgi, 3-dokumenty int Global::iTextMode = 0; // tryb pracy wyświetlacza tekstowego int Global::iScreenMode[12] = {0, 0, 0, 0, 0, 0,