mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 01:59:19 +02:00
merge with tmj
This commit is contained in:
@@ -123,12 +123,13 @@ TButton::Turn( bool const State ) {
|
||||
}
|
||||
}
|
||||
|
||||
void TButton::Update() {
|
||||
void TButton::Update( bool const Power ) {
|
||||
|
||||
if( ( bData != nullptr )
|
||||
&& ( *bData != m_state ) ) {
|
||||
auto const state { Power && ( bData ? *bData : m_state ) };
|
||||
|
||||
m_state = ( *bData );
|
||||
if( state != m_state ) {
|
||||
|
||||
m_state = state;
|
||||
play();
|
||||
}
|
||||
|
||||
|
||||
2
Button.h
2
Button.h
@@ -30,7 +30,7 @@ public:
|
||||
bool Active() {
|
||||
return ( ( pModelOn != nullptr )
|
||||
|| ( pModelOff != nullptr ) ); }
|
||||
void Update();
|
||||
void Update( bool const Power = true );
|
||||
bool Init( std::string const &asName, TModel3d const *pModel, bool bNewOn = false );
|
||||
void Load( cParser &Parser, TDynamicObject const *Owner );
|
||||
void AssignBool(bool const *bValue);
|
||||
|
||||
446
Driver.cpp
446
Driver.cpp
@@ -372,14 +372,13 @@ bool TSpeedPos::Set(basic_event *event, double dist, double length, TOrders orde
|
||||
iFlags = spEvent;
|
||||
evEvent = event;
|
||||
vPos = event->input_location(); // współrzędne eventu albo komórki pamięci (zrzutować na tor?)
|
||||
if( dist + length >= 0 ) {
|
||||
iFlags |= spEnabled;
|
||||
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
|
||||
}
|
||||
else {
|
||||
// located behind the tracking consist, don't bother with it
|
||||
// ignore events located behind the consist, but with exception of stop points which may be needed to update freshly received timetable
|
||||
if( ( dist + length < 0 )
|
||||
&& ( event->input_command() != TCommandType::cm_PassengerStopPoint ) ) {
|
||||
return false;
|
||||
}
|
||||
iFlags |= spEnabled;
|
||||
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości
|
||||
// zależnie od trybu sprawdzenie czy jest tutaj gdzieś semafor lub tarcza manewrowa
|
||||
// jeśli wskazuje stop wtedy wystawiamy true jako koniec sprawdzania
|
||||
// WriteLog("EventSet: Vel=" + AnsiString(fVelNext) + " iFlags=" + AnsiString(iFlags) + " order="+AnsiString(order));
|
||||
@@ -486,6 +485,20 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
||||
|
||||
if (iTableDirection != iDirection ) {
|
||||
// jeśli zmiana kierunku, zaczynamy od toru ze wskazanym pojazdem
|
||||
TableClear();
|
||||
/*
|
||||
// aktualna prędkość // changed to -1 to recognize speed limit, if any
|
||||
fLastVel = -1.0;
|
||||
sSpeedTable.clear();
|
||||
iLast = -1;
|
||||
tLast = nullptr; //żaden nie sprawdzony
|
||||
SemNextIndex = -1;
|
||||
SemNextStopIndex = -1;
|
||||
*/
|
||||
if( VelSignalLast == 0.0 ) {
|
||||
// don't allow potential red light overrun keep us from reversing
|
||||
VelSignalLast = -1.0;
|
||||
}
|
||||
iTableDirection = iDirection; // ustalenie w jakim kierunku jest wypełniana tabelka względem pojazdu
|
||||
pTrack = pVehicle->RaTrackGet(); // odcinek, na którym stoi
|
||||
fTrackLength = pVehicle->RaTranslationGet(); // pozycja na tym torze (odległość od Point1)
|
||||
@@ -503,17 +516,6 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
||||
.Length();
|
||||
// aktualna odległość ma być ujemna gdyż jesteśmy na końcu składu
|
||||
fCurrentDistance = -fLength - fTrackLength;
|
||||
// aktualna prędkość // changed to -1 to recognize speed limit, if any
|
||||
fLastVel = -1.0;
|
||||
sSpeedTable.clear();
|
||||
iLast = -1;
|
||||
tLast = nullptr; //żaden nie sprawdzony
|
||||
SemNextIndex = -1;
|
||||
SemNextStopIndex = -1;
|
||||
if( VelSignalLast == 0.0 ) {
|
||||
// don't allow potential red light overrun keep us from reversing
|
||||
VelSignalLast = -1.0;
|
||||
}
|
||||
fTrackLength = pTrack->Length(); //skasowanie zmian w zmiennej żeby poprawnie liczyło w dalszych krokach
|
||||
MoveDistanceReset(); // AI startuje 1s po zaczęciu jazdy i mógł już coś przejechać
|
||||
}
|
||||
@@ -759,7 +761,7 @@ void TController::TableCheck(double fDistance)
|
||||
{ // przeliczenie odległości w tabelce, ewentualnie doskanowanie (bez analizy prędkości itp.)
|
||||
if( iTableDirection != iDirection ) {
|
||||
// jak zmiana kierunku, to skanujemy od końca składu
|
||||
TableTraceRoute( fDistance, pVehicles[ 1 ] );
|
||||
TableTraceRoute( fDistance, pVehicles[ end::rear ] );
|
||||
TableSort();
|
||||
}
|
||||
else if (iTableDirection)
|
||||
@@ -786,7 +788,7 @@ void TController::TableCheck(double fDistance)
|
||||
--iLast;
|
||||
}
|
||||
tLast = sSpeedTable[ i ].trTrack;
|
||||
TableTraceRoute( fDistance, pVehicles[ 1 ] );
|
||||
TableTraceRoute( fDistance, pVehicles[ end::rear ] );
|
||||
TableSort();
|
||||
// nie kontynuujemy pętli, trzeba doskanować ciąg dalszy
|
||||
break;
|
||||
@@ -824,7 +826,7 @@ void TController::TableCheck(double fDistance)
|
||||
sSpeedTable[iLast].Update(); // aktualizacja ostatniego
|
||||
// WriteLog("TableCheck: Upate last track. Dist=" + AnsiString(sSpeedTable[iLast].fDist));
|
||||
if( sSpeedTable[ iLast ].fDist < fDistance ) {
|
||||
TableTraceRoute( fDistance, pVehicles[ 1 ] ); // doskanowanie dalszego odcinka
|
||||
TableTraceRoute( fDistance, pVehicles[ end::rear ] ); // doskanowanie dalszego odcinka
|
||||
TableSort();
|
||||
}
|
||||
// garbage collection
|
||||
@@ -1030,9 +1032,9 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
+ ": at " + std::to_string(simulation::Time.data().wHour) + ":" + std::to_string(simulation::Time.data().wMinute)
|
||||
+ " next " + asNextStop); // informacja
|
||||
#endif
|
||||
// update brake settings and ai braking tables
|
||||
// update consist weight, brake settings and ai braking tables
|
||||
// NOTE: this calculation is expected to run after completing loading/unloading
|
||||
AutoRewident(); // nastawianie hamulca do jazdy pociągowej
|
||||
CheckVehicles(); // nastawianie hamulca do jazdy pociągowej
|
||||
|
||||
if( static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 1 ) ) ) ) % 2 ) {
|
||||
// nie podjeżdżać do semafora, jeśli droga nie jest wolna
|
||||
@@ -1173,7 +1175,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
if( mvOccupied->Vel < 2.0 ) {
|
||||
// stanąć nie musi, ale zwolnić przynajmniej
|
||||
if( ( sSpeedTable[ i ].fDist < fMaxProximityDist )
|
||||
&& ( TrackBlock() > 1000.0 ) ) {
|
||||
&& ( Obstacle.distance > 1000 ) ) {
|
||||
// jest w maksymalnym zasięgu to można go pominąć (wziąć drugą prędkosć)
|
||||
// as long as there isn't any obstacle in arbitrary view range
|
||||
eSignSkip = sSpeedTable[ i ].evEvent;
|
||||
@@ -1259,7 +1261,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
|
||||
//sprawdzenie eventów pasywnych przed nami
|
||||
if( ( mvOccupied->CategoryFlag & 1 )
|
||||
&& ( sSpeedTable[ i ].fDist > pVehicles[ 0 ]->fTrackBlock - 20.0 ) ) {
|
||||
&& ( sSpeedTable[ i ].fDist > Obstacle.distance - 20 ) ) {
|
||||
// jak sygnał jest dalej niż zawalidroga
|
||||
v = 0.0; // to może być podany dla tamtego: jechać tak, jakby tam stop był
|
||||
}
|
||||
@@ -2061,7 +2063,7 @@ bool TController::CheckVehicles(TOrders user)
|
||||
&& ( p->MoverParameters->BrakeSubsystem != TBrakeSubSystem::ss_LSt ) ) {
|
||||
iDrivigFlags &= ~( moveOerlikons );
|
||||
}
|
||||
p = p->Neightbour(dir); // pojazd podłączony od wskazanej strony
|
||||
p = p->Neighbour(dir); // pojazd podłączony od wskazanej strony
|
||||
}
|
||||
if (main)
|
||||
iDrivigFlags |= movePrimary; // nie znaleziono innego, można się porządzić
|
||||
@@ -2353,7 +2355,6 @@ bool TController::PrepareEngine()
|
||||
voltrear = false;
|
||||
LastReactionTime = 0.0;
|
||||
ReactionTime = PrepareTime;
|
||||
iDrivigFlags |= moveActive; // może skanować sygnały i reagować na komendy
|
||||
|
||||
if ( mvControlling->EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) {
|
||||
voltfront = true;
|
||||
@@ -2408,11 +2409,11 @@ bool TController::PrepareEngine()
|
||||
if( !iDirection ) {
|
||||
// jeśli nie ma ustalonego kierunku
|
||||
if( ( mvControlling->PantFrontVolt != 0.0 ) || ( mvControlling->PantRearVolt != 0.0 ) || voltfront || voltrear ) {
|
||||
if( mvOccupied->Couplers[ 1 ].CouplingFlag == coupling::faux ) {
|
||||
if( mvOccupied->Couplers[ end::rear ].Connected == nullptr ) {
|
||||
// jeśli z tyłu nie ma nic
|
||||
iDirection = -1; // jazda w kierunku sprzęgu 1
|
||||
}
|
||||
if( mvOccupied->Couplers[ 0 ].CouplingFlag == coupling::faux ) {
|
||||
if( mvOccupied->Couplers[ end::front ].Connected == nullptr ) {
|
||||
// jeśli z przodu nie ma nic
|
||||
iDirection = 1; // jazda w kierunku sprzęgu 0
|
||||
}
|
||||
@@ -2484,6 +2485,8 @@ bool TController::PrepareEngine()
|
||||
}
|
||||
eAction = TAction::actUnknown;
|
||||
iEngineActive = 1;
|
||||
iDrivigFlags |= moveActive; // może skanować sygnały i reagować na komendy
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -2618,12 +2621,12 @@ bool TController::IncBrake()
|
||||
|| ( mvOccupied->TrainType == dt_ET42 ) ) {
|
||||
// NOTE: we're doing simplified checks full of presuptions here.
|
||||
// they'll break if someone does strange thing like turning around the second unit
|
||||
if( ( mvOccupied->Couplers[ 1 ].CouplingFlag & coupling::permanent )
|
||||
&& ( mvOccupied->Couplers[ 1 ].Connected->Couplers[ 1 ].CouplingFlag > 0 ) ) {
|
||||
if( ( mvOccupied->Couplers[ end::rear ].CouplingFlag & coupling::permanent )
|
||||
&& ( mvOccupied->Couplers[ end::rear ].Connected->Couplers[ end::rear ].Connected != nullptr ) ) {
|
||||
standalone = false;
|
||||
}
|
||||
if( ( mvOccupied->Couplers[ 0 ].CouplingFlag & coupling::permanent )
|
||||
&& ( mvOccupied->Couplers[ 0 ].Connected->Couplers[ 0 ].CouplingFlag > 0 ) ) {
|
||||
if( ( mvOccupied->Couplers[ end::front ].CouplingFlag & coupling::permanent )
|
||||
&& ( mvOccupied->Couplers[ end::front ].Connected->Couplers[ end::front ].Connected != nullptr ) ) {
|
||||
standalone = false;
|
||||
}
|
||||
}
|
||||
@@ -2637,16 +2640,16 @@ bool TController::IncBrake()
|
||||
( ( mvOccupied->Couplers[ 0 ].CouplingFlag == 0 )
|
||||
&& ( mvOccupied->Couplers[ 1 ].CouplingFlag == 0 ) );
|
||||
*/
|
||||
if( pVehicles[ 0 ] != pVehicles[ 1 ] ) {
|
||||
if( pVehicles[ end::front ] != pVehicles[ end::rear ] ) {
|
||||
// more detailed version, will use manual braking also for coupled sets of controlled vehicles
|
||||
auto *vehicle = pVehicles[ 0 ]; // start from first
|
||||
auto *vehicle = pVehicles[ end::front ]; // start from first
|
||||
while( ( true == standalone )
|
||||
&& ( vehicle != nullptr ) ) {
|
||||
// NOTE: we could simplify this by doing only check of the rear coupler, but this can be quite tricky in itself
|
||||
// TODO: add easier ways to access front/rear coupler taking into account vehicle's direction
|
||||
standalone =
|
||||
( ( ( vehicle->MoverParameters->Couplers[ 0 ].CouplingFlag == 0 ) || ( vehicle->MoverParameters->Couplers[ 0 ].CouplingFlag & coupling::control ) )
|
||||
&& ( ( vehicle->MoverParameters->Couplers[ 1 ].CouplingFlag == 0 ) || ( vehicle->MoverParameters->Couplers[ 1 ].CouplingFlag & coupling::control ) ) );
|
||||
( ( ( vehicle->MoverParameters->Couplers[ end::front ].Connected == nullptr ) || ( vehicle->MoverParameters->Couplers[ end::front ].CouplingFlag & coupling::control ) )
|
||||
&& ( ( vehicle->MoverParameters->Couplers[ end::rear ].Connected == nullptr ) || ( vehicle->MoverParameters->Couplers[ end::rear ].CouplingFlag & coupling::control ) ) );
|
||||
vehicle = vehicle->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
|
||||
}
|
||||
}
|
||||
@@ -3172,7 +3175,7 @@ void TController::SpeedSet()
|
||||
// Ra 2014-06: "automatyczna" skrzynia biegów...
|
||||
if (!mvControlling->MotorParam[mvControlling->ScndCtrlPos].AutoSwitch) // gdy biegi ręczne
|
||||
if ((mvControlling->ShuntMode ? mvControlling->AnPos : 1.0) * mvControlling->Vel >
|
||||
0.6 * mvControlling->MotorParam[mvControlling->ScndCtrlPos].mfi)
|
||||
0.75 * mvControlling->MotorParam[mvControlling->ScndCtrlPos].mfi)
|
||||
// if (mvControlling->enrot>0.95*mvControlling->dizel_nMmax) //youBy: jeśli obroty >
|
||||
// 0,95 nmax, wrzuć wyższy bieg - Ra: to nie działa
|
||||
{ // jak prędkość większa niż 0.6 maksymalnej na danym biegu, wrzucić wyższy
|
||||
@@ -3223,7 +3226,7 @@ void TController::Doors( bool const Open, int const Side ) {
|
||||
auto const lewe = ( pVehicle->DirectionGet() > 0 ) ? 1 : 2;
|
||||
auto const prawe = 3 - lewe;
|
||||
|
||||
if( ( pVehicle->MoverParameters->Doors.open_permit == false )
|
||||
if( ( true == pVehicle->MoverParameters->Doors.permit_needed )
|
||||
&& ( true == AIControllFlag ) ) {
|
||||
// grant door control permission if it's not automatic
|
||||
// TBD: stricter requirements?
|
||||
@@ -3247,7 +3250,8 @@ void TController::Doors( bool const Open, int const Side ) {
|
||||
}
|
||||
else {
|
||||
// zamykanie
|
||||
if( ( true == pVehicle->MoverParameters->Doors.open_permit ) && ( false == doors_open() ) ) {
|
||||
if( ( false == pVehicle->MoverParameters->Doors.permit_needed )
|
||||
&& ( false == doors_open() ) ) {
|
||||
// the doors are already closed and we don't have to revoke control permit, we can skip all hard work
|
||||
iDrivigFlags &= ~moveDoorOpened;
|
||||
}
|
||||
@@ -3265,14 +3269,18 @@ void TController::Doors( bool const Open, int const Side ) {
|
||||
&& ( ( fActionTime > -0.5 )
|
||||
|| ( false == AIControllFlag ) ) ) {
|
||||
// ai doesn't close the door until it's free to depart, but human driver has free reign to do stupid things
|
||||
if( ( pVehicle->MoverParameters->Doors.open_control == control_t::conductor )
|
||||
if( ( pVehicle->MoverParameters->Doors.close_control == control_t::conductor )
|
||||
|| ( ( true == AIControllFlag )
|
||||
&& ( ( pVehicle->MoverParameters->Doors.open_control == control_t::driver )
|
||||
|| ( pVehicle->MoverParameters->Doors.open_control == control_t::mixed ) ) ) ) {
|
||||
&& ( ( pVehicle->MoverParameters->Doors.close_control == control_t::driver )
|
||||
|| ( pVehicle->MoverParameters->Doors.close_control == control_t::mixed ) ) ) ) {
|
||||
// if the door are controlled by the driver, we let the user operate them unless this user is an ai
|
||||
// the train conductor, if present, handles door operation also for human-driven trains
|
||||
pVehicle->MoverParameters->OperateDoors( side::right, false );
|
||||
pVehicle->MoverParameters->OperateDoors( side::left, false );
|
||||
if( pVehicle->MoverParameters->Doors.permit_needed ) {
|
||||
pVehicle->MoverParameters->PermitDoors( side::right, false );
|
||||
pVehicle->MoverParameters->PermitDoors( side::left, false );
|
||||
}
|
||||
}
|
||||
|
||||
auto *vehicle = pVehicles[ 0 ]; // pojazd na czole składu
|
||||
@@ -3301,6 +3309,10 @@ void TController::Doors( bool const Open, int const Side ) {
|
||||
bool
|
||||
TController::doors_open() const {
|
||||
|
||||
return (
|
||||
IsAnyDoorOpen[ side::right ]
|
||||
|| IsAnyDoorOpen[ side::left ] );
|
||||
/*
|
||||
auto *vehicle = pVehicles[ 0 ]; // pojazd na czole składu
|
||||
while( vehicle != nullptr ) {
|
||||
if( ( false == vehicle->MoverParameters->Doors.instances[side::right].is_closed )
|
||||
@@ -3312,6 +3324,7 @@ TController::doors_open() const {
|
||||
}
|
||||
// if we're still here there's nothing open
|
||||
return false;
|
||||
*/
|
||||
}
|
||||
|
||||
void TController::RecognizeCommand()
|
||||
@@ -3624,22 +3637,21 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
|
||||
}
|
||||
WaitingTime = 0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
|
||||
}
|
||||
else // if (NewValue2==0.0) //zerowy sprzęg
|
||||
if (NewValue1 >= 0.0) // jeśli ilość wagonów inna niż wszystkie
|
||||
{ // będzie odczepianie, ale jeśli wagony są z przodu, to trzeba najpierw zmienić kierunek
|
||||
if ((mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 1 : 0].CouplingFlag ==
|
||||
0) ? // z tyłu nic
|
||||
(mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 0 : 1].CouplingFlag > 0) :
|
||||
false) // a z przodu skład
|
||||
{
|
||||
iDirectionOrder = -iDirection; // zmiana na ciągnięcie
|
||||
OrderNext(Change_direction); // najpierw zmień kierunek (zastąpi Disconnect)
|
||||
OrderPush(Disconnect); // a odczep już po zmianie kierunku
|
||||
else { // if (NewValue2==0.0) //zerowy sprzęg
|
||||
if( NewValue1 >= 0.0 ) {
|
||||
// jeśli ilość wagonów inna niż wszystkie będzie odczepianie,
|
||||
// ale jeśli wagony są z przodu, to trzeba najpierw zmienić kierunek
|
||||
if( ( mvOccupied->Couplers[ mvOccupied->DirAbsolute > 0 ? end::rear : end::front ].Connected == nullptr ) // z tyłu nic
|
||||
&& ( mvOccupied->Couplers[ mvOccupied->DirAbsolute > 0 ? end::front : end::rear ].Connected != nullptr ) ) { // a z przodu skład
|
||||
iDirectionOrder = -iDirection; // zmiana na ciągnięcie
|
||||
OrderNext( Change_direction ); // najpierw zmień kierunek (zastąpi Disconnect)
|
||||
OrderPush( Disconnect ); // a odczep już po zmianie kierunku
|
||||
}
|
||||
else if( mvOccupied->Couplers[ mvOccupied->DirAbsolute > 0 ? end::rear : end::front ].Connected != nullptr ) { // z tyłu coś
|
||||
OrderNext( Disconnect ); // jak ciągnie, to tylko odczep (NewValue1) wagonów
|
||||
}
|
||||
WaitingTime = 0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
|
||||
}
|
||||
else if (mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 1 : 0].CouplingFlag >
|
||||
0) // z tyłu coś
|
||||
OrderNext(Disconnect); // jak ciągnie, to tylko odczep (NewValue1) wagonów
|
||||
WaitingTime = 0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
|
||||
}
|
||||
if (NewValue1 == -1.0)
|
||||
{
|
||||
@@ -4180,55 +4192,46 @@ TController::UpdateSituation(double dt) {
|
||||
// 8. Ustalić częstotliwość świadomości AI (zatrzymanie precyzyjne - częściej, brak atrakcji
|
||||
// - rzadziej).
|
||||
|
||||
// check for potential colliders
|
||||
// check for potential collisions
|
||||
{
|
||||
auto rearvehicle = (
|
||||
pVehicles[ 0 ] == pVehicles[ 1 ] ?
|
||||
pVehicles[ 0 ] :
|
||||
pVehicles[ 1 ] );
|
||||
// HACK: vehicle order in the consist is based on intended travel direction
|
||||
// if our actual travel direction doesn't match that, we should be scanning from the other end of the consist
|
||||
// we cast to int to avoid getting confused by microstutters
|
||||
auto *frontvehicle { pVehicles[ ( static_cast<int>( mvOccupied->V ) * iDirection >= 0 ? end::front : end::rear ) ] };
|
||||
|
||||
int routescandirection;
|
||||
// for moving vehicle determine heading from velocity; for standing fall back on the set direction
|
||||
if( ( std::abs( mvOccupied->V ) < 0.1 ? // ignore potential micro-stutters in oposite direction during "almost stop"
|
||||
if( ( std::abs( frontvehicle->MoverParameters->V ) > 0.5 ? // ignore potential micro-stutters in oposite direction during "almost stop"
|
||||
frontvehicle->MoverParameters->V > 0.0 :
|
||||
( pVehicle->DirectionGet() == frontvehicle->DirectionGet() ?
|
||||
iDirection > 0 :
|
||||
mvOccupied->V > 0.0 ) ) {
|
||||
iDirection < 0 ) ) ) {
|
||||
// towards coupler 0
|
||||
if( ( mvOccupied->V * iDirection < 0.0 )
|
||||
|| ( ( rearvehicle->NextConnected != nullptr )
|
||||
&& ( rearvehicle->MoverParameters->Couplers[ ( rearvehicle->DirectionGet() > 0 ? 1 : 0 ) ].CouplingFlag == coupling::faux ) ) ) {
|
||||
// scan behind if we're moving backward, or if we had something connected there and are moving away
|
||||
rearvehicle->ABuScanObjects( (
|
||||
pVehicle->DirectionGet() == rearvehicle->DirectionGet() ?
|
||||
-1 :
|
||||
1 ),
|
||||
fMaxProximityDist );
|
||||
}
|
||||
pVehicles[ 0 ]->ABuScanObjects( (
|
||||
pVehicle->DirectionGet() == pVehicles[ 0 ]->DirectionGet() ?
|
||||
1 :
|
||||
-1 ),
|
||||
routescanrange );
|
||||
routescandirection = end::front;
|
||||
}
|
||||
else {
|
||||
// towards coupler 1
|
||||
if( ( mvOccupied->V * iDirection < 0.0 )
|
||||
|| ( ( rearvehicle->PrevConnected != nullptr )
|
||||
&& ( rearvehicle->MoverParameters->Couplers[ ( rearvehicle->DirectionGet() > 0 ? 0 : 1 ) ].CouplingFlag == coupling::faux ) ) ) {
|
||||
// scan behind if we're moving backward, or if we had something connected there and are moving away
|
||||
rearvehicle->ABuScanObjects( (
|
||||
pVehicle->DirectionGet() == rearvehicle->DirectionGet() ?
|
||||
1 :
|
||||
-1 ),
|
||||
fMaxProximityDist );
|
||||
routescandirection = end::rear;
|
||||
}
|
||||
|
||||
Obstacle = neighbour_data();
|
||||
auto const lookup { frontvehicle->find_vehicle( routescandirection, routescanrange ) };
|
||||
|
||||
if( std::get<bool>( lookup ) == true ) {
|
||||
|
||||
Obstacle.vehicle = std::get<TDynamicObject *>( lookup );
|
||||
Obstacle.vehicle_end = std::get<int>( lookup );
|
||||
Obstacle.distance = std::get<double>( lookup );
|
||||
|
||||
if( Obstacle.distance < ( mvOccupied->CategoryFlag == 2 ? 25 : 100 ) ) {
|
||||
// at short distances (re)calculate range between couplers directly
|
||||
Obstacle.distance = TMoverParameters::CouplerDist( frontvehicle->MoverParameters, Obstacle.vehicle->MoverParameters );
|
||||
}
|
||||
pVehicles[ 0 ]->ABuScanObjects( (
|
||||
pVehicle->DirectionGet() == pVehicles[ 0 ]->DirectionGet() ?
|
||||
-1 :
|
||||
1 ),
|
||||
routescanrange );
|
||||
}
|
||||
else {
|
||||
Obstacle.distance = 10000; // legacy value. TBD, TODO: use standard -1 instead?
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// tu bedzie logika sterowania
|
||||
if (AIControllFlag) {
|
||||
|
||||
@@ -4290,37 +4293,17 @@ TController::UpdateSituation(double dt) {
|
||||
if (AIControllFlag)
|
||||
{ // to robi tylko AI, wersję dla człowieka trzeba dopiero zrobić
|
||||
// sprzęgi sprawdzamy w pierwszej kolejności, bo jak połączony, to koniec
|
||||
bool ok; // true gdy się podłączy (uzyskany sprzęg będzie zgodny z żądanym)
|
||||
if (pVehicles[0]->DirectionGet() > 0) // jeśli sprzęg 0
|
||||
{ // sprzęg 0 - próba podczepienia
|
||||
if( pVehicles[ 0 ]->MoverParameters->Couplers[ 0 ].Connected ) {
|
||||
// jeśli jest coś wykryte (a chyba jest, nie?)
|
||||
if( pVehicles[ 0 ]->MoverParameters->Attach(
|
||||
0, 2, pVehicles[ 0 ]->MoverParameters->Couplers[ 0 ].Connected,
|
||||
iCoupler ) ) {
|
||||
// pVehicles[0]->dsbCouplerAttach->SetVolume(DSBVOLUME_MAX);
|
||||
// pVehicles[0]->dsbCouplerAttach->Play(0,0,0);
|
||||
}
|
||||
}
|
||||
// udało się? (mogło częściowo)
|
||||
ok = (pVehicles[0]->MoverParameters->Couplers[0].CouplingFlag == iCoupler);
|
||||
}
|
||||
else // if (pVehicles[0]->MoverParameters->DirAbsolute<0) //jeśli sprzęg 1
|
||||
{ // sprzęg 1 - próba podczepienia
|
||||
if( pVehicles[ 0 ]->MoverParameters->Couplers[ 1 ].Connected ) {
|
||||
// jeśli jest coś wykryte (a chyba jest, nie?)
|
||||
if( pVehicles[ 0 ]->MoverParameters->Attach(
|
||||
1, 2, pVehicles[ 0 ]->MoverParameters->Couplers[ 1 ].Connected,
|
||||
iCoupler ) ) {
|
||||
// pVehicles[0]->dsbCouplerAttach->SetVolume(DSBVOLUME_MAX);
|
||||
// pVehicles[0]->dsbCouplerAttach->Play(0,0,0);
|
||||
}
|
||||
}
|
||||
// udało się? (mogło częściowo)
|
||||
ok = (pVehicles[0]->MoverParameters->Couplers[1].CouplingFlag == iCoupler);
|
||||
}
|
||||
if (ok)
|
||||
{ // jeżeli został podłączony
|
||||
auto *vehicle { pVehicles[ end::front ] };
|
||||
auto *vehicleparameters { vehicle->MoverParameters };
|
||||
int const end { ( vehicle->DirectionGet() > 0 ? end::front : end::rear ) };
|
||||
auto const &neighbour { vehicleparameters->Neighbours[ end ] };
|
||||
// próba podczepienia
|
||||
vehicleparameters->Attach(
|
||||
end, neighbour.vehicle_end,
|
||||
neighbour.vehicle->MoverParameters,
|
||||
iCoupler );
|
||||
if( vehicleparameters->Couplers[ end ].CouplingFlag == iCoupler ) {
|
||||
// jeżeli został podłączony
|
||||
iCoupler = 0; // dalsza jazda manewrowa już bez łączenia
|
||||
iDrivigFlags &= ~moveConnect; // zdjęcie flagi doczepiania
|
||||
SetVelocity(0, 0, stopJoin); // wyłączyć przyspieszanie
|
||||
@@ -4336,7 +4319,7 @@ TController::UpdateSituation(double dt) {
|
||||
fMaxProximityDist = 5.0; //[m] w takim przedziale odległości powinien stanąć
|
||||
fVelPlus = 2.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania
|
||||
fVelMinus = 1.0; // margines prędkości powodujący załączenie napędu
|
||||
if( pVehicles[ 0 ]->fTrackBlock <= 20.0 ) {
|
||||
if( Obstacle.distance <= 20.0 ) {
|
||||
// przy zderzeniu fTrackBlock nie jest miarodajne
|
||||
// początek podczepiania, z wyłączeniem sprawdzania fTrackBlock
|
||||
iDrivigFlags |= moveConnect;
|
||||
@@ -4476,8 +4459,8 @@ TController::UpdateSituation(double dt) {
|
||||
&& ( false == TestFlag( iDrivigFlags, movePress ) )
|
||||
&& ( iCoupler == 0 )
|
||||
// && ( mvOccupied->Vel > 0.0 )
|
||||
&& ( pVehicle->MoverParameters->Couplers[ end::front ].CouplingFlag == coupling::faux )
|
||||
&& ( pVehicle->MoverParameters->Couplers[ end::rear ].CouplingFlag == coupling::faux ) ) {
|
||||
&& ( pVehicle->MoverParameters->Couplers[ end::front ].Connected == nullptr )
|
||||
&& ( pVehicle->MoverParameters->Couplers[ end::rear ].Connected == nullptr ) ) {
|
||||
SetVelocity(0, 0, stopJoin); // 1. faza odczepiania: zatrzymanie
|
||||
// WriteLog("Zatrzymanie w celu odczepienia");
|
||||
AccPreferred = std::min( 0.0, AccPreferred );
|
||||
@@ -4515,7 +4498,7 @@ TController::UpdateSituation(double dt) {
|
||||
else
|
||||
{ // samochód ma stać, aż dostanie odjazd, chyba że stoi przez kolizję
|
||||
if (eStopReason == stopBlock)
|
||||
if (pVehicles[0]->fTrackBlock > fDriverDist)
|
||||
if (Obstacle.distance > fDriverDist)
|
||||
if (AIControllFlag)
|
||||
{
|
||||
PrepareEngine(); // zmieni ustawiony kierunek
|
||||
@@ -4667,7 +4650,8 @@ TController::UpdateSituation(double dt) {
|
||||
n = 0; // nie ma co dalej sprawdzać, doczepianie zakończone
|
||||
}
|
||||
} while (n--);
|
||||
if( p ? p->MoverParameters->Couplers[ d ].CouplingFlag == coupling::faux : true ) {
|
||||
if( ( p == nullptr )
|
||||
|| ( p->MoverParameters->Couplers[ d ].Connected == nullptr ) ) {
|
||||
// no target, or already just virtual coupling
|
||||
WriteLog( mvOccupied->Name + " didn't find anything to disconnect." );
|
||||
iVehicleCount = -2; // odczepiono, co było do odczepienia
|
||||
@@ -4758,9 +4742,9 @@ TController::UpdateSituation(double dt) {
|
||||
// w trybie Connect skanować do tyłu tylko jeśli przed kolejnym sygnałem nie ma taboru do podłączenia
|
||||
// Ra 2F1H: z tym (fTrackBlock) to nie jest najlepszy pomysł, bo lepiej by
|
||||
// było porównać z odległością od sygnalizatora z przodu
|
||||
if( ( OrderList[ OrderPos ] & Connect ) ?
|
||||
( pVehicles[ 0 ]->fTrackBlock > 2000 || pVehicles[ 0 ]->fTrackBlock > FirstSemaphorDist ) :
|
||||
true ) {
|
||||
if( ( ( OrderList[ OrderPos ] & Connect ) == 0 )
|
||||
|| ( Obstacle.distance > std::min( 2000.0, FirstSemaphorDist ) ) ) {
|
||||
|
||||
if( ( comm = BackwardScan() ) != TCommandType::cm_Unknown ) {
|
||||
// jeśli w drugą można jechać
|
||||
// należy sprawdzać odległość od znalezionego sygnalizatora,
|
||||
@@ -4785,121 +4769,99 @@ TController::UpdateSituation(double dt) {
|
||||
VelDesired = fVelMax; // bo VelDesired<0 oznacza prędkość maksymalną
|
||||
|
||||
// Ra: jazda na widoczność
|
||||
/*
|
||||
// condition disabled, it'd prevent setting reduced acceleration in the last connect stage
|
||||
if ((iDrivigFlags & moveConnect) == 0) // przy końcówce podłączania nie hamować
|
||||
*/
|
||||
{ // sprawdzenie jazdy na widoczność
|
||||
auto const vehicle = pVehicles[ 0 ]; // base calculactions off relevant end of the consist
|
||||
auto const coupler =
|
||||
vehicle->MoverParameters->Couplers + (
|
||||
vehicle->DirectionGet() > 0 ?
|
||||
0 :
|
||||
1 ); // sprzęg z przodu składu
|
||||
if( ( coupler->Connected )
|
||||
&& ( coupler->CouplingFlag == coupling::faux ) ) {
|
||||
// mamy coś z przodu podłączone sprzęgiem wirtualnym
|
||||
// wyliczanie optymalnego przyspieszenia do jazdy na widoczność
|
||||
/*
|
||||
ActualProximityDist = std::min(
|
||||
if( Obstacle.distance < 5000 ) {
|
||||
// mamy coś z przodu
|
||||
// prędkość pojazdu z przodu (zakładając, że jedzie w tę samą stronę!!!)
|
||||
auto const k { Obstacle.vehicle->MoverParameters->Vel };
|
||||
if( k - vel < 5 ) {
|
||||
// porównanie modułów prędkości [km/h]
|
||||
// zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej
|
||||
ActualProximityDist = std::min<double>(
|
||||
ActualProximityDist,
|
||||
vehicle->fTrackBlock - (
|
||||
mvOccupied->CategoryFlag & 2 ?
|
||||
fMinProximityDist : // cars can bunch up tighter
|
||||
fMaxProximityDist ) ); // other vehicle types less so
|
||||
*/
|
||||
// prędkość pojazdu z przodu (zakładając, że jedzie w tę samą stronę!!!)
|
||||
double k = coupler->Connected->Vel;
|
||||
if( k - vel < 5 ) {
|
||||
// porównanie modułów prędkości [km/h]
|
||||
// zatroszczyć się trzeba, jeśli tamten nie jedzie znacząco szybciej
|
||||
ActualProximityDist = std::min(
|
||||
ActualProximityDist,
|
||||
vehicle->fTrackBlock );
|
||||
Obstacle.distance );
|
||||
|
||||
if( ActualProximityDist <= (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
100.0 : // cars
|
||||
250.0 ) ) { // others
|
||||
// regardless of driving mode at close distance take precaution measures:
|
||||
// match the other vehicle's speed or slow down if the other vehicle is stopped
|
||||
VelDesired =
|
||||
min_speed(
|
||||
VelDesired,
|
||||
std::max(
|
||||
k,
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
40.0 : // cars
|
||||
20.0 ) ); // others
|
||||
if( vel > VelDesired + fVelPlus ) {
|
||||
// if going too fast force some prompt braking
|
||||
AccPreferred = std::min( -0.65, AccPreferred );
|
||||
}
|
||||
if( ActualProximityDist <= (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
100.0 : // cars
|
||||
250.0 ) ) { // others
|
||||
// regardless of driving mode at close distance take precaution measures:
|
||||
// match the other vehicle's speed or slow down if the other vehicle is stopped
|
||||
VelDesired =
|
||||
min_speed(
|
||||
VelDesired,
|
||||
std::max(
|
||||
k,
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
40.0 : // cars
|
||||
20.0 ) ); // others
|
||||
if( vel > VelDesired + fVelPlus ) {
|
||||
// if going too fast force some prompt braking
|
||||
AccPreferred = std::min( -0.65, AccPreferred );
|
||||
}
|
||||
}
|
||||
|
||||
double const distance = vehicle->fTrackBlock - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości
|
||||
if( distance < 0.0 ) {
|
||||
// jeśli odległość jest zbyt mała
|
||||
if( k < 10.0 ) // k - prędkość tego z przodu
|
||||
{ // jeśli tamten porusza się z niewielką prędkością albo stoi
|
||||
if( OrderCurrentGet() & Connect ) {
|
||||
// jeśli spinanie, to jechać dalej
|
||||
AccPreferred = std::min( 0.35, AccPreferred ); // nie hamuj
|
||||
VelDesired =
|
||||
min_speed(
|
||||
VelDesired,
|
||||
( vehicle->fTrackBlock > 150.0 ?
|
||||
20.0:
|
||||
4.0 ) );
|
||||
VelNext = 2.0; // i pakuj się na tamtego
|
||||
}
|
||||
else {
|
||||
// a normalnie to hamować
|
||||
VelNext = 0.0;
|
||||
if( vehicle->fTrackBlock <= fMinProximityDist ) {
|
||||
VelDesired = 0.0;
|
||||
}
|
||||
|
||||
if( ( mvOccupied->CategoryFlag & 1 )
|
||||
&& ( OrderCurrentGet() & Obey_train ) ) {
|
||||
// trains which move normally should try to stop at safe margin
|
||||
ActualProximityDist -= fDriverDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// jeśli oba jadą, to przyhamuj lekko i ogranicz prędkość
|
||||
if( vehicle->fTrackBlock < (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
fMaxProximityDist + 0.5 * vel : // cars
|
||||
2.0 * fMaxProximityDist + 2.0 * vel ) ) { //others
|
||||
// jak tamten jedzie wolniej a jest w drodze hamowania
|
||||
AccPreferred = std::min( -0.9, AccPreferred );
|
||||
VelNext = min_speed( std::round( k ) - 5.0, VelDesired );
|
||||
if( vehicle->fTrackBlock <= (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
fMaxProximityDist : // cars
|
||||
2.0 * fMaxProximityDist ) ) { //others
|
||||
// try to force speed change if obstacle is really close
|
||||
VelDesired = VelNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
ReactionTime = (
|
||||
mvOccupied->Vel > 0.01 ?
|
||||
0.1 : // orientuj się, bo jest goraco
|
||||
2.0 ); // we're already standing still, so take it easy
|
||||
}
|
||||
else {
|
||||
double const distance = Obstacle.distance - fMaxProximityDist - ( fBrakeDist * 1.15 ); // odległość bezpieczna zależy od prędkości
|
||||
if( distance < 0.0 ) {
|
||||
// jeśli odległość jest zbyt mała
|
||||
if( k < 10.0 ) // k - prędkość tego z przodu
|
||||
{ // jeśli tamten porusza się z niewielką prędkością albo stoi
|
||||
if( OrderCurrentGet() & Connect ) {
|
||||
// if there's something nearby in the connect mode don't speed up too much
|
||||
// jeśli spinanie, to jechać dalej
|
||||
AccPreferred = std::min( 0.35, AccPreferred ); // nie hamuj
|
||||
VelDesired =
|
||||
min_speed(
|
||||
VelDesired,
|
||||
( vehicle->fTrackBlock > 100.0 ?
|
||||
20.0 :
|
||||
( Obstacle.distance > 150 ?
|
||||
20.0:
|
||||
4.0 ) );
|
||||
VelNext = 2.0; // i pakuj się na tamtego
|
||||
}
|
||||
else {
|
||||
// a normalnie to hamować
|
||||
VelNext = 0.0;
|
||||
if( Obstacle.distance <= fMinProximityDist ) {
|
||||
VelDesired = 0.0;
|
||||
}
|
||||
|
||||
if( ( mvOccupied->CategoryFlag & 1 )
|
||||
&& ( OrderCurrentGet() & Obey_train ) ) {
|
||||
// trains which move normally should try to stop at safe margin
|
||||
ActualProximityDist -= fDriverDist;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// jeśli oba jadą, to przyhamuj lekko i ogranicz prędkość
|
||||
if( Obstacle.distance < (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
fMaxProximityDist + 0.5 * vel : // cars
|
||||
2.0 * fMaxProximityDist + 2.0 * vel ) ) { //others
|
||||
// jak tamten jedzie wolniej a jest w drodze hamowania
|
||||
AccPreferred = std::min( -0.9, AccPreferred );
|
||||
VelNext = min_speed( std::round( k ) - 5.0, VelDesired );
|
||||
if( Obstacle.distance <= (
|
||||
( mvOccupied->CategoryFlag & 2 ) ?
|
||||
fMaxProximityDist : // cars
|
||||
2.0 * fMaxProximityDist ) ) { //others
|
||||
// try to force speed change if obstacle is really close
|
||||
VelDesired = VelNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
ReactionTime = (
|
||||
mvOccupied->Vel > 0.01 ?
|
||||
0.1 : // orientuj się, bo jest goraco
|
||||
2.0 ); // we're already standing still, so take it easy
|
||||
}
|
||||
else {
|
||||
if( OrderCurrentGet() & Connect ) {
|
||||
// if there's something nearby in the connect mode don't speed up too much
|
||||
VelDesired =
|
||||
min_speed(
|
||||
VelDesired,
|
||||
( Obstacle.distance > 100 ?
|
||||
20.0 :
|
||||
4.0 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5059,7 +5021,7 @@ TController::UpdateSituation(double dt) {
|
||||
if( mvOccupied->CategoryFlag & 1 ) {
|
||||
// trains
|
||||
if( ( OrderCurrentGet() & ( Shunt | Connect ) )
|
||||
&& ( pVehicles[0]->fTrackBlock < 50.0 ) ) {
|
||||
&& ( Obstacle.distance < 50 ) ) {
|
||||
// crude detection of edge case, if approaching another vehicle coast slowly until min distance
|
||||
// this should allow to bunch up trainsets more on sidings
|
||||
VelDesired = min_speed( 5.0, VelDesired );
|
||||
@@ -6343,7 +6305,7 @@ bool TController::IsStop() const
|
||||
double
|
||||
TController::TrackBlock() const {
|
||||
|
||||
return pVehicles[ end::front ]->fTrackBlock;
|
||||
return Obstacle.distance;
|
||||
}
|
||||
|
||||
void TController::MoveTo(TDynamicObject *to)
|
||||
|
||||
1
Driver.h
1
Driver.h
@@ -376,6 +376,7 @@ private:
|
||||
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
|
||||
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
|
||||
basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
|
||||
neighbour_data Obstacle; // nearest vehicle detected ahead on current route
|
||||
|
||||
// timetable
|
||||
// methods
|
||||
|
||||
915
DynObj.cpp
915
DynObj.cpp
File diff suppressed because it is too large
Load Diff
33
DynObj.h
33
DynObj.h
@@ -183,12 +183,13 @@ public:
|
||||
std::string asDestination; // dokąd pojazd ma być kierowany "(stacja):(tor)"
|
||||
Math3D::matrix4x4 mMatrix; // macierz przekształcenia do renderowania modeli
|
||||
TMoverParameters *MoverParameters; // parametry fizyki ruchu oraz przeliczanie
|
||||
TDynamicObject *NextConnected; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
||||
TDynamicObject *PrevConnected; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||
int NextConnectedNo; // numer sprzęgu podłączonego z tyłu
|
||||
int PrevConnectedNo; // numer sprzęgu podłączonego z przodu
|
||||
double fScanDist; // odległość skanowania torów na obecność innych pojazdów
|
||||
double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
|
||||
inline TDynamicObject *NextConnected() { return MoverParameters->Neighbours[ end::rear ].vehicle; }; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
||||
inline TDynamicObject *PrevConnected() { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||
inline TDynamicObject *NextConnected() const { return MoverParameters->Neighbours[ end::rear ].vehicle; }; // pojazd podłączony od strony sprzęgu 1 (kabina -1)
|
||||
inline TDynamicObject *PrevConnected() const { return MoverParameters->Neighbours[ end::front ].vehicle; }; // pojazd podłączony od strony sprzęgu 0 (kabina 1)
|
||||
inline int NextConnectedNo() const { return MoverParameters->Neighbours[ end::rear ].vehicle_end; }
|
||||
inline int PrevConnectedNo() const { return MoverParameters->Neighbours[ end::front ].vehicle_end; }
|
||||
// double fTrackBlock; // odległość do przeszkody do dalszego ruchu (wykrywanie kolizji z innym pojazdem)
|
||||
|
||||
TPowerSource ConnectedEnginePowerSource( TDynamicObject const *Caller ) const;
|
||||
|
||||
@@ -455,11 +456,8 @@ private:
|
||||
int iNumAxles; // ilość osi
|
||||
std::string asModel;
|
||||
|
||||
public:
|
||||
void ABuScanObjects(int ScanDir, double ScanDist);
|
||||
|
||||
private:
|
||||
TDynamicObject *ABuFindObject( int &Foundcoupler, double &Distance, TTrack const *Track, int const Direction, int const Mycoupler );
|
||||
TDynamicObject *ABuFindObject( int &Foundcoupler, double &Distance, TTrack const *Track, int const Direction, int const Mycoupler ) const;
|
||||
void ABuCheckMyTrack();
|
||||
|
||||
public:
|
||||
@@ -470,7 +468,6 @@ private:
|
||||
TDynamicObject * Next();
|
||||
TDynamicObject * PrevC(int C);
|
||||
TDynamicObject * NextC(int C);
|
||||
double NextDistance(double d = -1.0);
|
||||
void SetdMoveLen(double dMoveLen) {
|
||||
MoverParameters->dMoveLen = dMoveLen; }
|
||||
void ResetdMoveLen() {
|
||||
@@ -485,6 +482,7 @@ private:
|
||||
return this ?
|
||||
asName :
|
||||
std::string(); };
|
||||
std::string asBaseDir;
|
||||
|
||||
// std::ofstream PneuLogFile; //zapis parametrow pneumatycznych
|
||||
// youBy - dym
|
||||
@@ -506,7 +504,6 @@ private:
|
||||
bool bDisplayCab; // czy wyswietlac kabine w train.cpp
|
||||
int iCabs; // maski bitowe modeli kabin
|
||||
TTrack *MyTrack; // McZapkie-030303: tor na ktorym stoi, ABu
|
||||
std::string asBaseDir;
|
||||
int iOverheadMask; // maska przydzielana przez AI pojazdom posiadającym pantograf, aby wymuszały jazdę bezprądową
|
||||
TTractionParam tmpTraction;
|
||||
double fAdjustment; // korekcja - docelowo przenieść do TrkFoll.cpp wraz z odległością od poprzedniego
|
||||
@@ -521,7 +518,7 @@ private:
|
||||
int init_sections( TModel3d const *Model, std::string const &Nameprefix );
|
||||
void create_controller( std::string const Type, bool const Trainset );
|
||||
void AttachPrev(TDynamicObject *Object, int iType = 1);
|
||||
bool UpdateForce(double dt, double dt1, bool FullVer);
|
||||
bool UpdateForce(double dt);
|
||||
// initiates load change by specified amounts, with a platform on specified side
|
||||
void LoadExchange( int const Disembark, int const Embark, int const Platform );
|
||||
// calculates time needed to complete current load change
|
||||
@@ -605,14 +602,13 @@ private:
|
||||
Axle1.GetTranslation() :
|
||||
Axle0.GetTranslation(); };
|
||||
// zwraca tor z aktywną osią
|
||||
inline TTrack * RaTrackGet() {
|
||||
inline TTrack * RaTrackGet() const {
|
||||
return iAxleFirst ?
|
||||
Axle1.GetTrack() :
|
||||
Axle0.GetTrack(); };
|
||||
|
||||
void couple( int const Side );
|
||||
int uncouple( int const Side );
|
||||
void CouplersDettach(double MinDist, int MyScanDir);
|
||||
void RadioStop();
|
||||
void Damage(char flag);
|
||||
void RaLightsSet(int head, int rear);
|
||||
@@ -626,8 +622,11 @@ private:
|
||||
return iDirection + iDirection - 1; };
|
||||
int DettachStatus(int dir);
|
||||
int Dettach(int dir);
|
||||
TDynamicObject * Neightbour(int &dir);
|
||||
void CoupleDist();
|
||||
TDynamicObject * Neighbour(int &dir);
|
||||
// updates potential collision sources
|
||||
void update_neighbours();
|
||||
// locates potential collision source within specified range, scanning its route in specified direction
|
||||
auto find_vehicle( int const Direction, double const Range ) const -> std::tuple<TDynamicObject *, int, double, bool>;
|
||||
TDynamicObject * ControlledFind();
|
||||
void ParamSet(int what, int into);
|
||||
// zapytanie do AI, po którym segmencie skrzyżowania jechać
|
||||
|
||||
19
Event.cpp
19
Event.cpp
@@ -886,9 +886,14 @@ whois_event::run_() {
|
||||
auto *targetcell { static_cast<TMemCell *>( std::get<scene::basic_node *>( target ) ) };
|
||||
if( targetcell == nullptr ) { continue; }
|
||||
// event effect code
|
||||
// +24: vehicle type, consist brake level, obstacle distance
|
||||
// +16: load type, load amount, max load amount
|
||||
// +8: destination, direction, engine power
|
||||
// +0: train name, station count, stop on next station
|
||||
if( m_input.flags & flags::load ) {
|
||||
// +16 or +24
|
||||
// jeśli pytanie o ładunek
|
||||
if( m_input.flags & flags::mode_add ) {
|
||||
if( m_input.flags & flags::mode_alt ) {
|
||||
// jeśli typ pojazdu
|
||||
// TODO: define and recognize individual request types
|
||||
auto const owner { (
|
||||
@@ -912,7 +917,7 @@ whois_event::run_() {
|
||||
|
||||
WriteLog(
|
||||
"Type: WhoIs (" + to_string( m_input.flags ) + ") - "
|
||||
+ "[name: " + m_activator->MoverParameters->TypeName + "], "
|
||||
+ "[type: " + m_activator->MoverParameters->TypeName + "], "
|
||||
+ "[consist brake level: " + to_string( consistbrakelevel, 2 ) + "], "
|
||||
+ "[obstacle distance: " + to_string( collisiondistance, 2 ) + " m]" );
|
||||
}
|
||||
@@ -931,7 +936,8 @@ whois_event::run_() {
|
||||
+ "[max load: " + to_string( m_activator->MoverParameters->MaxLoad, 2 ) + "]" );
|
||||
}
|
||||
}
|
||||
else if( m_input.flags & flags::mode_add ) { // jeśli miejsce docelowe pojazdu
|
||||
// +8
|
||||
else if( m_input.flags & flags::mode_alt ) { // jeśli miejsce docelowe pojazdu
|
||||
targetcell->UpdateValues(
|
||||
m_activator->asDestination, // adres docelowy
|
||||
m_activator->DirectionGet(), // kierunek pojazdu względem czoła składu (1=zgodny,-1=przeciwny)
|
||||
@@ -944,6 +950,7 @@ whois_event::run_() {
|
||||
+ "[direction: " + to_string( m_activator->DirectionGet() ) + "], "
|
||||
+ "[engine power: " + to_string( m_activator->MoverParameters->Power, 2 ) + "]" );
|
||||
}
|
||||
// +0
|
||||
else if( m_activator->Mechanik ) {
|
||||
if( m_activator->Mechanik->Primary() ) { // tylko jeśli ktoś tam siedzi - nie powinno dotyczyć pasażera!
|
||||
targetcell->UpdateValues(
|
||||
@@ -953,7 +960,11 @@ whois_event::run_() {
|
||||
1 :
|
||||
0, // 1, gdy ma tu zatrzymanie
|
||||
m_input.flags );
|
||||
WriteLog( "Train detected: " + m_activator->Mechanik->TrainName() );
|
||||
WriteLog(
|
||||
"Type: WhoIs (" + to_string( m_input.flags ) + ") - "
|
||||
+ "[train: " + m_activator->Mechanik->TrainName() + "], "
|
||||
+ "[stations left: " + to_string( m_activator->Mechanik->StationCount() - m_activator->Mechanik->StationIndex() ) + "], "
|
||||
+ "[stop at next: " + ( m_activator->Mechanik->IsStop() ? "yes" : "no") + "]" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
Event.h
6
Event.h
@@ -25,8 +25,10 @@ public:
|
||||
value_1 = 1 << 1,
|
||||
value_2 = 1 << 2,
|
||||
// update values
|
||||
load = 1 << 3,
|
||||
mode_add = 1 << 4,
|
||||
mode_add = 1 << 3,
|
||||
// whois
|
||||
mode_alt = 1 << 3,
|
||||
load = 1 << 4,
|
||||
// condition values
|
||||
track_busy = 1 << 3,
|
||||
track_free = 1 << 4,
|
||||
|
||||
36
Gauge.cpp
36
Gauge.cpp
@@ -360,21 +360,35 @@ void TGauge::AssignInt(int *iValue)
|
||||
iData = iValue;
|
||||
};
|
||||
|
||||
void TGauge::AssignBool(bool *bValue)
|
||||
{
|
||||
m_datatype = 'b';
|
||||
bData = bValue;
|
||||
};
|
||||
|
||||
void TGauge::UpdateValue()
|
||||
{ // ustawienie wartości docelowej z parametru
|
||||
switch (m_datatype)
|
||||
{ // to nie jest zbyt optymalne, można by zrobić osobne funkcje
|
||||
case 'f':
|
||||
UpdateValue( *fData );
|
||||
break;
|
||||
case 'd':
|
||||
UpdateValue( *dData );
|
||||
break;
|
||||
case 'i':
|
||||
UpdateValue( *iData );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case 'f': {
|
||||
UpdateValue( *fData );
|
||||
break;
|
||||
}
|
||||
case 'd': {
|
||||
UpdateValue( *dData );
|
||||
break;
|
||||
}
|
||||
case 'i': {
|
||||
UpdateValue( *iData );
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
UpdateValue( ( *bData ? 1.f : 0.f ) );
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
2
Gauge.h
2
Gauge.h
@@ -48,6 +48,7 @@ public:
|
||||
void AssignFloat(float *fValue);
|
||||
void AssignDouble(double *dValue);
|
||||
void AssignInt(int *iValue);
|
||||
void AssignBool(bool *bValue);
|
||||
void UpdateValue();
|
||||
// returns offset of submodel associated with the button from the model centre
|
||||
glm::vec3 model_offset() const;
|
||||
@@ -82,6 +83,7 @@ private:
|
||||
float *fData;
|
||||
double *dData { nullptr };
|
||||
int *iData;
|
||||
bool *bData;
|
||||
};
|
||||
int m_soundtype { 0 }; // toggle between exclusive and multiple sound generation
|
||||
sound_source m_soundtemplate { sound_placement::internal, EU07_SOUND_CABCONTROLSCUTOFFRANGE }; // shared properties for control's sounds
|
||||
|
||||
@@ -140,7 +140,7 @@ static int const ctrain_depot = 128; //nie rozłączalny podczas zwykłyc
|
||||
// vehicle sides; exclusive
|
||||
enum end {
|
||||
front = 0,
|
||||
rear
|
||||
rear = 1
|
||||
};
|
||||
|
||||
enum side {
|
||||
@@ -609,18 +609,16 @@ struct power_coupling {
|
||||
struct TCoupling {
|
||||
/*parametry*/
|
||||
double SpringKB = 1.0; /*stala sprezystosci zderzaka/sprzegu, %tlumiennosci */
|
||||
double SpringKC = 1.0;
|
||||
double beta = 0.0;
|
||||
double DmaxB = 0.1; /*tolerancja scisku/rozciagania, sila rozerwania*/
|
||||
double FmaxB = 1000.0;
|
||||
double SpringKC = 1.0;
|
||||
double DmaxC = 0.1;
|
||||
double FmaxC = 1000.0;
|
||||
TCouplerType CouplerType = TCouplerType::NoCoupler; /*typ sprzegu*/
|
||||
/*zmienne*/
|
||||
double beta = 0.0;
|
||||
TCouplerType CouplerType = TCouplerType::NoCoupler; /*typ sprzegu*/
|
||||
int AllowedFlag = 3; //Ra: maska dostępnych
|
||||
/*zmienne*/
|
||||
int CouplingFlag = 0; /*0 - wirtualnie, 1 - sprzegi, 2 - pneumatycznie, 4 - sterowanie, 8 - kabel mocy*/
|
||||
int AllowedFlag = 3; //Ra: znaczenie jak wyżej, maska dostępnych
|
||||
bool Render = false; /*ABu: czy rysowac jak zaczepiony sprzeg*/
|
||||
double CoupleDist = 0.0; /*ABu: optymalizacja - liczenie odleglosci raz na klatkę, bez iteracji*/
|
||||
class TMoverParameters *Connected = nullptr; /*co jest podlaczone*/
|
||||
int ConnectedNr = 0; //Ra: od której strony podłączony do (Connected): 0=przód, 1=tył
|
||||
double CForce = 0.0; /*sila z jaka dzialal*/
|
||||
@@ -628,16 +626,39 @@ struct TCoupling {
|
||||
bool CheckCollision = false; /*czy sprawdzac sile czy pedy*/
|
||||
|
||||
power_coupling power_high;
|
||||
power_coupling power_low; // TODO: implement this
|
||||
// power_coupling power_low; // TODO: implement this
|
||||
|
||||
int sounds { 0 }; // sounds emitted by the coupling devices
|
||||
bool Render = false; /*ABu: czy rysowac jak zaczepiony sprzeg*/
|
||||
};
|
||||
|
||||
struct neighbour_data {
|
||||
TDynamicObject *vehicle { nullptr }; // detected obstacle
|
||||
int vehicle_end { -1 }; // facing end of the obstacle
|
||||
float distance { -1.f }; // distance to the obstacle
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TMoverParameters
|
||||
{ // Ra: wrapper na kod pascalowy, przejmujący jego funkcje Q: 20160824 - juz nie wrapper a klasa bazowa :)
|
||||
private:
|
||||
// types
|
||||
|
||||
/* TODO: implement
|
||||
// communication cable, exchanging control signals with adjacent vehicle
|
||||
struct jumper_cable {
|
||||
// types
|
||||
using flag_pair = std::pair<bool, bool>;
|
||||
// members
|
||||
// booleans
|
||||
// std::array<bool, 1> flags {};
|
||||
// boolean pairs, exchanged data is swapped when connected to a matching end (front to front or back to back)
|
||||
// TBD, TODO: convert to regular bool array for efficiency once it's working?
|
||||
std::array<flag_pair, 1> flag_pairs {};
|
||||
// integers
|
||||
// std::array<int, 1> values {};
|
||||
};
|
||||
*/
|
||||
// basic approximation of a generic device
|
||||
// TBD: inheritance or composition?
|
||||
struct basic_device {
|
||||
@@ -702,6 +723,8 @@ private:
|
||||
bool is_closing { false }; // the door is currently closing
|
||||
bool is_opening { false }; // the door is currently opening
|
||||
bool is_open { false }; // the door is fully open
|
||||
bool step_folding { false }; // the doorstep is currently closing
|
||||
bool step_unfolding { false }; // the doorstep is currently opening
|
||||
};
|
||||
|
||||
struct door_data {
|
||||
@@ -722,9 +745,14 @@ private:
|
||||
bool has_autowarning { false };
|
||||
float auto_duration { -1.f }; // automatic door closure delay period
|
||||
float auto_velocity { -1.f }; // automatic door closure velocity threshold
|
||||
bool auto_include_remote { false }; // automatic door closure applies also to remote control
|
||||
bool permit_needed { false };
|
||||
std::vector<int> permit_presets; // permit presets selectable with preset switch
|
||||
// ld inputs
|
||||
bool lock_enabled { true };
|
||||
bool open_permit { true };
|
||||
bool step_enabled { true };
|
||||
// internal data
|
||||
int permit_preset { -1 }; // curent position of preset selection switch
|
||||
// vehicle parts
|
||||
std::array<basic_door, 2> instances; // door on the right and left side of the vehicle
|
||||
// ld outputs
|
||||
@@ -800,14 +828,12 @@ private:
|
||||
public:
|
||||
|
||||
double dMoveLen = 0.0;
|
||||
std::string filename;
|
||||
/*---opis lokomotywy, wagonu itp*/
|
||||
/*--opis serii--*/
|
||||
int CategoryFlag = 1; /*1 - pociag, 2 - samochod, 4 - statek, 8 - samolot*/
|
||||
/*--sekcja stalych typowych parametrow*/
|
||||
std::string TypeName; /*nazwa serii/typu*/
|
||||
//TrainType: string; {typ: EZT/elektrowoz - Winger 040304}
|
||||
int TrainType = 0; /*Ra: powinno być szybciej niż string*/
|
||||
int TrainType = 0; /*typ: EZT/elektrowoz - Winger 040304 Ra: powinno być szybciej niż string*/
|
||||
TEngineType EngineType = TEngineType::None; /*typ napedu*/
|
||||
TPowerParameters EnginePowerSource; /*zrodlo mocy dla silnikow*/
|
||||
TPowerParameters SystemPowerSource; /*zrodlo mocy dla systemow sterowania/przetwornic/sprezarek*/
|
||||
@@ -1059,6 +1085,7 @@ public:
|
||||
TRotation Rot { 0.0, 0.0, 0.0 };
|
||||
std::string Name; /*nazwa wlasna*/
|
||||
TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami
|
||||
std::array<neighbour_data, 2> Neighbours; // potential collision sources
|
||||
bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/
|
||||
int SoundFlag = 0; /*!o patrz stale sound_ */
|
||||
double DistCounter = 0.0; /*! licznik kilometrow */
|
||||
@@ -1289,24 +1316,19 @@ public:
|
||||
double FrictConst2d= 0.0;
|
||||
double TotalMassxg = 0.0; /*TotalMass*g*/
|
||||
|
||||
Math3D::vector3 vCoulpler[2]; // powtórzenie współrzędnych sprzęgów z DynObj :/
|
||||
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
|
||||
int iProblem = 0; // flagi problemów z taborem, aby AI nie musiało porównywać; 0=może jechać
|
||||
int iLights[2]; // bity zapalonych świateł tutaj, żeby dało się liczyć pobór prądu
|
||||
private:
|
||||
double CouplerDist(int Coupler);
|
||||
|
||||
public:
|
||||
TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int Cab);
|
||||
// obsługa sprzęgów
|
||||
double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
||||
/* double Distance(const vector3 &Loc1, const vector3 &Loc2, const vector3 &Dim1, const vector3 &Dim2);
|
||||
*/ //bool AttachA(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false);
|
||||
static double CouplerDist( TMoverParameters const *Left, TMoverParameters const *Right );
|
||||
static double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
||||
bool Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false, bool Audible = true);
|
||||
int DettachStatus(int ConnectNo);
|
||||
bool Dettach(int ConnectNo);
|
||||
void SetCoupleDist();
|
||||
bool DirectionForward();
|
||||
void BrakeLevelSet(double b);
|
||||
bool BrakeLevelAdd(double b);
|
||||
@@ -1322,7 +1344,7 @@ public:
|
||||
|
||||
// Q *******************************************************************************************
|
||||
double GetTrainsetVoltage(void);
|
||||
bool Physic_ReActivation(void);
|
||||
bool switch_physics(bool const State);
|
||||
double LocalBrakeRatio(void);
|
||||
double ManualBrakeRatio(void);
|
||||
double PipeRatio(void);/*ile napelniac*/
|
||||
@@ -1394,17 +1416,17 @@ public:
|
||||
/*funkcje obliczajace sily*/
|
||||
void ComputeConstans(void);//ABu: wczesniejsze wyznaczenie stalych dla liczenia sil
|
||||
double ComputeMass(void);
|
||||
void ComputeTotalForce(double dt, double dt1, bool FullVer);
|
||||
void ComputeTotalForce(double dt);
|
||||
double Adhesive(double staticfriction) const;
|
||||
double TractionForce(double dt);
|
||||
double FrictionForce(double R, int TDamage);
|
||||
double BrakeForceR(double ratio, double velocity);
|
||||
double BrakeForceP(double press, double velocity);
|
||||
double BrakeForce(const TTrackParam &Track);
|
||||
double CouplerForce(int CouplerN, double dt);
|
||||
double CouplerForce(int const End, double dt);
|
||||
void CollisionDetect(int CouplerN, double dt);
|
||||
/*obrot kol uwzgledniajacy poslizg*/
|
||||
double ComputeRotatingWheel(double WForce, double dt, double n);
|
||||
double ComputeRotatingWheel(double WForce, double dt, double n) const;
|
||||
|
||||
/*--funkcje dla lokomotyw*/
|
||||
bool DirectionBackward(void);/*! kierunek ruchu*/
|
||||
@@ -1472,7 +1494,9 @@ public:
|
||||
/* funckje dla wagonow*/
|
||||
bool AssignLoad( std::string const &Name, float const Amount = 0.f );
|
||||
bool LoadingDone(double LSpeed, std::string const &Loadname);
|
||||
bool PermitDoors( side const Door, range_t const Notify = range_t::consist );
|
||||
bool PermitDoors( side const Door, bool const State = true, range_t const Notify = range_t::consist );
|
||||
bool ChangeDoorPermitPreset( int const Change, range_t const Notify = range_t::consist );
|
||||
bool PermitDoorStep( bool const State, range_t const Notify = range_t::consist );
|
||||
bool OperateDoors( side const Door, bool const State, range_t const Notify = range_t::consist );
|
||||
bool LockDoors( bool const State, range_t const Notify = range_t::consist );
|
||||
bool signal_departure( bool const State, range_t const Notify = range_t::consist ); // toggles departure warning
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
278
Train.cpp
278
Train.cpp
@@ -138,28 +138,17 @@ TButton &TCab::Button(int n)
|
||||
}
|
||||
};
|
||||
|
||||
void TCab::Update()
|
||||
void TCab::Update( bool const Power )
|
||||
{ // odczyt parametrów i ustawienie animacji submodelom
|
||||
/*
|
||||
int i;
|
||||
for (i = 0; i < iGauges; ++i)
|
||||
{ // animacje izometryczne
|
||||
ggList[i].UpdateValue(); // odczyt parametru i przeliczenie na kąt
|
||||
ggList[i].Update(); // ustawienie animacji
|
||||
}
|
||||
for (i = 0; i < iButtons; ++i)
|
||||
{ // animacje dwustanowe
|
||||
btList[i].Update(); // odczyt parametru i wybór submodelu
|
||||
}
|
||||
*/
|
||||
for( auto &gauge : ggList ) {
|
||||
// animacje izometryczne
|
||||
gauge.UpdateValue(); // odczyt parametru i przeliczenie na kąt
|
||||
gauge.Update(); // ustawienie animacji
|
||||
}
|
||||
|
||||
for( auto &button : btList ) {
|
||||
// animacje dwustanowe
|
||||
button.Update(); // odczyt parametru i wybór submodelu
|
||||
button.Update( Power ); // odczyt parametru i wybór submodelu
|
||||
}
|
||||
};
|
||||
|
||||
@@ -169,6 +158,7 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
||||
|
||||
{ user_command::aidriverenable, &TTrain::OnCommand_aidriverenable },
|
||||
{ user_command::aidriverdisable, &TTrain::OnCommand_aidriverdisable },
|
||||
{ user_command::jointcontrollerset, &TTrain::OnCommand_jointcontrollerset },
|
||||
{ user_command::mastercontrollerincrease, &TTrain::OnCommand_mastercontrollerincrease },
|
||||
{ user_command::mastercontrollerincreasefast, &TTrain::OnCommand_mastercontrollerincreasefast },
|
||||
{ user_command::mastercontrollerdecrease, &TTrain::OnCommand_mastercontrollerdecrease },
|
||||
@@ -325,12 +315,15 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
||||
{ user_command::doortoggleright, &TTrain::OnCommand_doortoggleright },
|
||||
{ user_command::doorpermitleft, &TTrain::OnCommand_doorpermitleft },
|
||||
{ user_command::doorpermitright, &TTrain::OnCommand_doorpermitright },
|
||||
{ user_command::doorpermitpresetactivatenext, &TTrain::OnCommand_doorpermitpresetactivatenext },
|
||||
{ user_command::doorpermitpresetactivateprevious, &TTrain::OnCommand_doorpermitpresetactivateprevious },
|
||||
{ user_command::dooropenleft, &TTrain::OnCommand_dooropenleft },
|
||||
{ user_command::dooropenright, &TTrain::OnCommand_dooropenright },
|
||||
{ user_command::doorcloseleft, &TTrain::OnCommand_doorcloseleft },
|
||||
{ user_command::doorcloseright, &TTrain::OnCommand_doorcloseright },
|
||||
{ user_command::dooropenall, &TTrain::OnCommand_dooropenall },
|
||||
{ user_command::doorcloseall, &TTrain::OnCommand_doorcloseall },
|
||||
{ user_command::doorsteptoggle, &TTrain::OnCommand_doorsteptoggle },
|
||||
{ user_command::carcouplingincrease, &TTrain::OnCommand_carcouplingincrease },
|
||||
{ user_command::carcouplingdisconnect, &TTrain::OnCommand_carcouplingdisconnect },
|
||||
{ user_command::departureannounce, &TTrain::OnCommand_departureannounce },
|
||||
@@ -765,12 +758,49 @@ void TTrain::OnCommand_aidriverdisable( TTrain *Train, command_data const &Comma
|
||||
auto const EU07_CONTROLLER_BASERETURNDELAY { 0.5f };
|
||||
auto const EU07_CONTROLLER_KEYBOARDETURNDELAY { 1.5f };
|
||||
|
||||
void TTrain::OnCommand_jointcontrollerset( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
// on press or hold
|
||||
// value controls brake in range 0-0.5, master controller in range 0.5-1.0
|
||||
if( Command.param1 >= 0.5 ) {
|
||||
Train->set_master_controller(
|
||||
( Command.param1 * 2 - 1 )
|
||||
* ( Train->mvControlled->CoupledCtrl ?
|
||||
Train->mvControlled->MainCtrlPosNo + Train->mvControlled->ScndCtrlPosNo :
|
||||
Train->mvControlled->MainCtrlPosNo ) );
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
Train->mvOccupied->LocalBrakePosA = 0;
|
||||
}
|
||||
else {
|
||||
Train->mvOccupied->LocalBrakePosA = (
|
||||
clamp(
|
||||
1.0 - ( Command.param1 * 2 ),
|
||||
0.0, 1.0 ) );
|
||||
if( Train->mvControlled->MainCtrlPos > 0 ) {
|
||||
Train->set_master_controller( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// release
|
||||
Train->m_mastercontrollerinuse = false;
|
||||
Train->m_mastercontrollerreturndelay = EU07_CONTROLLER_BASERETURNDELAY; // NOTE: keyboard return delay is omitted for other input sources
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_mastercontrollerincrease( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
// on press or hold
|
||||
Train->mvControlled->IncMainCtrl( 1 );
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
if( ( Train->ggJointCtrl.SubModel != nullptr )
|
||||
&& ( Train->mvControlled->LocalBrakePosA > 0.0 ) ) {
|
||||
OnCommand_independentbrakedecrease( Train, Command );
|
||||
}
|
||||
else {
|
||||
Train->mvControlled->IncMainCtrl( 1 );
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// release
|
||||
@@ -783,7 +813,19 @@ void TTrain::OnCommand_mastercontrollerincreasefast( TTrain *Train, command_data
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
// on press or hold
|
||||
Train->mvControlled->IncMainCtrl( 2 );
|
||||
if( ( Train->ggJointCtrl.SubModel != nullptr )
|
||||
&& ( Train->mvControlled->LocalBrakePosA > 0.0 ) ) {
|
||||
OnCommand_independentbrakedecreasefast( Train, Command );
|
||||
}
|
||||
else {
|
||||
Train->mvControlled->IncMainCtrl( 2 );
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// release
|
||||
Train->m_mastercontrollerinuse = false;
|
||||
Train->m_mastercontrollerreturndelay = EU07_CONTROLLER_KEYBOARDETURNDELAY + EU07_CONTROLLER_BASERETURNDELAY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -791,8 +833,14 @@ void TTrain::OnCommand_mastercontrollerdecrease( TTrain *Train, command_data con
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
// on press or hold
|
||||
Train->mvControlled->DecMainCtrl( 1 );
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
if( ( Train->ggJointCtrl.SubModel != nullptr )
|
||||
&& ( Train->mvControlled->MainCtrlPos == 0 ) ) {
|
||||
OnCommand_independentbrakeincrease( Train, Command );
|
||||
}
|
||||
else {
|
||||
Train->mvControlled->DecMainCtrl( 1 );
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// release
|
||||
@@ -805,7 +853,19 @@ void TTrain::OnCommand_mastercontrollerdecreasefast( TTrain *Train, command_data
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
// on press or hold
|
||||
Train->mvControlled->DecMainCtrl( 2 );
|
||||
if( ( Train->ggJointCtrl.SubModel != nullptr )
|
||||
&& ( Train->mvControlled->MainCtrlPos == 0 ) ) {
|
||||
OnCommand_independentbrakeincreasefast( Train, Command );
|
||||
}
|
||||
else {
|
||||
Train->mvControlled->DecMainCtrl( 2 );
|
||||
Train->m_mastercontrollerinuse = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// release
|
||||
Train->m_mastercontrollerinuse = false;
|
||||
Train->m_mastercontrollerreturndelay = EU07_CONTROLLER_KEYBOARDETURNDELAY + EU07_CONTROLLER_BASERETURNDELAY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -989,7 +1049,7 @@ void TTrain::OnCommand_independentbrakeset( TTrain *Train, command_data const &C
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
|
||||
Train->mvControlled->LocalBrakePosA = (
|
||||
Train->mvOccupied->LocalBrakePosA = (
|
||||
clamp(
|
||||
Command.param1,
|
||||
0.0, 1.0 ) );
|
||||
@@ -4237,6 +4297,27 @@ void TTrain::OnCommand_doorpermitright( TTrain *Train, command_data const &Comma
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorpermitpresetactivatenext( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
|
||||
Train->mvOccupied->ChangeDoorPermitPreset( 1 );
|
||||
// visual feedback
|
||||
Train->ggDoorPermitPresetButton.UpdateValue( Train->mvOccupied->Doors.permit_preset, Train->dsbSwitch );
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorpermitpresetactivateprevious( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
|
||||
Train->mvOccupied->ChangeDoorPermitPreset( -1 );
|
||||
// visual feedback
|
||||
Train->ggDoorPermitPresetButton.UpdateValue( Train->mvOccupied->Doors.permit_preset, Train->dsbSwitch );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TTrain::OnCommand_dooropenleft( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
auto const remoteopencontrol {
|
||||
@@ -4575,6 +4656,13 @@ void TTrain::OnCommand_doorcloseall( TTrain *Train, command_data const &Command
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_doorsteptoggle( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
Train->mvOccupied->PermitDoorStep( false == Train->mvOccupied->Doors.step_enabled );
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_carcouplingincrease( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( ( true == FreeFlyModeFlag )
|
||||
@@ -4844,11 +4932,11 @@ void TTrain::OnCommand_cabchangeforward( TTrain *Train, command_data const &Comm
|
||||
if( false == Train->CabChange( 1 ) ) {
|
||||
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ end::front ].CouplingFlag, coupling::gangway ) ) {
|
||||
// przejscie do nastepnego pojazdu
|
||||
Global.changeDynObj = Train->DynamicObject->PrevConnected;
|
||||
Global.changeDynObj = Train->DynamicObject->PrevConnected();
|
||||
Global.changeDynObj->MoverParameters->ActiveCab = (
|
||||
Train->DynamicObject->PrevConnectedNo ?
|
||||
-1 :
|
||||
1 );
|
||||
Train->DynamicObject->MoverParameters->Neighbours[end::front].vehicle_end ?
|
||||
-1 :
|
||||
1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4860,11 +4948,11 @@ void TTrain::OnCommand_cabchangebackward( TTrain *Train, command_data const &Com
|
||||
if( false == Train->CabChange( -1 ) ) {
|
||||
if( TestFlag( Train->DynamicObject->MoverParameters->Couplers[ end::rear ].CouplingFlag, coupling::gangway ) ) {
|
||||
// przejscie do nastepnego pojazdu
|
||||
Global.changeDynObj = Train->DynamicObject->NextConnected;
|
||||
Global.changeDynObj = Train->DynamicObject->NextConnected();
|
||||
Global.changeDynObj->MoverParameters->ActiveCab = (
|
||||
Train->DynamicObject->NextConnectedNo ?
|
||||
-1 :
|
||||
1 );
|
||||
Train->DynamicObject->MoverParameters->Neighbours[end::rear].vehicle_end ?
|
||||
-1 :
|
||||
1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5237,14 +5325,14 @@ bool TTrain::Update( double const Deltatime )
|
||||
{
|
||||
TDynamicObject *tmp;
|
||||
tmp = NULL;
|
||||
if (DynamicObject->NextConnected)
|
||||
if (DynamicObject->NextConnected())
|
||||
if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) &&
|
||||
(mvOccupied->ActiveCab == 1))
|
||||
tmp = DynamicObject->NextConnected;
|
||||
if (DynamicObject->PrevConnected)
|
||||
tmp = DynamicObject->NextConnected();
|
||||
if (DynamicObject->PrevConnected())
|
||||
if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) &&
|
||||
(mvOccupied->ActiveCab == -1))
|
||||
tmp = DynamicObject->PrevConnected;
|
||||
tmp = DynamicObject->PrevConnected();
|
||||
if( tmp ) {
|
||||
if( tmp->MoverParameters->Power > 0 ) {
|
||||
if( ggI1B.SubModel ) {
|
||||
@@ -5285,7 +5373,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
ggClockHInd.Update();
|
||||
}
|
||||
|
||||
Cabine[iCabn].Update(); // nowy sposób ustawienia animacji
|
||||
Cabine[iCabn].Update( mvControlled->Battery || mvControlled->ConverterFlag ); // nowy sposób ustawienia animacji
|
||||
if (ggZbS.SubModel)
|
||||
{
|
||||
ggZbS.UpdateValue(mvOccupied->Handle->GetCP());
|
||||
@@ -5645,10 +5733,10 @@ bool TTrain::Update( double const Deltatime )
|
||||
tmp = NULL;
|
||||
if ((TestFlag(mvControlled->Couplers[1].CouplingFlag, ctrain_controll)) &&
|
||||
(mvOccupied->ActiveCab > 0))
|
||||
tmp = DynamicObject->NextConnected;
|
||||
tmp = DynamicObject->NextConnected();
|
||||
if ((TestFlag(mvControlled->Couplers[0].CouplingFlag, ctrain_controll)) &&
|
||||
(mvOccupied->ActiveCab < 0))
|
||||
tmp = DynamicObject->PrevConnected;
|
||||
tmp = DynamicObject->PrevConnected();
|
||||
|
||||
if (tmp)
|
||||
if ( mvControlled->Battery || mvControlled->ConverterFlag ) {
|
||||
@@ -5715,7 +5803,21 @@ bool TTrain::Update( double const Deltatime )
|
||||
}
|
||||
}
|
||||
// McZapkie-080602: obroty (albo translacje) regulatorow
|
||||
if (ggMainCtrl.SubModel) {
|
||||
if( ggJointCtrl.SubModel != nullptr ) {
|
||||
// joint master controller moves forward to adjust power and backward to adjust brakes
|
||||
auto const brakerangemultiplier {
|
||||
( mvControlled->CoupledCtrl ?
|
||||
mvControlled->MainCtrlPosNo + mvControlled->ScndCtrlPosNo :
|
||||
mvControlled->MainCtrlPosNo )
|
||||
/ static_cast<double>(LocalBrakePosNo) };
|
||||
ggJointCtrl.UpdateValue(
|
||||
( mvOccupied->LocalBrakePosA > 0.0 ? mvOccupied->LocalBrakePosA * LocalBrakePosNo * -1 * brakerangemultiplier :
|
||||
mvControlled->CoupledCtrl ? double( mvControlled->MainCtrlPos + mvControlled->ScndCtrlPos ) :
|
||||
double( mvControlled->MainCtrlPos ) ),
|
||||
dsbNastawnikJazdy );
|
||||
ggJointCtrl.Update();
|
||||
}
|
||||
if ( ggMainCtrl.SubModel != nullptr ) {
|
||||
|
||||
#ifdef _WIN32
|
||||
if( ( DynamicObject->Mechanik != nullptr )
|
||||
@@ -5802,7 +5904,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
ggBrakeCtrl.Update();
|
||||
}
|
||||
|
||||
if( ggLocalBrake.SubModel ) {
|
||||
if( ggLocalBrake.SubModel != nullptr ) {
|
||||
#ifdef _WIN32
|
||||
if( ( DynamicObject->Mechanik != nullptr )
|
||||
&& ( false == DynamicObject->Mechanik->AIControllFlag ) // nie blokujemy AI
|
||||
@@ -5839,6 +5941,7 @@ bool TTrain::Update( double const Deltatime )
|
||||
// NBMX wrzesien 2003 - drzwi
|
||||
ggDoorLeftPermitButton.Update();
|
||||
ggDoorRightPermitButton.Update();
|
||||
ggDoorPermitPresetButton.Update();
|
||||
ggDoorLeftButton.Update();
|
||||
ggDoorRightButton.Update();
|
||||
ggDoorLeftOnButton.Update();
|
||||
@@ -5869,11 +5972,12 @@ bool TTrain::Update( double const Deltatime )
|
||||
InstrumentLightType == 1 ? mvControlled->Mains :
|
||||
InstrumentLightType == 2 ? mvControlled->ConverterFlag :
|
||||
InstrumentLightType == 3 ? mvControlled->Battery || mvControlled->ConverterFlag :
|
||||
InstrumentLightType == 4 ? mvControlled->Battery || mvControlled->ConverterFlag :
|
||||
false ) };
|
||||
if( InstrumentLightType == 3 ) {
|
||||
// TODO: link the light state with the state of the master key
|
||||
InstrumentLightActive = true;
|
||||
}
|
||||
InstrumentLightActive = (
|
||||
InstrumentLightType == 3 ? true : // TODO: link the light state with the state of the master key
|
||||
InstrumentLightType == 4 ? ( mvOccupied->iLights[end::front] != 0 ) || ( mvOccupied->iLights[end::rear] != 0 ) :
|
||||
InstrumentLightActive );
|
||||
btInstrumentLight.Turn( InstrumentLightActive && lightpower );
|
||||
btDashboardLight.Turn( DashboardLightActive && lightpower );
|
||||
btTimetableLight.Turn( TimetableLightActive && lightpower );
|
||||
@@ -6245,7 +6349,10 @@ TTrain::update_sounds( double const Deltatime ) {
|
||||
|| TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ) {
|
||||
|
||||
if( false == dsbBuzzer.is_playing() ) {
|
||||
dsbBuzzer.play( sound_flags::looping );
|
||||
dsbBuzzer
|
||||
.pitch( dsbBuzzer.m_frequencyoffset + dsbBuzzer.m_frequencyfactor )
|
||||
.gain( dsbBuzzer.m_amplitudeoffset + dsbBuzzer.m_amplitudefactor )
|
||||
.play( sound_flags::looping );
|
||||
Console::BitsSet( 1 << 14 ); // ustawienie bitu 16 na PoKeys
|
||||
}
|
||||
}
|
||||
@@ -6270,9 +6377,10 @@ TTrain::update_sounds( double const Deltatime ) {
|
||||
auto const frequency { (
|
||||
true == dsbHasler.is_combined() ?
|
||||
fTachoVelocity * 0.01 :
|
||||
1.0 ) };
|
||||
dsbHasler.m_frequencyoffset + dsbHasler.m_frequencyfactor ) };
|
||||
dsbHasler
|
||||
.pitch( frequency )
|
||||
.gain( dsbHasler.m_amplitudeoffset + dsbHasler.m_amplitudefactor )
|
||||
.play( sound_flags::exclusive | sound_flags::looping );
|
||||
}
|
||||
else if( fTachoCount < 1.f ) {
|
||||
@@ -6827,6 +6935,9 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
|
||||
if( dsbReverserKey.offset() == nullvector ) {
|
||||
dsbReverserKey.offset( ggDirKey.model_offset() );
|
||||
}
|
||||
if( dsbNastawnikJazdy.offset() == nullvector ) {
|
||||
dsbNastawnikJazdy.offset( ggJointCtrl.model_offset() );
|
||||
}
|
||||
if( dsbNastawnikJazdy.offset() == nullvector ) {
|
||||
dsbNastawnikJazdy.offset( ggMainCtrl.model_offset() );
|
||||
}
|
||||
@@ -6925,26 +7036,25 @@ void TTrain::DynamicSet(TDynamicObject *d)
|
||||
mvOccupied = mvControlled = d ? DynamicObject->MoverParameters : NULL; // albo silnikowy w EZT
|
||||
if (!DynamicObject)
|
||||
return;
|
||||
if (mvControlled->TrainType & dt_EZT) // na razie dotyczy to EZT
|
||||
if (DynamicObject->NextConnected ? mvControlled->Couplers[1].AllowedFlag & ctrain_depot :
|
||||
false)
|
||||
{ // gdy jest człon od sprzęgu 1, a sprzęg łączony
|
||||
// warsztatowo (powiedzmy)
|
||||
if ((mvControlled->Power < 1.0) && (mvControlled->Couplers[1].Connected->Power >
|
||||
1.0)) // my nie mamy mocy, ale ten drugi ma
|
||||
mvControlled =
|
||||
DynamicObject->NextConnected->MoverParameters; // będziemy sterować tym z mocą
|
||||
// TODO: leverage code already present in TDynamicObject::ControlledFind()
|
||||
if( ( d->MoverParameters->TrainType == dt_EZT )
|
||||
|| ( d->MoverParameters->TrainType == dt_DMU ) ) {
|
||||
|
||||
if( ( d->NextConnected() != nullptr )
|
||||
&& ( true == TestFlag( d->MoverParameters->Couplers[ end::rear ].AllowedFlag, coupling::permanent ) ) ) {
|
||||
if( ( mvControlled->Power < 1.0 ) && ( mvControlled->Couplers[ 1 ].Connected->Power > 1.0 ) ) {
|
||||
// my nie mamy mocy, ale ten drugi ma
|
||||
mvControlled = DynamicObject->NextConnected()->MoverParameters; // będziemy sterować tym z mocą
|
||||
}
|
||||
}
|
||||
else if (DynamicObject->PrevConnected ?
|
||||
mvControlled->Couplers[0].AllowedFlag & ctrain_depot :
|
||||
false)
|
||||
{ // gdy jest człon od sprzęgu 0, a sprzęg łączony
|
||||
// warsztatowo (powiedzmy)
|
||||
if ((mvControlled->Power < 1.0) && (mvControlled->Couplers[0].Connected->Power >
|
||||
1.0)) // my nie mamy mocy, ale ten drugi ma
|
||||
mvControlled =
|
||||
DynamicObject->PrevConnected->MoverParameters; // będziemy sterować tym z mocą
|
||||
else if( ( d->PrevConnected() != nullptr )
|
||||
&& ( true == TestFlag( d->MoverParameters->Couplers[ end::front ].AllowedFlag, coupling::permanent ) ) ) {
|
||||
if( ( mvControlled->Power < 1.0 ) && ( mvControlled->Couplers[ 0 ].Connected->Power > 1.0 ) ) {
|
||||
// my nie mamy mocy, ale ten drugi ma
|
||||
mvControlled = DynamicObject->PrevConnected()->MoverParameters; // będziemy sterować tym z mocą
|
||||
}
|
||||
}
|
||||
}
|
||||
mvSecond = NULL; // gdyby się nic nie znalazło
|
||||
if (mvOccupied->Power > 1.0) // dwuczłonowe lub ukrotnienia, żeby nie szukać każdorazowo
|
||||
if (mvOccupied->Couplers[1].Connected ?
|
||||
@@ -7069,6 +7179,7 @@ void TTrain::clear_cab_controls()
|
||||
|
||||
// other cab controls
|
||||
// TODO: arrange in more readable manner, and eventually refactor
|
||||
ggJointCtrl.Clear();
|
||||
ggMainCtrl.Clear();
|
||||
ggMainCtrlAct.Clear();
|
||||
ggScndCtrl.Clear();
|
||||
@@ -7116,6 +7227,7 @@ void TTrain::clear_cab_controls()
|
||||
ggRadioTest.Clear();
|
||||
ggDoorLeftPermitButton.Clear();
|
||||
ggDoorRightPermitButton.Clear();
|
||||
ggDoorPermitPresetButton.Clear();
|
||||
ggDoorLeftButton.Clear();
|
||||
ggDoorRightButton.Clear();
|
||||
ggDoorLeftOnButton.Clear();
|
||||
@@ -7429,6 +7541,7 @@ void TTrain::set_cab_controls( int const Cab ) {
|
||||
0.f ) );
|
||||
// doors
|
||||
// NOTE: for the time being permit switches are presumed to be impulse switches
|
||||
ggDoorPermitPresetButton.PutValue( mvOccupied->Doors.permit_preset );
|
||||
ggDoorLeftButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::left : side::right ) ].is_closed ? 0.f : 1.f );
|
||||
ggDoorRightButton.PutValue( mvOccupied->Doors.instances[ ( mvOccupied->ActiveCab == 1 ? side::right : side::left ) ].is_closed ? 0.f : 1.f );
|
||||
// door lock
|
||||
@@ -7648,7 +7761,8 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
||||
// TODO: move viable dedicated lights to the automatic light array
|
||||
std::unordered_map<std::string, bool *> const autolights = {
|
||||
{ "i-doorpermit_left:", &mvOccupied->Doors.instances[side::left].open_permit },
|
||||
{ "i-doorpermit_right:", &mvOccupied->Doors.instances[ side::right ].open_permit }
|
||||
{ "i-doorpermit_right:", &mvOccupied->Doors.instances[ side::right ].open_permit },
|
||||
{ "i-doorstep:", &mvOccupied->Doors.step_enabled }
|
||||
};
|
||||
{
|
||||
auto lookup = autolights.find( Label );
|
||||
@@ -7676,6 +7790,10 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
||||
btInstrumentLight.Load( Parser, DynamicObject );
|
||||
InstrumentLightType = 3;
|
||||
}
|
||||
else if( Label == "i-instrumentlight_l:" ) {
|
||||
btInstrumentLight.Load( Parser, DynamicObject );
|
||||
InstrumentLightType = 4;
|
||||
}
|
||||
else if (Label == "i-doors:")
|
||||
{
|
||||
int i = Parser.getToken<int>() - 1;
|
||||
@@ -7697,6 +7815,7 @@ bool TTrain::initialize_button(cParser &Parser, std::string const &Label, int co
|
||||
bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int const Cabindex) {
|
||||
|
||||
std::unordered_map<std::string, TGauge &> const gauges = {
|
||||
{ "jointctrl:", ggJointCtrl },
|
||||
{ "mainctrl:", ggMainCtrl },
|
||||
{ "scndctrl:", ggScndCtrl },
|
||||
{ "dirkey:" , ggDirKey },
|
||||
@@ -7725,6 +7844,7 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "stlinoff_bt:", ggStLinOffButton },
|
||||
{ "doorleftpermit_sw:", ggDoorLeftPermitButton },
|
||||
{ "doorrightpermit_sw:", ggDoorRightPermitButton },
|
||||
{ "doorpermitpreset_sw:", ggDoorPermitPresetButton },
|
||||
{ "door_left_sw:", ggDoorLeftButton },
|
||||
{ "door_right_sw:", ggDoorRightButton },
|
||||
{ "doorlefton_sw:", ggDoorLeftOnButton },
|
||||
@@ -7800,14 +7920,31 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
{ "universal8:", ggUniversals[ 8 ] },
|
||||
{ "universal9:", ggUniversals[ 9 ] }
|
||||
};
|
||||
auto lookup = gauges.find( Label );
|
||||
if( lookup != gauges.end() ) {
|
||||
lookup->second.Load( Parser, DynamicObject);
|
||||
m_controlmapper.insert( lookup->second, lookup->first );
|
||||
return true;
|
||||
{
|
||||
auto lookup = gauges.find( Label );
|
||||
if( lookup != gauges.end() ) {
|
||||
lookup->second.Load( Parser, DynamicObject );
|
||||
m_controlmapper.insert( lookup->second, lookup->first );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// TODO: move viable dedicated gauges to the automatic array
|
||||
std::unordered_map<std::string, bool *> const autoboolgauges = {
|
||||
{ "doorstep_sw:", &mvOccupied->Doors.step_enabled }
|
||||
};
|
||||
{
|
||||
auto lookup = autoboolgauges.find( Label );
|
||||
if( lookup != autoboolgauges.end() ) {
|
||||
auto &gauge = Cabine[ Cabindex ].Gauge( -1 ); // pierwsza wolna lampka
|
||||
gauge.Load( Parser, DynamicObject );
|
||||
gauge.AssignBool( lookup->second );
|
||||
m_controlmapper.insert( gauge, lookup->first );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// ABu 090305: uniwersalne przyciski lub inne rzeczy
|
||||
else if( Label == "mainctrlact:" ) {
|
||||
if( Label == "mainctrlact:" ) {
|
||||
ggMainCtrlAct.Load( Parser, DynamicObject);
|
||||
}
|
||||
// SEKCJA WSKAZNIKOW
|
||||
@@ -7997,6 +8134,9 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( Label == "clock_seconds:" ) {
|
||||
ggClockSInd.Load( Parser, DynamicObject );
|
||||
}
|
||||
else if (Label == "evoltage:")
|
||||
{
|
||||
// woltomierz napiecia silnikow
|
||||
|
||||
12
Train.h
12
Train.h
@@ -32,7 +32,7 @@ class TCab {
|
||||
public:
|
||||
// methods
|
||||
void Load(cParser &Parser);
|
||||
void Update();
|
||||
void Update( bool const Power );
|
||||
TGauge &Gauge( int n = -1 ); // pobranie adresu obiektu
|
||||
TButton &Button( int n = -1 ); // pobranie adresu obiektu
|
||||
// members
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
|
||||
private:
|
||||
// members
|
||||
std::vector<TGauge> ggList;
|
||||
std::deque<TGauge> ggList; // need a container which doesn't invalidate references
|
||||
std::vector<TButton> btList;
|
||||
};
|
||||
|
||||
@@ -155,6 +155,7 @@ class TTrain
|
||||
// TBD, TODO: consider this approach if we ever want to have customized consist behaviour to received commands, based on the consist/vehicle type or whatever
|
||||
static void OnCommand_aidriverenable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_aidriverdisable( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_jointcontrollerset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mastercontrollerincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mastercontrollerincreasefast( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_mastercontrollerdecrease( TTrain *Train, command_data const &Command );
|
||||
@@ -315,12 +316,15 @@ class TTrain
|
||||
static void OnCommand_doortoggleright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorpermitleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorpermitright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorpermitpresetactivatenext( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorpermitpresetactivateprevious( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dooropenleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dooropenright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorcloseleft( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorcloseright( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_dooropenall( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorcloseall( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_doorsteptoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_carcouplingincrease( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_carcouplingdisconnect( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_departureannounce( TTrain *Train, command_data const &Command );
|
||||
@@ -369,6 +373,7 @@ public: // reszta może by?publiczna
|
||||
TGauge ggWater1TempB;
|
||||
|
||||
// McZapkie: definicje regulatorow
|
||||
TGauge ggJointCtrl;
|
||||
TGauge ggMainCtrl;
|
||||
TGauge ggMainCtrlAct;
|
||||
TGauge ggScndCtrl;
|
||||
@@ -445,6 +450,7 @@ public: // reszta może by?publiczna
|
||||
// NBMX wrzesien 2003 - obsluga drzwi
|
||||
TGauge ggDoorLeftPermitButton;
|
||||
TGauge ggDoorRightPermitButton;
|
||||
TGauge ggDoorPermitPresetButton;
|
||||
TGauge ggDoorLeftButton;
|
||||
TGauge ggDoorRightButton;
|
||||
TGauge ggDoorLeftOnButton;
|
||||
@@ -517,7 +523,7 @@ public: // reszta może by?publiczna
|
||||
TButton btInstrumentLight;
|
||||
TButton btDashboardLight;
|
||||
TButton btTimetableLight;
|
||||
int InstrumentLightType{ 0 }; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw., 3-rozrzad
|
||||
int InstrumentLightType{ 0 }; // ABu 030405 - swiecenie uzaleznione od: 0-nic, 1-obw.gl, 2-przetw., 3-rozrzad, 4-external lights
|
||||
bool InstrumentLightActive{ false };
|
||||
bool DashboardLightActive{ false };
|
||||
bool TimetableLightActive{ false };
|
||||
|
||||
27
TrkFoll.cpp
27
TrkFoll.cpp
@@ -96,10 +96,6 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
|
||||
// bPrimary=true - jest pierwszą osią w pojeździe, czyli generuje eventy i przepisuje pojazd
|
||||
// Ra: zwraca false, jeśli pojazd ma być usunięty
|
||||
auto const ismoving { ( std::abs( fDistance ) > 0.01 ) && ( Owner->GetVelocity() > 0.01 ) };
|
||||
int const eventfilter { (
|
||||
( ( true == ismoving ) && ( Owner->ctOwner != nullptr ) ) ?
|
||||
Owner->ctOwner->Direction() * ( Owner->ctOwner->Vehicle()->DirectionGet() == Owner->DirectionGet() ? 1 : -1 ) * ( fDirection > 0 ? 1 : -1 ) :
|
||||
0 ) };
|
||||
fDistance *= fDirection; // dystans mnożnony przez kierunek
|
||||
double s; // roboczy dystans
|
||||
double dir; // zapamiętany kierunek do sprawdzenia, czy się zmienił
|
||||
@@ -110,6 +106,13 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
|
||||
// TODO: refactor following block as track method
|
||||
if( pCurrentTrack->m_events ) { // sumaryczna informacja o eventach
|
||||
// omijamy cały ten blok, gdy tor nie ma on żadnych eventów (większość nie ma)
|
||||
int const eventfilter { (
|
||||
false == ismoving ? 0 : // only moving vehicles activate events type 1/2
|
||||
false == bPrimary ? 0 : // only primary axle activates events type 1/2
|
||||
Owner->ctOwner == nullptr ?
|
||||
( fDistance > 0 ? 1 : -1 ) : // loose vehicle has no means to determine 'intended' direction so the filter does effectively nothing in such case
|
||||
( fDirection > 0 ? 1 : -1 ) * Owner->ctOwner->Direction() * ( Owner->ctOwner->Vehicle()->DirectionGet() == Owner->DirectionGet() ? 1 : -1 ) ) };
|
||||
|
||||
if( false == ismoving ) {
|
||||
//McZapkie-140602: wyzwalanie zdarzenia gdy pojazd stoi
|
||||
if( ( Owner->Mechanik != nullptr )
|
||||
@@ -127,16 +130,12 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
|
||||
&& ( Owner->Mechanik->Primary() ) ) {
|
||||
// tylko dla jednego członu
|
||||
// McZapkie-280503: wyzwalanie event tylko dla pojazdow z obsada
|
||||
if( true == bPrimary ) {
|
||||
pCurrentTrack->QueueEvents( pCurrentTrack->m_events1, Owner );
|
||||
}
|
||||
pCurrentTrack->QueueEvents( pCurrentTrack->m_events1, Owner );
|
||||
}
|
||||
}
|
||||
if( SetFlag( iEventallFlag, -1 ) ) {
|
||||
// McZapkie-280503: wyzwalanie eventall dla wszystkich pojazdow
|
||||
if( true == bPrimary ) {
|
||||
pCurrentTrack->QueueEvents( pCurrentTrack->m_events1all, Owner );
|
||||
}
|
||||
pCurrentTrack->QueueEvents( pCurrentTrack->m_events1all, Owner );
|
||||
}
|
||||
}
|
||||
else if( ( fDistance > 0 ) && ( eventfilter > 0 ) ) {
|
||||
@@ -146,16 +145,12 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
|
||||
if( ( Owner->Mechanik != nullptr )
|
||||
&& ( Owner->Mechanik->Primary() ) ) {
|
||||
// tylko dla jednego członu
|
||||
if( true == bPrimary ) {
|
||||
pCurrentTrack->QueueEvents( pCurrentTrack->m_events2, Owner );
|
||||
}
|
||||
pCurrentTrack->QueueEvents( pCurrentTrack->m_events2, Owner );
|
||||
}
|
||||
}
|
||||
if( SetFlag( iEventallFlag, -2 ) ) {
|
||||
// sprawdza i zeruje na przyszłość, true jeśli zmieni z 2 na 0
|
||||
if( true == bPrimary ) {
|
||||
pCurrentTrack->QueueEvents( pCurrentTrack->m_events2all, Owner );
|
||||
}
|
||||
pCurrentTrack->QueueEvents( pCurrentTrack->m_events2all, Owner );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ commanddescription_sequence Commands_descriptions = {
|
||||
|
||||
{ "aidriverenable", command_target::vehicle },
|
||||
{ "aidriverdisable", command_target::vehicle },
|
||||
{ "jointcontrollerset", command_target::vehicle },
|
||||
{ "mastercontrollerincrease", command_target::vehicle },
|
||||
{ "mastercontrollerincreasefast", command_target::vehicle },
|
||||
{ "mastercontrollerdecrease", command_target::vehicle },
|
||||
@@ -144,12 +145,15 @@ commanddescription_sequence Commands_descriptions = {
|
||||
{ "doortoggleright", command_target::vehicle },
|
||||
{ "doorpermitleft", command_target::vehicle },
|
||||
{ "doorpermitright", command_target::vehicle },
|
||||
{ "doorpermitpresetactivatenext", command_target::vehicle },
|
||||
{ "doorpermitpresetactivateprevious", command_target::vehicle },
|
||||
{ "dooropenleft", command_target::vehicle },
|
||||
{ "dooropenright", command_target::vehicle },
|
||||
{ "dooropenall", command_target::vehicle },
|
||||
{ "doorcloseleft", command_target::vehicle },
|
||||
{ "doorcloseright", command_target::vehicle },
|
||||
{ "doorcloseall", command_target::vehicle },
|
||||
{ "doorsteptoggle", command_target::vehicle },
|
||||
{ "departureannounce", command_target::vehicle },
|
||||
{ "doorlocktoggle", command_target::vehicle },
|
||||
{ "pantographcompressorvalvetoggle", command_target::vehicle },
|
||||
|
||||
@@ -16,6 +16,7 @@ enum class user_command {
|
||||
|
||||
aidriverenable,
|
||||
aidriverdisable,
|
||||
jointcontrollerset,
|
||||
mastercontrollerincrease,
|
||||
mastercontrollerincreasefast,
|
||||
mastercontrollerdecrease,
|
||||
@@ -137,12 +138,15 @@ enum class user_command {
|
||||
doortoggleright,
|
||||
doorpermitleft,
|
||||
doorpermitright,
|
||||
doorpermitpresetactivatenext,
|
||||
doorpermitpresetactivateprevious,
|
||||
dooropenleft,
|
||||
dooropenright,
|
||||
dooropenall,
|
||||
doorcloseleft,
|
||||
doorcloseright,
|
||||
doorcloseall,
|
||||
doorsteptoggle,
|
||||
departureannounce,
|
||||
doorlocktoggle,
|
||||
pantographcompressorvalvetoggle,
|
||||
|
||||
@@ -27,6 +27,7 @@ driverkeyboard_input::default_bindings() {
|
||||
m_bindingsetups = {
|
||||
{ user_command::aidriverenable, GLFW_KEY_Q | keymodifier::shift },
|
||||
{ user_command::aidriverdisable, GLFW_KEY_Q },
|
||||
// jointcontrollerset,
|
||||
{ user_command::mastercontrollerincrease, GLFW_KEY_KP_ADD },
|
||||
{ user_command::mastercontrollerincreasefast, GLFW_KEY_KP_ADD | keymodifier::shift },
|
||||
{ user_command::mastercontrollerdecrease, GLFW_KEY_KP_SUBTRACT },
|
||||
@@ -144,11 +145,17 @@ driverkeyboard_input::default_bindings() {
|
||||
{ user_command::carcouplingdisconnect, GLFW_KEY_DELETE },
|
||||
{ user_command::doortoggleleft, GLFW_KEY_COMMA },
|
||||
{ user_command::doortoggleright, GLFW_KEY_PERIOD },
|
||||
{ user_command::doorpermitleft, GLFW_KEY_COMMA | keymodifier::shift },
|
||||
{ user_command::doorpermitright, GLFW_KEY_PERIOD | keymodifier::shift },
|
||||
{ user_command::doorpermitpresetactivatenext, GLFW_KEY_PERIOD | keymodifier::shift | keymodifier::control },
|
||||
{ user_command::doorpermitpresetactivateprevious, GLFW_KEY_COMMA | keymodifier::shift | keymodifier::control },
|
||||
// dooropenleft,
|
||||
// dooropenright,
|
||||
{ user_command::dooropenall, GLFW_KEY_SLASH | keymodifier::shift },
|
||||
// doorcloseleft,
|
||||
// doorcloseright,
|
||||
{ user_command::doorcloseall, GLFW_KEY_SLASH | keymodifier::control },
|
||||
// doorsteptoggle,
|
||||
{ user_command::departureannounce, GLFW_KEY_SLASH },
|
||||
{ user_command::doorlocktoggle, GLFW_KEY_S | keymodifier::control },
|
||||
{ user_command::pantographcompressorvalvetoggle, GLFW_KEY_V | keymodifier::control },
|
||||
@@ -202,8 +209,8 @@ driverkeyboard_input::default_bindings() {
|
||||
{ user_command::instrumentlighttoggle, GLFW_KEY_SEMICOLON },
|
||||
// instrumentlightenable,
|
||||
// instrumentlightdisable,
|
||||
// dashboardlighttoggle,
|
||||
// timetablelighttoggle,
|
||||
{ user_command::dashboardlighttoggle, GLFW_KEY_SEMICOLON | keymodifier::shift },
|
||||
{ user_command::timetablelighttoggle, GLFW_KEY_APOSTROPHE | keymodifier::shift },
|
||||
{ user_command::generictoggle0, GLFW_KEY_0 },
|
||||
{ user_command::generictoggle1, GLFW_KEY_1 },
|
||||
{ user_command::generictoggle2, GLFW_KEY_2 },
|
||||
|
||||
@@ -21,6 +21,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "uilayer.h"
|
||||
#include "Logs.h"
|
||||
|
||||
auto const EU07_CONTROLLER_MOUSESLIDERSIZE{ 0.65 };
|
||||
|
||||
void
|
||||
mouse_slider::bind( user_command const &Command ) {
|
||||
|
||||
@@ -29,6 +31,7 @@ mouse_slider::bind( user_command const &Command ) {
|
||||
auto const *train { simulation::Train };
|
||||
TMoverParameters const *vehicle { nullptr };
|
||||
switch( m_command ) {
|
||||
case user_command::jointcontrollerset:
|
||||
case user_command::mastercontrollerset:
|
||||
case user_command::secondcontrollerset: {
|
||||
vehicle = ( train ? train->Controlled() : nullptr );
|
||||
@@ -47,6 +50,29 @@ mouse_slider::bind( user_command const &Command ) {
|
||||
|
||||
// calculate initial value and accepted range
|
||||
switch( m_command ) {
|
||||
case user_command::jointcontrollerset: {
|
||||
// NOTE: special case, merges two separate controls
|
||||
auto const *occupied { train ? train->Occupied() : nullptr };
|
||||
if( occupied == nullptr ) { return; }
|
||||
|
||||
auto const powerrange { static_cast<double>(
|
||||
vehicle->CoupledCtrl ?
|
||||
vehicle->MainCtrlPosNo + vehicle->ScndCtrlPosNo :
|
||||
vehicle->MainCtrlPosNo ) };
|
||||
// for simplicity upper half of the range controls power, lower controls brakes
|
||||
auto const brakerangemultiplier { powerrange / LocalBrakePosNo };
|
||||
|
||||
m_valuerange = 1.0;
|
||||
m_value =
|
||||
0.5
|
||||
+ 0.5 * ( vehicle->CoupledCtrl ?
|
||||
vehicle->MainCtrlPos + vehicle->ScndCtrlPos :
|
||||
vehicle->MainCtrlPos ) / powerrange
|
||||
- 0.5 * occupied->LocalBrakePosA;
|
||||
m_analogue = true;
|
||||
m_invertrange = false;
|
||||
break;
|
||||
}
|
||||
case user_command::mastercontrollerset: {
|
||||
m_valuerange = (
|
||||
vehicle->CoupledCtrl ?
|
||||
@@ -57,24 +83,28 @@ mouse_slider::bind( user_command const &Command ) {
|
||||
vehicle->MainCtrlPos + vehicle->ScndCtrlPos :
|
||||
vehicle->MainCtrlPos );
|
||||
m_analogue = false;
|
||||
m_invertrange = false;
|
||||
break;
|
||||
}
|
||||
case user_command::secondcontrollerset: {
|
||||
m_valuerange = vehicle->ScndCtrlPosNo;
|
||||
m_value = vehicle->ScndCtrlPos;
|
||||
m_analogue = false;
|
||||
m_invertrange = true;
|
||||
break;
|
||||
}
|
||||
case user_command::trainbrakeset: {
|
||||
m_valuerange = 1.0;
|
||||
m_value = ( vehicle->fBrakeCtrlPos - vehicle->Handle->GetPos( bh_MIN ) ) / ( vehicle->Handle->GetPos( bh_MAX ) - vehicle->Handle->GetPos( bh_MIN ) );
|
||||
m_analogue = true;
|
||||
m_invertrange = true;
|
||||
break;
|
||||
}
|
||||
case user_command::independentbrakeset: {
|
||||
m_valuerange = 1.0;
|
||||
m_value = vehicle->LocalBrakePosA;
|
||||
m_analogue = true;
|
||||
m_invertrange = true;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -86,14 +116,18 @@ mouse_slider::bind( user_command const &Command ) {
|
||||
Application.get_cursor_pos( m_cursorposition.x, m_cursorposition.y );
|
||||
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||
|
||||
auto const controlsize { Global.iWindowHeight * 0.75 };
|
||||
auto const controlsize { Global.iWindowHeight * EU07_CONTROLLER_MOUSESLIDERSIZE };
|
||||
auto const controledge { Global.iWindowHeight * 0.5 + controlsize * 0.5 };
|
||||
auto const stepsize { controlsize / m_valuerange };
|
||||
|
||||
if( m_invertrange ) {
|
||||
m_value = ( m_analogue ? 1.0 : m_valuerange ) - m_value;
|
||||
}
|
||||
|
||||
Application.set_cursor_pos(
|
||||
Global.iWindowWidth * 0.5,
|
||||
( m_analogue ?
|
||||
controledge - ( 1.0 - m_value ) * controlsize :
|
||||
controledge - m_value * controlsize :
|
||||
controledge - m_value * stepsize - 0.5 * stepsize ) );
|
||||
}
|
||||
|
||||
@@ -108,15 +142,17 @@ mouse_slider::release() {
|
||||
void
|
||||
mouse_slider::on_move( double const Mousex, double const Mousey ) {
|
||||
|
||||
auto const controlsize { Global.iWindowHeight * 0.75 };
|
||||
auto const controlsize { Global.iWindowHeight * EU07_CONTROLLER_MOUSESLIDERSIZE };
|
||||
auto const controledge { Global.iWindowHeight * 0.5 + controlsize * 0.5 };
|
||||
auto const stepsize { controlsize / m_valuerange };
|
||||
|
||||
auto mousey = clamp( Mousey, controledge - controlsize, controledge );
|
||||
m_value = (
|
||||
m_analogue ?
|
||||
1.0 - ( ( controledge - mousey ) / controlsize ) :
|
||||
( controledge - mousey ) / controlsize :
|
||||
std::floor( ( controledge - mousey ) / stepsize ) );
|
||||
if( m_invertrange ) {
|
||||
m_value = ( m_analogue ? 1.0 : m_valuerange ) - m_value; }
|
||||
}
|
||||
|
||||
|
||||
@@ -370,6 +406,7 @@ drivermouse_input::button( int const Button, int const Action ) {
|
||||
m_varyingpollrate = true;
|
||||
break;
|
||||
}
|
||||
case user_command::jointcontrollerset:
|
||||
case user_command::mastercontrollerset:
|
||||
case user_command::secondcontrollerset:
|
||||
case user_command::trainbrakeset:
|
||||
@@ -445,6 +482,9 @@ void
|
||||
drivermouse_input::default_bindings() {
|
||||
|
||||
m_buttonbindings = {
|
||||
{ "jointctrl:", {
|
||||
user_command::jointcontrollerset,
|
||||
user_command::none } },
|
||||
{ "mainctrl:", {
|
||||
user_command::mastercontrollerset,
|
||||
user_command::none } },
|
||||
@@ -557,6 +597,9 @@ drivermouse_input::default_bindings() {
|
||||
{ "doorrightpermit_sw:", {
|
||||
user_command::doorpermitright,
|
||||
user_command::none } },
|
||||
{ "doorpermitpreset_sw:", {
|
||||
user_command::doorpermitpresetactivatenext,
|
||||
user_command::doorpermitpresetactivateprevious } },
|
||||
{ "door_left_sw:", {
|
||||
user_command::doortoggleleft,
|
||||
user_command::none } },
|
||||
@@ -581,6 +624,9 @@ drivermouse_input::default_bindings() {
|
||||
{ "dooralloff_sw:", {
|
||||
user_command::doorcloseall,
|
||||
user_command::none } },
|
||||
{ "doorstep_sw:", {
|
||||
user_command::doorsteptoggle,
|
||||
user_command::none } },
|
||||
{ "departure_signal_bt:", {
|
||||
user_command::departureannounce,
|
||||
user_command::none } },
|
||||
|
||||
@@ -39,6 +39,7 @@ private:
|
||||
double m_value { 0.0 };
|
||||
double m_valuerange { 0.0 };
|
||||
bool m_analogue { false };
|
||||
bool m_invertrange { false };
|
||||
glm::dvec2 m_cursorposition { 0.0 };
|
||||
};
|
||||
|
||||
|
||||
@@ -207,29 +207,45 @@ timetable_panel::update() {
|
||||
auto textline = " -> " + nextstation;
|
||||
|
||||
text_lines.emplace_back( textline, Global.UITextColor );
|
||||
text_lines.emplace_back( "", Global.UITextColor );
|
||||
}
|
||||
}
|
||||
|
||||
if( is_expanded ) {
|
||||
|
||||
text_lines.emplace_back( "", Global.UITextColor );
|
||||
if( vehicle->MoverParameters->CategoryFlag == 1 ) {
|
||||
// consist data
|
||||
auto consistmass { owner->fMass };
|
||||
auto consistlength { owner->fLength };
|
||||
if( ( owner->mvControlling->TrainType != dt_DMU )
|
||||
&& ( owner->mvControlling->TrainType != dt_EZT ) ) {
|
||||
//odejmij lokomotywy czynne, a przynajmniej aktualną
|
||||
consistmass -= owner->pVehicle->MoverParameters->TotalMass;
|
||||
// subtract potential other half of a two-part vehicle
|
||||
auto const *previous { owner->pVehicle->PrevC( coupling::permanent ) };
|
||||
if( previous != nullptr ) { consistmass -= previous->MoverParameters->TotalMass; }
|
||||
auto const *next { owner->pVehicle->NextC( coupling::permanent ) };
|
||||
if( next != nullptr ) { consistmass -= next->MoverParameters->TotalMass; }
|
||||
}
|
||||
std::snprintf(
|
||||
m_buffer.data(), m_buffer.size(),
|
||||
locale::strings[ locale::string::driver_timetable_consistdata ].c_str(),
|
||||
static_cast<int>( table->LocLoad ),
|
||||
static_cast<int>( consistmass / 1000 ),
|
||||
static_cast<int>( consistlength ) );
|
||||
|
||||
text_lines.emplace_back( m_buffer.data(), Global.UITextColor );
|
||||
text_lines.emplace_back( "", Global.UITextColor );
|
||||
}
|
||||
|
||||
if( 0 == table->StationCount ) {
|
||||
// only bother if there's stations to list
|
||||
text_lines.emplace_back( locale::strings[ locale::string::driver_timetable_notimetable ], Global.UITextColor );
|
||||
}
|
||||
else {
|
||||
|
||||
auto const readycolor { glm::vec4( 84.0f / 255.0f, 164.0f / 255.0f, 132.0f / 255.0f, 1.f ) };
|
||||
|
||||
text_lines.emplace_back("Brutto rozkl. " + to_string(table->LocLoad), Global.UITextColor);
|
||||
auto fMass = owner->fMass / 1000;
|
||||
if (owner->mvControlling->TrainType & (dt_DMU + dt_EZT) == 0)
|
||||
{
|
||||
//odejmij lokomotywy czynne, a przynajmniej aktualną
|
||||
}
|
||||
text_lines.emplace_back("Brutto rzecz. " + to_string(fMass,0), Global.UITextColor);
|
||||
text_lines.emplace_back("Dl.poc. rzecz. " + to_string(owner->fLength,0), Global.UITextColor);
|
||||
|
||||
// header
|
||||
text_lines.emplace_back( "+-----+------------------------------------+-------+-----+", Global.UITextColor );
|
||||
|
||||
@@ -545,10 +561,7 @@ debug_panel::update_vehicle_coupler( int const Side ) {
|
||||
// NOTE: mover and vehicle are guaranteed to be valid by the caller
|
||||
std::string couplerstatus { locale::strings[ locale::string::debug_vehicle_none ] };
|
||||
|
||||
auto const *connected { (
|
||||
Side == end::front ?
|
||||
m_input.vehicle->PrevConnected :
|
||||
m_input.vehicle->NextConnected ) };
|
||||
auto const *connected { m_input.vehicle->MoverParameters->Neighbours[ Side ].vehicle };
|
||||
|
||||
if( connected == nullptr ) { return couplerstatus; }
|
||||
|
||||
@@ -556,10 +569,10 @@ debug_panel::update_vehicle_coupler( int const Side ) {
|
||||
|
||||
std::snprintf(
|
||||
m_buffer.data(), m_buffer.size(),
|
||||
"%s [%d]%s",
|
||||
"%s [%d] (%.1f m)",
|
||||
connected->name().c_str(),
|
||||
mover.Couplers[ Side ].CouplingFlag,
|
||||
std::string( mover.Couplers[ Side ].CouplingFlag == 0 ? " (" + to_string( mover.Couplers[ Side ].CoupleDist, 1 ) + " m)" : "" ).c_str() );
|
||||
mover.Neighbours[ Side ].distance );
|
||||
|
||||
return { m_buffer.data() };
|
||||
}
|
||||
@@ -682,6 +695,12 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
|
||||
"Distances:\n proximity: " + to_string( mechanik.ActualProximityDist, 0 )
|
||||
+ ", braking: " + to_string( mechanik.fBrakeDist, 0 );
|
||||
|
||||
if( mechanik.Obstacle.distance < 5000 ) {
|
||||
textline +=
|
||||
"\n obstacle: " + to_string( mechanik.Obstacle.distance, 0 )
|
||||
+ " (" + mechanik.Obstacle.vehicle->asName + ")";
|
||||
}
|
||||
|
||||
Output.emplace_back( textline, Global.UITextColor );
|
||||
|
||||
// velocity factors
|
||||
|
||||
@@ -174,6 +174,7 @@ opengl_vbogeometrybank::draw_( gfx::geometry_handle const &Geometry, gfx::stream
|
||||
// try to set up the buffer we need
|
||||
::glGenBuffers( 1, &m_buffer );
|
||||
bind_buffer();
|
||||
if( m_buffer == 0 ) { return; } // if we didn't get a buffer we'll try again during the next draw call
|
||||
// NOTE: we're using static_draw since it's generally true for all we have implemented at the moment
|
||||
// TODO: allow to specify usage hint at the object creation, and pass it here
|
||||
::glBufferData(
|
||||
|
||||
@@ -49,10 +49,12 @@ bounding_area::serialize( std::ostream &Output ) const {
|
||||
|
||||
// restores content of the struct from provided input stream
|
||||
void
|
||||
bounding_area::deserialize( std::istream &Input ) {
|
||||
bounding_area::deserialize( std::istream &Input, bool const Preserveradius ) {
|
||||
|
||||
center = sn_utils::d_dvec3( Input );
|
||||
radius = sn_utils::ld_float32( Input );
|
||||
radius = ( Preserveradius ?
|
||||
std::max( radius, sn_utils::ld_float32( Input ) ) :
|
||||
sn_utils::ld_float32( Input ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -59,9 +59,9 @@ struct bounding_area {
|
||||
// stores content of the struct in provided output stream
|
||||
void
|
||||
serialize( std::ostream &Output ) const;
|
||||
// restores content of the struct from provided input stream
|
||||
// restores content of the struct from provided input stream.
|
||||
void
|
||||
deserialize( std::istream &Input );
|
||||
deserialize( std::istream &Input, bool const Preserveradius = true );
|
||||
};
|
||||
|
||||
//using group_handle = std::size_t;
|
||||
|
||||
@@ -59,7 +59,7 @@ basic_station::update_load( TDynamicObject *First, Mtable::TTrainParameters &Sch
|
||||
firststop ? 0 :
|
||||
std::min<float>(
|
||||
parameters.LoadAmount,
|
||||
Random( parameters.MaxLoad * 0.10 * stationsizemodifier ) ) );
|
||||
Random( parameters.MaxLoad * 0.15f * stationsizemodifier ) ) );
|
||||
auto loadcount = static_cast<int>(
|
||||
laststop ?
|
||||
0 :
|
||||
|
||||
@@ -41,6 +41,7 @@ init() {
|
||||
"Timetable",
|
||||
"Time: %d:%02d:%02d",
|
||||
"(no timetable)",
|
||||
"Consist weight: %d t (specified) %d t (actual)\nConsist length: %d m",
|
||||
|
||||
"Transcripts",
|
||||
|
||||
@@ -61,6 +62,7 @@ init() {
|
||||
" pantograph: %.2f%cMT",
|
||||
"Forces:\n tractive: %.1f, brake: %.1f, friction: %.2f%s\nAcceleration:\n tangential: %.2f, normal: %.2f (path radius: %s)\nVelocity: %.2f, distance traveled: %.2f\nPosition: [%.2f, %.2f, %.2f]",
|
||||
|
||||
"master controller",
|
||||
"master controller",
|
||||
"second controller",
|
||||
"shunt mode power",
|
||||
@@ -97,16 +99,18 @@ init() {
|
||||
"motor overload relay reset",
|
||||
"converter overload relay reset",
|
||||
"motor connectors",
|
||||
"left door (permit)",
|
||||
"right door (permit)",
|
||||
"door (permit)",
|
||||
"left door",
|
||||
"right door",
|
||||
"left door",
|
||||
"right door",
|
||||
"left door",
|
||||
"right door",
|
||||
"left door",
|
||||
"right door",
|
||||
"all doors",
|
||||
"all doors",
|
||||
"left door (open)",
|
||||
"right door (open)",
|
||||
"left door (close)",
|
||||
"right door (close)",
|
||||
"all doors (open)",
|
||||
"all doors (close)",
|
||||
"doorstep",
|
||||
"departure signal",
|
||||
"upper headlight",
|
||||
"left headlight",
|
||||
@@ -182,6 +186,7 @@ init() {
|
||||
"Rozklad jazdy",
|
||||
"Godzina: %d:%02d:%02d",
|
||||
"(brak rozkladu)",
|
||||
"Brutto: %d t (rozkladowe) %d t (rzeczywiste)\nDlugosc pociagu: %d m",
|
||||
|
||||
"Transkrypcje",
|
||||
|
||||
@@ -202,6 +207,7 @@ init() {
|
||||
" pantograf: %.2f%cZG",
|
||||
"Sily:\n napedna: %.1f, hamowania: %.1f, tarcie: %.2f%s\nPrzyspieszenia:\n styczne: %.2f, normalne: %.2f (promien: %s)\nPredkosc: %.2f, pokonana odleglosc: %.2f\nPozycja: [%.2f, %.2f, %.2f]",
|
||||
|
||||
"nastawnik jazdy",
|
||||
"nastawnik jazdy",
|
||||
"nastawnik dodatkowy",
|
||||
"sterowanie analogowe",
|
||||
@@ -238,16 +244,18 @@ init() {
|
||||
"przekaznik nadmiarowy silnikow trakcyjnych",
|
||||
"przekaznik nadmiarowy przetwornicy",
|
||||
"styczniki liniowe",
|
||||
"drzwi lewe (zezwol)",
|
||||
"drzwi prawe (zezwol)",
|
||||
"drzwi (zezwol)",
|
||||
"drzwi lewe",
|
||||
"drzwi prawe",
|
||||
"drzwi lewe",
|
||||
"drzwi prawe",
|
||||
"drzwi lewe",
|
||||
"drzwi prawe",
|
||||
"drzwi lewe",
|
||||
"drzwi prawe",
|
||||
"drzwi",
|
||||
"drzwi",
|
||||
"drzwi lewe (otworz)",
|
||||
"drzwi prawe (otworz)",
|
||||
"drzwi lewe (zamknij)",
|
||||
"drzwi prawe (zamknij)",
|
||||
"drzwi (otworz)",
|
||||
"drzwi (zamknij)",
|
||||
"stopien drzwi",
|
||||
"sygnal odjazdu",
|
||||
"reflektor gorny",
|
||||
"reflektor lewy",
|
||||
@@ -316,6 +324,7 @@ init() {
|
||||
{
|
||||
std::vector<std::string> cabcontrols = {
|
||||
"mainctrl:",
|
||||
"jointctrl:",
|
||||
"scndctrl:",
|
||||
"shuntmodepower:",
|
||||
"dirkey:",
|
||||
@@ -353,6 +362,7 @@ init() {
|
||||
"stlinoff_bt:",
|
||||
"doorleftpermit_sw:",
|
||||
"doorrightpermit_sw:",
|
||||
"doorpermitpreset_sw:",
|
||||
"door_left_sw:",
|
||||
"door_right_sw:",
|
||||
"doorlefton_sw:",
|
||||
@@ -361,6 +371,7 @@ init() {
|
||||
"doorrightoff_sw:",
|
||||
"doorallon_sw:",
|
||||
"dooralloff_sw:",
|
||||
"doorstep_sw:",
|
||||
"departure_signal_bt:",
|
||||
"upperlight_sw:",
|
||||
"leftlight_sw:",
|
||||
|
||||
@@ -30,6 +30,7 @@ enum string {
|
||||
driver_timetable_header,
|
||||
driver_timetable_time,
|
||||
driver_timetable_notimetable,
|
||||
driver_timetable_consistdata,
|
||||
|
||||
driver_transcripts_header,
|
||||
|
||||
@@ -51,6 +52,7 @@ enum string {
|
||||
debug_vehicle_forcesaccelerationvelocityposition,
|
||||
|
||||
cab_mainctrl,
|
||||
cab_jointctrl,
|
||||
cab_scndctrl,
|
||||
cab_shuntmodepower,
|
||||
cab_dirkey,
|
||||
@@ -88,6 +90,7 @@ enum string {
|
||||
cab_stlinoff_bt,
|
||||
cab_doorleftpermit_sw,
|
||||
cab_doorrightpermit_sw,
|
||||
cab_doorpermitpreset_sw,
|
||||
cab_door_left_sw,
|
||||
cab_door_right_sw,
|
||||
cab_doorlefton_sw,
|
||||
@@ -96,6 +99,7 @@ enum string {
|
||||
cab_doorrightoff_sw,
|
||||
cab_doorallon_sw,
|
||||
cab_dooralloff_sw,
|
||||
cab_doorstep_sw,
|
||||
cab_departure_signal_bt,
|
||||
cab_upperlight_sw,
|
||||
cab_leftlight_sw,
|
||||
|
||||
Reference in New Issue
Block a user