mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
Add new speed limitations types
SetVelocity - semaphor RoadVelocity - track speed limit SectionVelocity - track speed limit for some distance
This commit is contained in:
@@ -48,9 +48,11 @@ typedef enum
|
||||
{ // binarne odpowiedniki komend w komórce pamiêci
|
||||
cm_Unknown, // ci¹g nierozpoznany (nie jest komend¹)
|
||||
cm_Ready, // W4 zezwala na odjazd, ale semafor mo¿e zatrzymaæ
|
||||
cm_SetVelocity,
|
||||
cm_ShuntVelocity,
|
||||
cm_SetProximityVelocity,
|
||||
cm_SetVelocity, // prêdkoœæ poci¹gowa zadawana na semaforze
|
||||
cm_RoadVelocity, // prêdkoœæ drogowa
|
||||
cm_SectionVelocity, //ograniczenie prêdkoœci na odcinku
|
||||
cm_ShuntVelocity, // prêdkoœæ manewrowa na semaforze
|
||||
cm_SetProximityVelocity, // informacja wstêpna o ograniczeniu
|
||||
cm_ChangeDirection,
|
||||
cm_PassengerStopPoint,
|
||||
cm_OutsideStation,
|
||||
|
||||
106
Driver.cpp
106
Driver.cpp
@@ -122,46 +122,61 @@ void TSpeedPos::CommandCheck()
|
||||
TCommandType command = evEvent->Command();
|
||||
double value1 = evEvent->ValueGet(1);
|
||||
double value2 = evEvent->ValueGet(2);
|
||||
if (command == cm_ShuntVelocity)
|
||||
{ // prędkość manewrową zapisać, najwyżej AI zignoruje przy analizie tabelki
|
||||
switch (command)
|
||||
{
|
||||
case cm_ShuntVelocity:
|
||||
// prędkość manewrową zapisać, najwyżej AI zignoruje przy analizie tabelki
|
||||
fVelNext = value1; // powinno być value2, bo druga określa "za"?
|
||||
iFlags |= 0x200;
|
||||
}
|
||||
else if (command == cm_SetVelocity)
|
||||
{ // w semaforze typu "m" jest ShuntVelocity dla Ms2 i SetVelocity dla S1
|
||||
iFlags |= spShuntSemaphor;
|
||||
break;
|
||||
case cm_SetVelocity:
|
||||
// w semaforze typu "m" jest ShuntVelocity dla Ms2 i SetVelocity dla S1
|
||||
// SetVelocity * 0 -> można jechać, ale stanąć przed
|
||||
// SetVelocity 0 20 -> stanąć przed, potem można jechać 20 (SBL)
|
||||
// SetVelocity -1 100 -> można jechać, przy następnym ograniczenie (SBL)
|
||||
// SetVelocity 40 -1 -> PutValues: jechać 40 aż do minięcia (koniec ograniczenia(
|
||||
fVelNext = value1;
|
||||
iFlags &= ~0xE00; // nie manewrowa, nie przystanek, nie zatrzymać na SBL
|
||||
iFlags &= ~(spShuntSemaphor | spPassengerStopPoint | spStopOnSBL);
|
||||
iFlags |= spSemaphor;// nie manewrowa, nie przystanek, nie zatrzymać na SBL, ale semafor
|
||||
if (value1 == 0.0) // jeśli pierwsza zerowa
|
||||
if (value2 != 0.0) // a druga nie
|
||||
{ // S1 na SBL, można przejechać po zatrzymaniu (tu nie mamy prędkości ani odległości)
|
||||
fVelNext = value2; // normalnie będzie zezwolenie na jazdę, aby się usunął z tabelki
|
||||
iFlags |= 0x800; // flaga, że ma zatrzymać; na pewno nie zezwoli na manewry
|
||||
iFlags |= spStopOnSBL; // flaga, że ma zatrzymać; na pewno nie zezwoli na manewry
|
||||
}
|
||||
}
|
||||
else if (command == cm_PassengerStopPoint) // nie ma dostępu do rozkładu
|
||||
{ // przystanek, najwyżej AI zignoruje przy analizie tabelki
|
||||
if ((iFlags & 0x400) == 0)
|
||||
break;
|
||||
case cm_SectionVelocity:
|
||||
// odcinek z ograniczeniem prędkości
|
||||
fVelNext = value1;
|
||||
iFlags |= spSectionVel;
|
||||
break;
|
||||
case cm_RoadVelocity:
|
||||
// prędkość drogowa (od tej pory będzie jako domyślna najwyższa
|
||||
fVelNext = value1;
|
||||
iFlags |= spRoadVel;
|
||||
break;
|
||||
case cm_PassengerStopPoint:
|
||||
// nie ma dostępu do rozkładu
|
||||
// przystanek, najwyżej AI zignoruje przy analizie tabelki
|
||||
if ((iFlags & spPassengerStopPoint) == 0)
|
||||
fVelNext = 0.0; // TrainParams->IsStop()?0.0:-1.0; //na razie tak
|
||||
iFlags |= 0x400; // niestety nie da się w tym miejscu współpracować z rozkładem
|
||||
}
|
||||
else if (command == cm_SetProximityVelocity)
|
||||
{ // ignorować
|
||||
iFlags |= spPassengerStopPoint; // niestety nie da się w tym miejscu współpracować z rozkładem
|
||||
break;
|
||||
case cm_SetProximityVelocity:
|
||||
// ignorować
|
||||
fVelNext = -1;
|
||||
}
|
||||
else if (command == cm_OutsideStation)
|
||||
{ // w trybie manewrowym: skanować od niej wstecz i stanąć po wyjechaniu za sygnalizator i
|
||||
break;
|
||||
case cm_OutsideStation:
|
||||
// w trybie manewrowym: skanować od niej wstecz i stanąć po wyjechaniu za sygnalizator i
|
||||
// zmienić kierunek
|
||||
// w trybie pociągowym: można przyspieszyć do wskazanej prędkości (po zjechaniu z rozjazdów)
|
||||
fVelNext = -1;
|
||||
iFlags |= 0x2100; // W5
|
||||
}
|
||||
else
|
||||
{ // inna komenda w evencie skanowanym powoduje zatrzymanie i wysłanie tej komendy
|
||||
iFlags &= ~0xE00; // nie manewrowa, nie przystanek, nie zatrzymać na SBL
|
||||
iFlags |= spOutsideStation; // W5
|
||||
break;
|
||||
default:
|
||||
// inna komenda w evencie skanowanym powoduje zatrzymanie i wysłanie tej komendy
|
||||
iFlags &= ~(spShuntSemaphor | spPassengerStopPoint |
|
||||
spStopOnSBL); // nie manewrowa, nie przystanek, nie zatrzymać na SBL
|
||||
fVelNext = 0; // jak nieznana komenda w komórce sygnałowej, to ma stać
|
||||
}
|
||||
};
|
||||
@@ -180,17 +195,17 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len)
|
||||
if (iska < 0.0) // iloczyn skalarny jest ujemny, gdy punkt jest z tyłu
|
||||
{ // jeśli coś jest z tyłu, to dokładna odległość nie ma już większego znaczenia
|
||||
fDist = -fDist; // potrzebne do badania wyjechania składem poza ograniczenie
|
||||
if (iFlags & 32) // 32 ustawione, gdy obiekt już został minięty
|
||||
if (iFlags & spElapsed) // 32 ustawione, gdy obiekt już został minięty
|
||||
{ // jeśli minięty (musi być minięty również przez końcówkę składu)
|
||||
}
|
||||
else
|
||||
{
|
||||
iFlags ^= 32; // 32-minięty - będziemy liczyć odległość względem przeciwnego końca
|
||||
iFlags ^= spElapsed; // 32-minięty - będziemy liczyć odległość względem przeciwnego końca
|
||||
// toru (nadal może być z przodu i ogdaniczać)
|
||||
if ((iFlags & 0x43) == 3) // tylko jeśli (istotny) tor, bo eventy są punktowe
|
||||
if (trTrack) // może być NULL, jeśli koniec toru (????)
|
||||
vPos =
|
||||
(iFlags & 4) ?
|
||||
(iFlags & spReverse) ?
|
||||
trTrack->CurrentSegment()->FastGetPoint_0() :
|
||||
trTrack->CurrentSegment()->FastGetPoint_1(); // drugi koniec istotny
|
||||
}
|
||||
@@ -201,14 +216,14 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len)
|
||||
// dokładniejsze wartości
|
||||
}
|
||||
if (fDist > 0.0) // nie może być 0.0, a przypadkiem mogło by się trafić i było by źle
|
||||
if ((iFlags & 32) == 0) // 32 ustawione, gdy obiekt już został minięty
|
||||
if ((iFlags & spElapsed) == 0) // 32 ustawione, gdy obiekt już został minięty
|
||||
{ // jeśli obiekt nie został minięty, można od niego zliczać narastająco (inaczej może być
|
||||
// problem z wektorem kierunku)
|
||||
len = fDist = len + fDist; // zliczanie dlugości narastająco
|
||||
*p = vPos; // nowy punkt odniesienia
|
||||
*dir = Normalize(v); // nowy wektor kierunku od poprzedniego obiektu do aktualnego
|
||||
}
|
||||
if (iFlags & 2) // jeśli tor
|
||||
if (iFlags & spTrack) // jeśli tor
|
||||
{
|
||||
if (trTrack) // może być NULL, jeśli koniec toru (???)
|
||||
{
|
||||
@@ -221,25 +236,25 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len)
|
||||
// głównej drogi - chyba że jest równorzędne...
|
||||
fVelNext = 30.0; // uzależnić prędkość od promienia; albo niech będzie
|
||||
// ograniczona w skrzyżowaniu (velocity z ujemną wartością)
|
||||
if ((iFlags & 32) == 0) // jeśli nie wjechał
|
||||
if ((iFlags & spElapsed) == 0) // jeśli nie wjechał
|
||||
if (trTrack->iNumDynamics > 0) // a skrzyżowanie zawiera pojazd
|
||||
fVelNext =
|
||||
0.0; // to zabronić wjazdu (chyba że ten z przodu też jedzie prosto)
|
||||
}
|
||||
if (iFlags & 8) // jeśli odcinek zmienny
|
||||
if (iFlags & spSwitch) // jeśli odcinek zmienny
|
||||
{
|
||||
if (bool(trTrack->GetSwitchState() & 1) !=
|
||||
bool(iFlags & 16)) // czy stan się zmienił?
|
||||
bool(iFlags & spSwitchStatus)) // czy stan się zmienił?
|
||||
{ // Ra: zakładam, że są tylko 2 możliwe stany
|
||||
iFlags ^= 16;
|
||||
iFlags ^= spSwitchStatus;
|
||||
// fVelNext=trTrack->VelocityGet(); //nowa prędkość
|
||||
if ((iFlags & 32) == 0)
|
||||
if ((iFlags & spElapsed) == 0)
|
||||
return true; // jeszcze trzeba skanowanie wykonać od tego toru
|
||||
// problem jest chyba, jeśli zwrotnica się przełoży zaraz po zjechaniu z niej
|
||||
// na Mydelniczce potrafi skanować na wprost mimo pojechania na bok
|
||||
}
|
||||
// poniższe nie dotyczy trybu łączenia?
|
||||
if ((iFlags & 32) ? false :
|
||||
if ((iFlags & spElapsed) ? false :
|
||||
trTrack->iNumDynamics >
|
||||
0) // jeśli jeszcze nie wjechano na tor, a coś na nim jest
|
||||
fDist -= 30.0, fVelNext = 0.0; // to niech stanie w zwiększonej odległości
|
||||
@@ -248,7 +263,7 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (iFlags & 0x100) // jeśli event
|
||||
else if (iFlags & spEvent) // jeśli event
|
||||
{ // odczyt komórki pamięci najlepiej by było zrobić jako notyfikację, czyli zmiana komórki
|
||||
// wywoła jakąś podaną funkcję
|
||||
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
|
||||
@@ -258,12 +273,12 @@ bool TSpeedPos::Update(vector3 *p, vector3 *dir, double &len)
|
||||
|
||||
AnsiString TSpeedPos::TableText()
|
||||
{ // pozycja tabelki prędkości
|
||||
if (iFlags & 0x1)
|
||||
if (iFlags & spEnabled)
|
||||
{ // o ile pozycja istotna
|
||||
if (iFlags & 0x2) // jeśli tor
|
||||
if (iFlags & spTrack) // jeśli tor
|
||||
return "Flags=#" + IntToHex(iFlags, 8) + ", Dist=" + FloatToStrF(fDist, ffFixed, 7, 1) +
|
||||
", Vel=" + AnsiString(fVelNext) + ", Track=" + trTrack->NameGet();
|
||||
else if (iFlags & 0x100) // jeśli event
|
||||
else if (iFlags & spEvent) // jeśli event
|
||||
return "Flags=#" + IntToHex(iFlags, 8) + ", Dist=" + FloatToStrF(fDist, ffFixed, 7, 1) +
|
||||
", Vel=" + AnsiString(fVelNext) + ", Event=" + evEvent->asName;
|
||||
}
|
||||
@@ -273,7 +288,7 @@ AnsiString TSpeedPos::TableText()
|
||||
bool TSpeedPos::Set(TEvent *e, double d)
|
||||
{ // zapamiętanie zdarzenia
|
||||
fDist = d;
|
||||
iFlags = 0x101; // event+istotny
|
||||
iFlags = spEnabled | spEvent; // event+istotny
|
||||
evEvent = e;
|
||||
vPos = e->PositionGet(); // współrzędne eventu albo komórki pamięci (zrzutować na tor?)
|
||||
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
|
||||
@@ -287,17 +302,17 @@ void TSpeedPos::Set(TTrack *t, double d, int f)
|
||||
if (trTrack)
|
||||
{
|
||||
iFlags = f | (trTrack->eType == tt_Normal ? 2 : 10); // zapamiętanie kierunku wraz z typem
|
||||
if (iFlags & 8)
|
||||
if (iFlags & spSwitch)
|
||||
if (trTrack->GetSwitchState() & 1)
|
||||
iFlags |= 16;
|
||||
iFlags |= spSwitchStatus;
|
||||
fVelNext = trTrack->VelocityGet();
|
||||
if (trTrack->iDamageFlag & 128)
|
||||
fVelNext = 0.0; // jeśli uszkodzony, to też stój
|
||||
if (iFlags & 64)
|
||||
if (iFlags & spEnd)
|
||||
fVelNext = (trTrack->iCategoryFlag & 1) ?
|
||||
0.0 :
|
||||
20.0; // jeśli koniec, to pociąg stój, a samochód zwolnij
|
||||
vPos = (bool(iFlags & 4) != bool(iFlags & 64)) ?
|
||||
vPos = (bool(iFlags & spReverse) != bool(iFlags & spEnd)) ?
|
||||
trTrack->CurrentSegment()->FastGetPoint_1() :
|
||||
trTrack->CurrentSegment()->FastGetPoint_0();
|
||||
}
|
||||
@@ -344,7 +359,8 @@ 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 & 0x101) == 0x101) // o ile używana pozycja
|
||||
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
|
||||
return true; // nie ma, czyli można dodać
|
||||
|
||||
26
Driver.h
26
Driver.h
@@ -92,17 +92,39 @@ enum TAction
|
||||
actTrial // próba hamulca (na postoju)
|
||||
};
|
||||
|
||||
enum TSpeedPosFlag
|
||||
{ // wartości dla iFlag w TSpeedPos
|
||||
spEnabled = 0x1, // pozycja brana pod uwagę
|
||||
spTrack = 0x2, // to jest tor
|
||||
spReverse = 0x4, // odwrotnie
|
||||
spSwitch = 0x8, // to zwrotnica
|
||||
spSwitchStatus = 0x10, // stan zwrotnicy
|
||||
spElapsed = 0x20, // pozycja minięta przez pojazd
|
||||
spEnd = 0x40, // koniec
|
||||
spCurve = 0x80, // łuk
|
||||
spEvent = 0x100, // event
|
||||
spShuntSemaphor = 0x200, // tarcza manewrowa
|
||||
spPassengerStopPoint = 0x400, // przystanek osobowy (wskaźnik W4)
|
||||
spStopOnSBL = 0x800, // zatrzymanie na SBL
|
||||
spCommandSent = 0x1000, // komenda wysłana
|
||||
spOutsideStation = 0x2000, // wskaźnik końca manewrów
|
||||
spSemaphor = 0x4000, // semafor pociągowy
|
||||
spRoadVel = 0x8000, // zadanie prędkości drogowej
|
||||
spSectionVel = 0x20000, // odcinek z ograniczeniem
|
||||
spEndOfTable = 0x10000 // zatkanie tabelki
|
||||
};
|
||||
|
||||
class TSpeedPos
|
||||
{ // pozycja tabeli prędkości dla AI
|
||||
public:
|
||||
double fDist; // aktualna odległość (ujemna gdy minięte)
|
||||
double fVelNext; // prędkość obowiązująca od tego miejsca
|
||||
// double fAcc;
|
||||
int iFlags;
|
||||
int iFlags; //flagi typu wpisu do tabelki
|
||||
// 1=istotny,2=tor,4=odwrotnie,8-zwrotnica (może się zmienić),16-stan
|
||||
// zwrotnicy,32-minięty,64=koniec,128=łuk
|
||||
// 0x100=event,0x200=manewrowa,0x400=przystanek,0x800=SBL,0x1000=wysłana komenda,0x2000=W5
|
||||
// 0x10000=zatkanie
|
||||
// 0x4000=semafor,0x10000=zatkanie
|
||||
vector3 vPos; // współrzędne XYZ do liczenia odległości
|
||||
struct
|
||||
{
|
||||
|
||||
10
Event.cpp
10
Event.cpp
@@ -338,6 +338,16 @@ void TEvent::Load(cParser *parser, vector3 *org)
|
||||
bEnabled = false;
|
||||
Params[6].asCommand = cm_SetVelocity;
|
||||
}
|
||||
else if (str == "RoadVelocity")
|
||||
{
|
||||
bEnabled = false;
|
||||
Params[6].asCommand = cm_RoadVelocity;
|
||||
}
|
||||
else if (str == "SectionVelocity")
|
||||
{
|
||||
bEnabled = false;
|
||||
Params[6].asCommand = cm_SectionVelocity;
|
||||
}
|
||||
else if (str == "ShuntVelocity")
|
||||
{
|
||||
bEnabled = false;
|
||||
|
||||
Reference in New Issue
Block a user