16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 23:49:17 +02:00

Merge branch 'tmj-dev' into milek-dev

This commit is contained in:
milek7
2018-09-20 22:00:02 +02:00
39 changed files with 2997 additions and 2171 deletions

View File

@@ -404,7 +404,7 @@ bool TAnimContainer::InMovement()
return (fRotateSpeed != 0.0) || (fTranslateSpeed != 0.0); return (fRotateSpeed != 0.0) || (fTranslateSpeed != 0.0);
} }
void TAnimContainer::EventAssign(TEvent *ev) void TAnimContainer::EventAssign(basic_event *ev)
{ // przypisanie eventu wykonywanego po zakończeniu animacji { // przypisanie eventu wykonywanego po zakończeniu animacji
evDone = ev; evDone = ev;
}; };

View File

@@ -43,7 +43,7 @@ class TAnimVocaloidFrame
char cBezier[64]; // krzywe Béziera do interpolacji dla x,y,z i obrotu char cBezier[64]; // krzywe Béziera do interpolacji dla x,y,z i obrotu
}; };
class TEvent; class basic_event;
class TAnimContainer class TAnimContainer
{ // opakowanie submodelu, określające animację egzemplarza - obsługiwane jako lista { // opakowanie submodelu, określające animację egzemplarza - obsługiwane jako lista
@@ -73,7 +73,7 @@ class TAnimContainer
{ // mogą być animacje klatkowe różnego typu, wskaźniki używa AnimModel { // mogą być animacje klatkowe różnego typu, wskaźniki używa AnimModel
TAnimVocaloidFrame *pMovementData; // wskaźnik do klatki TAnimVocaloidFrame *pMovementData; // wskaźnik do klatki
}; };
TEvent *evDone; // ewent wykonywany po zakończeniu animacji, np. zapór, obrotnicy basic_event *evDone; // ewent wykonywany po zakończeniu animacji, np. zapór, obrotnicy
public: public:
TAnimContainer *pNext; TAnimContainer *pNext;
TAnimContainer *acAnimNext; // lista animacji z eventem, które muszą być przeliczane również bez TAnimContainer *acAnimNext; // lista animacji z eventem, które muszą być przeliczane również bez
@@ -101,9 +101,9 @@ class TAnimContainer
void WillBeAnimated() { void WillBeAnimated() {
if (pSubModel) if (pSubModel)
pSubModel->WillBeAnimated(); }; pSubModel->WillBeAnimated(); };
void EventAssign(TEvent *ev); void EventAssign(basic_event *ev);
inline inline
TEvent * Event() { basic_event * Event() {
return evDone; }; return evDone; };
}; };

View File

@@ -14,7 +14,7 @@ http://mozilla.org/MPL/2.0/.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
class opengl_renderer; class opengl_renderer;
class TTrack; // odcinek trajektorii class TTrack; // odcinek trajektorii
class TEvent; class basic_event;
class TTrain; // pojazd sterowany class TTrain; // pojazd sterowany
class TDynamicObject; // pojazd w scenerii class TDynamicObject; // pojazd w scenerii
struct material_data; struct material_data;

View File

@@ -36,22 +36,22 @@ http://mozilla.org/MPL/2.0/.
// finds point of specified track nearest to specified event. returns: distance to that point from the specified end of the track // finds point of specified track nearest to specified event. returns: distance to that point from the specified end of the track
// TODO: move this to file with all generic routines, too easy to forget it's here and it may come useful // TODO: move this to file with all generic routines, too easy to forget it's here and it may come useful
double double
ProjectEventOnTrack( TEvent const *Event, TTrack const *Track, double const Direction ) { ProjectEventOnTrack( basic_event const *Event, TTrack const *Track, double const Direction ) {
auto const segment = Track->CurrentSegment(); auto const segment = Track->CurrentSegment();
auto const nearestpoint = segment->find_nearest_point( Event->PositionGet() ); auto const nearestpoint = segment->find_nearest_point( Event->input_location() );
return ( return (
Direction > 0 ? Direction > 0 ?
nearestpoint * segment->GetLength() : // measure from point1 nearestpoint * segment->GetLength() : // measure from point1
( 1.0 - nearestpoint ) * segment->GetLength() ); // measure from point2 ( 1.0 - nearestpoint ) * segment->GetLength() ); // measure from point2
}; };
double GetDistanceToEvent(TTrack const *track, TEvent const *event, double scan_dir, double start_dist, int iter = 0, bool back = false) double GetDistanceToEvent(TTrack const *track, basic_event const *event, double scan_dir, double start_dist, int iter = 0, bool back = false)
{ {
if( track == nullptr ) { return start_dist; } if( track == nullptr ) { return start_dist; }
auto const segment = track->CurrentSegment(); auto const segment = track->CurrentSegment();
auto const pos_event = event->PositionGet(); auto const pos_event = event->input_location();
double len1, len2; double len1, len2;
double sd = scan_dir; double sd = scan_dir;
double seg_len = scan_dir > 0 ? 0.0 : 1.0; double seg_len = scan_dir > 0 ? 0.0 : 1.0;
@@ -178,7 +178,7 @@ TSpeedPos::TSpeedPos(TTrack *track, double dist, int flag)
Set(track, dist, flag); Set(track, dist, flag);
}; };
TSpeedPos::TSpeedPos(TEvent *event, double dist, TOrders order) TSpeedPos::TSpeedPos(basic_event *event, double dist, TOrders order)
{ {
Set(event, dist, order); Set(event, dist, order);
}; };
@@ -195,9 +195,9 @@ void TSpeedPos::Clear()
void TSpeedPos::CommandCheck() void TSpeedPos::CommandCheck()
{ // sprawdzenie typu komendy w evencie i określenie prędkości { // sprawdzenie typu komendy w evencie i określenie prędkości
TCommandType command = evEvent->Command(); TCommandType command = evEvent->input_command();
double value1 = evEvent->ValueGet(1); double value1 = evEvent->input_value(1);
double value2 = evEvent->ValueGet(2); double value2 = evEvent->input_value(2);
switch (command) switch (command)
{ {
case TCommandType::cm_ShuntVelocity: case TCommandType::cm_ShuntVelocity:
@@ -323,7 +323,7 @@ std::string TSpeedPos::GetName() const
if (iFlags & spTrack) // jeśli tor if (iFlags & spTrack) // jeśli tor
return trTrack->name(); return trTrack->name();
else if( iFlags & spEvent ) // jeśli event else if( iFlags & spEvent ) // jeśli event
return evEvent->asName; return evEvent->m_name;
else else
return ""; return "";
} }
@@ -355,12 +355,12 @@ bool TSpeedPos::IsProperSemaphor(TOrders order)
return false; // true gdy zatrzymanie, wtedy nie ma po co skanować dalej return false; // true gdy zatrzymanie, wtedy nie ma po co skanować dalej
} }
bool TSpeedPos::Set(TEvent *event, double dist, TOrders order) bool TSpeedPos::Set(basic_event *event, double dist, TOrders order)
{ // zapamiętanie zdarzenia { // zapamiętanie zdarzenia
fDist = dist; fDist = dist;
iFlags = spEnabled | spEvent; // event+istotny iFlags = spEnabled | spEvent; // event+istotny
evEvent = event; evEvent = event;
vPos = event->PositionGet(); // współrzędne eventu albo komórki pamięci (zrzutować na tor?) vPos = event->input_location(); // współrzędne eventu albo komórki pamięci (zrzutować na tor?)
CommandCheck(); // sprawdzenie typu komendy w evencie i określenie prędkości 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 // zależnie od trybu sprawdzenie czy jest tutaj gdzieś semafor lub tarcza manewrowa
// jeśli wskazuje stop wtedy wystawiamy true jako koniec sprawdzania // jeśli wskazuje stop wtedy wystawiamy true jako koniec sprawdzania
@@ -418,13 +418,13 @@ void TController::TableClear()
eSignSkip = nullptr; // nic nie pomijamy eSignSkip = nullptr; // nic nie pomijamy
}; };
std::vector<TEvent *> TController::CheckTrackEvent( TTrack *Track, double const fDirection ) const std::vector<basic_event *> TController::CheckTrackEvent( TTrack *Track, double const fDirection ) const
{ // sprawdzanie eventów na podanym torze do podstawowego skanowania { // sprawdzanie eventów na podanym torze do podstawowego skanowania
std::vector<TEvent *> events; std::vector<basic_event *> events;
auto const &eventsequence { ( fDirection > 0 ? Track->m_events2 : Track->m_events1 ) }; auto const &eventsequence { ( fDirection > 0 ? Track->m_events2 : Track->m_events1 ) };
for( auto const &event : eventsequence ) { for( auto const &event : eventsequence ) {
if( ( event.second != nullptr ) if( ( event.second != nullptr )
&& ( false == event.second->bEnabled ) ) { && ( event.second->m_passive ) ) {
events.emplace_back( event.second ); events.emplace_back( event.second );
} }
} }
@@ -438,7 +438,7 @@ bool TController::TableAddNew()
return true; // false gdy się nałoży return true; // false gdy się nałoży
}; };
bool TController::TableNotFound(TEvent const *Event) const bool TController::TableNotFound(basic_event const *Event) const
{ // sprawdzenie, czy nie został już dodany do tabelki (np. podwójne W4 robi problemy) { // sprawdzenie, czy nie został już dodany do tabelki (np. podwójne W4 robi problemy)
auto lookup = auto lookup =
std::find_if( std::find_if(
@@ -450,7 +450,7 @@ bool TController::TableNotFound(TEvent const *Event) const
if( ( Global.iWriteLogEnabled & 8 ) if( ( Global.iWriteLogEnabled & 8 )
&& ( lookup != sSpeedTable.end() ) ) { && ( lookup != sSpeedTable.end() ) ) {
WriteLog( "Speed table for " + OwnerName() + " already contains event " + lookup->evEvent->asName ); WriteLog( "Speed table for " + OwnerName() + " already contains event " + lookup->evEvent->m_name );
} }
return lookup == sSpeedTable.end(); return lookup == sSpeedTable.end();
@@ -555,7 +555,7 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
TableAddNew(); // zawsze jest true TableAddNew(); // zawsze jest true
if (Global.iWriteLogEnabled & 8) { if (Global.iWriteLogEnabled & 8) {
WriteLog("Speed table for " + OwnerName() + " found new event, " + pEvent->asName); WriteLog("Speed table for " + OwnerName() + " found new event, " + pEvent->m_name);
} }
auto &newspeedpoint = sSpeedTable[iLast]; auto &newspeedpoint = sSpeedTable[iLast];
/* /*
@@ -785,7 +785,7 @@ void TController::TableCheck(double fDistance)
else if (sSpeedTable[i].iFlags & spEvent) // jeśli event else if (sSpeedTable[i].iFlags & spEvent) // jeśli event
{ {
if (sSpeedTable[i].fDist < ( if (sSpeedTable[i].fDist < (
sSpeedTable[i].evEvent->Type == tp_PutValues ? typeid( *(sSpeedTable[i].evEvent) ) == typeid( putvalues_event ) ?
-fLength : -fLength :
0)) // jeśli jest z tyłu 0)) // jeśli jest z tyłu
if ((mvOccupied->CategoryFlag & 1) ? false : if ((mvOccupied->CategoryFlag & 1) ? false :
@@ -837,13 +837,13 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// stop points are irrelevant when not in one of the basic modes // stop points are irrelevant when not in one of the basic modes
if( ( OrderCurrentGet() & ( Obey_train | Shunt ) ) == 0 ) { continue; } if( ( OrderCurrentGet() & ( Obey_train | Shunt ) ) == 0 ) { continue; }
// first 19 chars of the command is expected to be "PassengerStopPoint:" so we skip them // first 19 chars of the command is expected to be "PassengerStopPoint:" so we skip them
if ( ToLower(sSpeedTable[i].evEvent->CommandGet()).compare( 19, sizeof(asNextStop), ToLower(asNextStop)) != 0 ) if ( ToLower(sSpeedTable[i].evEvent->input_text()).compare( 19, sizeof(asNextStop), ToLower(asNextStop)) != 0 )
{ // jeśli nazwa nie jest zgodna { // jeśli nazwa nie jest zgodna
if (sSpeedTable[i].fDist < 300.0 && sSpeedTable[i].fDist > 0) // tylko jeśli W4 jest blisko, przy dwóch może zaczać szaleć if (sSpeedTable[i].fDist < 300.0 && sSpeedTable[i].fDist > 0) // tylko jeśli W4 jest blisko, przy dwóch może zaczać szaleć
{ {
// porównuje do następnej stacji, więc trzeba przewinąć do poprzedniej // porównuje do następnej stacji, więc trzeba przewinąć do poprzedniej
// nastepnie ustawić następną na aktualną tak żeby prawidłowo ją obsłużył w następnym kroku // nastepnie ustawić następną na aktualną tak żeby prawidłowo ją obsłużył w następnym kroku
if( true == TrainParams->RewindTimeTable( sSpeedTable[ i ].evEvent->CommandGet() ) ) { if( true == TrainParams->RewindTimeTable( sSpeedTable[ i ].evEvent->input_text() ) ) {
asNextStop = TrainParams->NextStop(); asNextStop = TrainParams->NextStop();
iStationStart = TrainParams->StationIndex; iStationStart = TrainParams->StationIndex;
} }
@@ -892,8 +892,8 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
Drugi paramer dodatni - długość peronu (W4). Drugi paramer dodatni - długość peronu (W4).
*/ */
auto L = 0.0; auto L = 0.0;
auto Par1 = sSpeedTable[i].evEvent->ValueGet(1); auto Par1 = sSpeedTable[i].evEvent->input_value(1);
auto Par2 = sSpeedTable[i].evEvent->ValueGet(2); auto Par2 = sSpeedTable[i].evEvent->input_value(2);
if ((Par2 >= 0) || (fLength < -Par2)) { //użyj tego W4 if ((Par2 >= 0) || (fLength < -Par2)) { //użyj tego W4
if (Par1 < 0) { if (Par1 < 0) {
L = -Par1; L = -Par1;
@@ -919,7 +919,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
&& ( ( iDrivigFlags & moveStopCloser ) != 0 ? && ( ( iDrivigFlags & moveStopCloser ) != 0 ?
sSpeedTable[ i ].fDist + fLength <= sSpeedTable[ i ].fDist + fLength <=
std::max( std::max(
std::abs( sSpeedTable[ i ].evEvent->ValueGet( 2 ) ), std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ),
2.0 * fMaxProximityDist + fLength ) : // fmaxproximitydist typically equals ~50 m 2.0 * fMaxProximityDist + fLength ) : // fmaxproximitydist typically equals ~50 m
sSpeedTable[ i ].fDist < d_to_next_sem ) ); sSpeedTable[ i ].fDist < d_to_next_sem ) );
@@ -940,7 +940,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
if( ( iDrivigFlags & moveDoorOpened ) == 0 ) { if( ( iDrivigFlags & moveDoorOpened ) == 0 ) {
// drzwi otwierać jednorazowo // drzwi otwierać jednorazowo
iDrivigFlags |= moveDoorOpened; // nie wykonywać drugi raz iDrivigFlags |= moveDoorOpened; // nie wykonywać drugi raz
Doors( true, static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->ValueGet( 2 ) ) ) ) % 10 ); Doors( true, static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ) ) ) % 10 );
} }
if (TrainParams->UpdateMTable( simulation::Time, asNextStop) ) { if (TrainParams->UpdateMTable( simulation::Time, asNextStop) ) {
@@ -952,7 +952,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
} }
// perform loading/unloading // perform loading/unloading
auto const platformside = static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->ValueGet( 2 ) ) ) ) % 10; auto const platformside = static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->input_value( 2 ) ) ) ) % 10;
auto const exchangetime = simulation::Station.update_load( pVehicles[ 0 ], *TrainParams, platformside ); auto const exchangetime = simulation::Station.update_load( pVehicles[ 0 ], *TrainParams, platformside );
WaitingSet( std::max( -fStopTime, exchangetime ) ); // na końcu rozkładu się ustawia 60s i tu by było skrócenie WaitingSet( std::max( -fStopTime, exchangetime ) ); // na końcu rozkładu się ustawia 60s i tu by było skrócenie
@@ -1021,7 +1021,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// NOTE: this calculation is expected to run after completing loading/unloading // NOTE: this calculation is expected to run after completing loading/unloading
AutoRewident(); // nastawianie hamulca do jazdy pociągowej AutoRewident(); // nastawianie hamulca do jazdy pociągowej
if( static_cast<int>( std::floor( std::abs( sSpeedTable[ i ].evEvent->ValueGet( 1 ) ) ) ) % 2 ) { 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 // nie podjeżdżać do semafora, jeśli droga nie jest wolna
iDrivigFlags |= moveStopHere; iDrivigFlags |= moveStopHere;
} }
@@ -1159,12 +1159,12 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// ostrożnie interpretować sygnały - semafor może zezwalać na jazdę pociągu z przodu! // ostrożnie interpretować sygnały - semafor może zezwalać na jazdę pociągu z przodu!
iDrivigFlags |= moveVisibility; iDrivigFlags |= moveVisibility;
// store the ordered restricted speed and don't exceed it until the flag is cleared // store the ordered restricted speed and don't exceed it until the flag is cleared
VelRestricted = sSpeedTable[ i ].evEvent->ValueGet( 2 ); VelRestricted = sSpeedTable[ i ].evEvent->input_value( 2 );
} }
} }
if( eSignSkip != sSpeedTable[ i ].evEvent ) { if( eSignSkip != sSpeedTable[ i ].evEvent ) {
// jeśli ten SBL nie jest do pominięcia to ma 0 odczytywać // jeśli ten SBL nie jest do pominięcia to ma 0 odczytywać
v = sSpeedTable[ i ].evEvent->ValueGet( 1 ); v = sSpeedTable[ i ].evEvent->input_value( 1 );
// TODO sprawdzić do której zmiennej jest przypisywane v i zmienić to tutaj // TODO sprawdzić do której zmiennej jest przypisywane v i zmienić to tutaj
} }
} }
@@ -1194,7 +1194,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
if (sSpeedTable[i].fSectionVelocityDist == 0.0) if (sSpeedTable[i].fSectionVelocityDist == 0.0)
{ {
if (Global.iWriteLogEnabled & 8) if (Global.iWriteLogEnabled & 8)
WriteLog("TableUpdate: Event is behind. SVD = 0: " + sSpeedTable[i].evEvent->asName); WriteLog("TableUpdate: Event is behind. SVD = 0: " + sSpeedTable[i].evEvent->m_name);
sSpeedTable[i].iFlags = 0; // jeśli punktowy to kasujemy i nie dajemy ograniczenia na stałe sSpeedTable[i].iFlags = 0; // jeśli punktowy to kasujemy i nie dajemy ograniczenia na stałe
} }
else if (sSpeedTable[i].fSectionVelocityDist < 0.0) else if (sSpeedTable[i].fSectionVelocityDist < 0.0)
@@ -1208,7 +1208,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
{ // jeśli większe to musi wyjechać za poprzednie { // jeśli większe to musi wyjechać za poprzednie
VelLimitLast = sSpeedTable[i].fVelNext; VelLimitLast = sSpeedTable[i].fVelNext;
if (Global.iWriteLogEnabled & 8) if (Global.iWriteLogEnabled & 8)
WriteLog("TableUpdate: Event is behind. SVD < 0: " + sSpeedTable[i].evEvent->asName); WriteLog("TableUpdate: Event is behind. SVD < 0: " + sSpeedTable[i].evEvent->m_name);
sSpeedTable[i].iFlags = 0; // wyjechaliśmy poza poprzednie, można skasować sSpeedTable[i].iFlags = 0; // wyjechaliśmy poza poprzednie, można skasować
} }
} }
@@ -1227,7 +1227,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
{ // { //
VelLimitLast = -1.0; VelLimitLast = -1.0;
if (Global.iWriteLogEnabled & 8) if (Global.iWriteLogEnabled & 8)
WriteLog("TableUpdate: Event is behind. SVD > 0: " + sSpeedTable[i].evEvent->asName); WriteLog("TableUpdate: Event is behind. SVD > 0: " + sSpeedTable[i].evEvent->m_name);
sSpeedTable[i].iFlags = 0; // wyjechaliśmy poza poprzednie, można skasować sSpeedTable[i].iFlags = 0; // wyjechaliśmy poza poprzednie, można skasować
} }
} }
@@ -1310,7 +1310,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
sSpeedTable[ i ].iFlags = 0; sSpeedTable[ i ].iFlags = 0;
} }
} }
else if( sSpeedTable[ i ].evEvent->StopCommand() ) { else if( sSpeedTable[ i ].evEvent->is_command() ) {
// jeśli prędkość jest zerowa, a komórka zawiera komendę // jeśli prędkość jest zerowa, a komórka zawiera komendę
eSignNext = sSpeedTable[ i ].evEvent; // dla informacji eSignNext = sSpeedTable[ i ].evEvent; // dla informacji
if( true == TestFlag( iDrivigFlags, moveStopHere ) ) { if( true == TestFlag( iDrivigFlags, moveStopHere ) ) {
@@ -1648,39 +1648,25 @@ TController::~TController()
CloseLog(); CloseLog();
}; };
std::string TController::Order2Str(TOrders Order) const // zamiana kodu rozkazu na opis
{ // zamiana kodu rozkazu na opis std::string TController::Order2Str(TOrders Order) const {
if (Order & Change_direction)
return "Change_direction"; // może być nałożona na inną i wtedy ma priorytet if( Order & Change_direction ) {
if (Order == Wait_for_orders) // może być nałożona na inną i wtedy ma priorytet
return "Wait_for_orders"; return "Change_direction";
if (Order == Prepare_engine) }
return "Prepare_engine"; switch( Order ) {
if (Order == Shunt) case Wait_for_orders: return "Wait_for_orders";
return "Shunt"; case Prepare_engine: return "Prepare_engine";
if (Order == Connect) case Release_engine: return "Release_engine";
return "Connect"; case Change_direction: return "Change_direction";
if (Order == Disconnect) case Connect: return "Connect";
return "Disconnect"; case Disconnect: return "Disconnect";
if (Order == Obey_train) case Shunt: return "Shunt";
return "Obey_train"; case Obey_train: return "Obey_train";
if (Order == Release_engine) case Jump_to_first_order: return "Jump_to_first_order";
return "Release_engine"; default: return "Undefined";
if (Order == Jump_to_first_order) }
return "Jump_to_first_order";
/* Ra: wersja ze switch nie działa prawidłowo (czemu?)
switch (Order)
{
Wait_for_orders: return "Wait_for_orders";
Prepare_engine: return "Prepare_engine";
Shunt: return "Shunt";
Change_direction: return "Change_direction";
Obey_train: return "Obey_train";
Release_engine: return "Release_engine";
Jump_to_first_order: return "Jump_to_first_order";
}
*/
return "Undefined!";
} }
std::string TController::OrderCurrent() const std::string TController::OrderCurrent() const
@@ -4634,8 +4620,11 @@ TController::UpdateSituation(double dt) {
// jedzie w dowolnym trybie albo Wait_for_orders // jedzie w dowolnym trybie albo Wait_for_orders
if( mvOccupied->Vel < 0.1 ) { if( mvOccupied->Vel < 0.1 ) {
// dopiero jak stanie // dopiero jak stanie
PutCommand( eSignNext->CommandGet(), eSignNext->ValueGet( 1 ), eSignNext->ValueGet( 2 ), nullptr ); /*
PutCommand( eSignNext->text(), eSignNext->value( 1 ), eSignNext->value( 2 ), nullptr );
eSignNext->StopCommandSent(); // się wykonało już eSignNext->StopCommandSent(); // się wykonało już
*/ // replacement of the above
eSignNext->send_command( *this );
} }
} }
break; break;
@@ -5608,7 +5597,7 @@ void TController::OrderPush(TOrders NewOrder)
if (OrderTop >= maxorders) if (OrderTop >= maxorders)
ErrorLog("Commands overflow: The program will now crash"); ErrorLog("Commands overflow: The program will now crash");
#if LOGORDERS #if LOGORDERS
WriteLog("--> OrderPush"); WriteLog("--> OrderPush: [" + Order2Str( NewOrder ) + "]");
OrdersDump(); // normalnie nie ma po co tego wypisywać OrdersDump(); // normalnie nie ma po co tego wypisywać
#endif #endif
} }
@@ -5755,22 +5744,22 @@ bool TController::BackwardTrackBusy(TTrack *Track)
return false; // wolny return false; // wolny
}; };
TEvent * TController::CheckTrackEventBackward(double fDirection, TTrack *Track) basic_event * TController::CheckTrackEventBackward(double fDirection, TTrack *Track)
{ // sprawdzanie eventu w torze, czy jest sygnałowym - skanowanie do tyłu { // sprawdzanie eventu w torze, czy jest sygnałowym - skanowanie do tyłu
// NOTE: this method returns only one event which meets the conditions, due to limitations in the caller // NOTE: this method returns only one event which meets the conditions, due to limitations in the caller
// TBD, TODO: clean up the caller and return all suitable events, as in theory things will go awry if the track has more than one signal // TBD, TODO: clean up the caller and return all suitable events, as in theory things will go awry if the track has more than one signal
auto const &eventsequence { ( fDirection > 0 ? Track->m_events2 : Track->m_events1 ) }; auto const &eventsequence { ( fDirection > 0 ? Track->m_events2 : Track->m_events1 ) };
for( auto const &event : eventsequence ) { for( auto const &event : eventsequence ) {
if( ( event.second != nullptr ) if( ( event.second != nullptr )
&& ( false == event.second->bEnabled ) && ( event.second->m_passive )
&& ( event.second->Type == tp_GetValues ) ) { && ( typeid(*(event.second)) == typeid( getvalues_event ) ) ) {
return event.second; return event.second;
} }
} }
return nullptr; return nullptr;
}; };
TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, TEvent *&Event) TTrack * TController::BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, basic_event *&Event)
{ // szukanie sygnalizatora w kierunku przeciwnym jazdy (eventu odczytu komórki pamięci) { // szukanie sygnalizatora w kierunku przeciwnym jazdy (eventu odczytu komórki pamięci)
TTrack *pTrackChVel = Track; // tor ze zmianą prędkości TTrack *pTrackChVel = Track; // tor ze zmianą prędkości
TTrack *pTrackFrom; // odcinek poprzedni, do znajdywania końca dróg TTrack *pTrackFrom; // odcinek poprzedni, do znajdywania końca dróg
@@ -5884,7 +5873,7 @@ TCommandType TController::BackwardScan()
// Ra: przy wstecznym skanowaniu prędkość nie ma znaczenia // Ra: przy wstecznym skanowaniu prędkość nie ma znaczenia
double scanmax = 1000; // 1000m do tyłu, żeby widział przeciwny koniec stacji double scanmax = 1000; // 1000m do tyłu, żeby widział przeciwny koniec stacji
double scandist = scanmax; // zmodyfikuje na rzeczywiście przeskanowane double scandist = scanmax; // zmodyfikuje na rzeczywiście przeskanowane
TEvent *e = NULL; // event potencjalnie od semafora basic_event *e = NULL; // event potencjalnie od semafora
// opcjonalnie może być skanowanie od "wskaźnika" z przodu, np. W5, Tm=Ms1, koniec toru wg drugiej osi w kierunku ruchu // opcjonalnie może być skanowanie od "wskaźnika" z przodu, np. W5, Tm=Ms1, koniec toru wg drugiej osi w kierunku ruchu
TTrack *scantrack = BackwardTraceRoute(scandist, scandir, pVehicles[0]->RaTrackGet(), e); TTrack *scantrack = BackwardTraceRoute(scandist, scandir, pVehicles[0]->RaTrackGet(), e);
auto const dir = startdir * pVehicles[0]->VectorFront(); // wektor w kierunku jazdy/szukania auto const dir = startdir * pVehicles[0]->VectorFront(); // wektor w kierunku jazdy/szukania
@@ -5907,12 +5896,12 @@ TCommandType TController::BackwardScan()
#endif #endif
// najpierw sprawdzamy, czy semafor czy inny znak został przejechany // najpierw sprawdzamy, czy semafor czy inny znak został przejechany
auto pos = pVehicles[1]->RearPosition(); // pozycja tyłu auto pos = pVehicles[1]->RearPosition(); // pozycja tyłu
if (e->Type == tp_GetValues) if( typeid( *e ) == typeid( getvalues_event ) )
{ // przesłać info o zbliżającym się semaforze { // przesłać info o zbliżającym się semaforze
#if LOGBACKSCAN #if LOGBACKSCAN
edir += "(" + ( e->asNodeName ) + ")"; edir += "(" + ( e->asNodeName ) + ")";
#endif #endif
auto sl = e->PositionGet(); // położenie komórki pamięci auto sl = e->input_location(); // położenie komórki pamięci
auto sem = sl - pos; // wektor do komórki pamięci od końca składu auto sem = sl - pos; // wektor do komórki pamięci od końca składu
if (dir.x * sem.x + dir.z * sem.z < 0) { if (dir.x * sem.x + dir.z * sem.z < 0) {
// jeśli został minięty // jeśli został minięty
@@ -5922,7 +5911,7 @@ TCommandType TController::BackwardScan()
#endif #endif
return TCommandType::cm_Unknown; // nic return TCommandType::cm_Unknown; // nic
} }
vmechmax = e->ValueGet(1); // prędkość przy tym semaforze vmechmax = e->input_value(1); // prędkość przy tym semaforze
// przeliczamy odległość od semafora - potrzebne by były współrzędne początku składu // przeliczamy odległość od semafora - potrzebne by były współrzędne początku składu
scandist = sem.Length() - 2; // 2m luzu przy manewrach wystarczy scandist = sem.Length() - 2; // 2m luzu przy manewrach wystarczy
if( scandist < 0 ) { if( scandist < 0 ) {
@@ -5930,7 +5919,7 @@ TCommandType TController::BackwardScan()
scandist = 0; scandist = 0;
} }
bool move = false; // czy AI w trybie manewerowym ma dociągnąć pod S1 bool move = false; // czy AI w trybie manewerowym ma dociągnąć pod S1
if( e->Command() == TCommandType::cm_SetVelocity ) { if( e->input_command() == TCommandType::cm_SetVelocity ) {
if( ( vmechmax == 0.0 ) ? if( ( vmechmax == 0.0 ) ?
( OrderCurrentGet() & ( Shunt | Connect ) ) : ( OrderCurrentGet() & ( Shunt | Connect ) ) :
( OrderCurrentGet() & Connect ) ) { // przy podczepianiu ignorować wyjazd? ( OrderCurrentGet() & Connect ) ) { // przy podczepianiu ignorować wyjazd?
@@ -5974,7 +5963,7 @@ TCommandType TController::BackwardScan()
if (OrderCurrentGet() ? OrderCurrentGet() & (Shunt | Connect) : if (OrderCurrentGet() ? OrderCurrentGet() & (Shunt | Connect) :
true) // w Wait_for_orders też widzi tarcze true) // w Wait_for_orders też widzi tarcze
{ // reakcja AI w trybie manewrowym dodatkowo na sygnały manewrowe { // reakcja AI w trybie manewrowym dodatkowo na sygnały manewrowe
if (move ? true : e->Command() == TCommandType::cm_ShuntVelocity) if (move ? true : e->input_command() == TCommandType::cm_ShuntVelocity)
{ // jeśli powyżej było SetVelocity 0 0, to dociągamy pod S1 { // jeśli powyżej było SetVelocity 0 0, to dociągamy pod S1
if ((scandist > fMinProximityDist) ? if ((scandist > fMinProximityDist) ?
(mvOccupied->Vel > 0.0) || (vmechmax == 0.0) : (mvOccupied->Vel > 0.0) || (vmechmax == 0.0) :
@@ -6007,7 +5996,7 @@ TCommandType TController::BackwardScan()
WriteLog( WriteLog(
edir + " - [ShuntVelocity] [" edir + " - [ShuntVelocity] ["
+ to_string( vmechmax, 2 ) + "] [" + to_string( vmechmax, 2 ) + "] ["
+ to_string( e->ValueGet( 2 ), 2 ) + "]" ); + to_string( e->value( 2 ), 2 ) + "]" );
#endif #endif
return ( return (
vmechmax > 0 ? vmechmax > 0 ?
@@ -6028,8 +6017,8 @@ TCommandType TController::BackwardScan()
} }
} // if (move?... } // if (move?...
} // if (OrderCurrentGet()==Shunt) } // if (OrderCurrentGet()==Shunt)
if (!e->bEnabled) // jeśli skanowany if (e->m_passive) // jeśli skanowany
if (e->StopCommand()) // a podłączona komórka ma komendę if (e->is_command()) // a podłączona komórka ma komendę
return TCommandType::cm_Command; // to też się obrócić return TCommandType::cm_Command; // to też się obrócić
} // if (e->Type==tp_GetValues) } // if (e->Type==tp_GetValues)
} // if (e) } // if (e)

View File

@@ -140,13 +140,13 @@ class TSpeedPos
struct struct
{ {
TTrack *trTrack{ nullptr }; // wskaźnik na tor o zmiennej prędkości (zwrotnica, obrotnica) TTrack *trTrack{ nullptr }; // wskaźnik na tor o zmiennej prędkości (zwrotnica, obrotnica)
TEvent *evEvent{ nullptr }; // połączenie z eventem albo komórką pamięci basic_event *evEvent{ nullptr }; // połączenie z eventem albo komórką pamięci
}; };
void CommandCheck(); void CommandCheck();
public: public:
TSpeedPos(TTrack *track, double dist, int flag); TSpeedPos(TTrack *track, double dist, int flag);
TSpeedPos(TEvent *event, double dist, TOrders order); TSpeedPos(basic_event *event, double dist, TOrders order);
TSpeedPos() = default; TSpeedPos() = default;
void Clear(); void Clear();
bool Update(); bool Update();
@@ -155,7 +155,7 @@ class TSpeedPos
void void
UpdateDistance( double dist ) { UpdateDistance( double dist ) {
fDist -= dist; } fDist -= dist; }
bool Set(TEvent *e, double d, TOrders order = Wait_for_orders); bool Set(basic_event *e, double d, TOrders order = Wait_for_orders);
void Set(TTrack *t, double d, int f); void Set(TTrack *t, double d, int f);
std::string TableText() const; std::string TableText() const;
std::string GetName() const; std::string GetName() const;
@@ -181,7 +181,7 @@ class TController {
std::vector<TSpeedPos> sSpeedTable; std::vector<TSpeedPos> sSpeedTable;
double fLastVel = 0.0; // prędkość na poprzednio sprawdzonym torze double fLastVel = 0.0; // prędkość na poprzednio sprawdzonym torze
TTrack *tLast = nullptr; // ostatni analizowany tor TTrack *tLast = nullptr; // ostatni analizowany tor
TEvent *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu basic_event *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu
std::size_t SemNextIndex{ std::size_t(-1) }; std::size_t SemNextIndex{ std::size_t(-1) };
std::size_t SemNextStopIndex{ std::size_t( -1 ) }; std::size_t SemNextStopIndex{ std::size_t( -1 ) };
double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki double dMoveLen = 0.0; // odległość przejechana od ostatniego sprawdzenia tabelki
@@ -190,7 +190,7 @@ class TController {
double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji
public: public:
double fAccGravity = 0.0; // przyspieszenie składowej stycznej grawitacji double fAccGravity = 0.0; // przyspieszenie składowej stycznej grawitacji
TEvent *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2] basic_event *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu
int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu
// parametry sterowania pojazdem (stan, hamowanie) // parametry sterowania pojazdem (stan, hamowanie)
@@ -362,9 +362,9 @@ private:
int OrderDirectionChange(int newdir, TMoverParameters *Vehicle); int OrderDirectionChange(int newdir, TMoverParameters *Vehicle);
void Lights(int head, int rear); void Lights(int head, int rear);
// Ra: metody obsługujące skanowanie toru // Ra: metody obsługujące skanowanie toru
std::vector<TEvent *> CheckTrackEvent(TTrack *Track, double const fDirection ) const; std::vector<basic_event *> CheckTrackEvent(TTrack *Track, double const fDirection ) const;
bool TableAddNew(); bool TableAddNew();
bool TableNotFound(TEvent const *Event) const; bool TableNotFound(basic_event const *Event) const;
void TableTraceRoute(double fDistance, TDynamicObject *pVehicle); void TableTraceRoute(double fDistance, TDynamicObject *pVehicle);
void TableCheck(double fDistance); void TableCheck(double fDistance);
TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc); TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc);
@@ -387,8 +387,8 @@ private:
private: // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu private: // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu
bool BackwardTrackBusy(TTrack *Track); bool BackwardTrackBusy(TTrack *Track);
TEvent *CheckTrackEventBackward(double fDirection, TTrack *Track); basic_event *CheckTrackEventBackward(double fDirection, TTrack *Track);
TTrack *BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, TEvent *&Event); TTrack *BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, basic_event *&Event);
void SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos ); void SetProximityVelocity( double dist, double vel, glm::dvec3 const *pos );
TCommandType BackwardScan(); TCommandType BackwardScan();

View File

@@ -1784,7 +1784,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
iDirection = (Reversed ? 0 : 1); // Ra: 0, jeśli ma być wstawiony jako obrócony tyłem iDirection = (Reversed ? 0 : 1); // Ra: 0, jeśli ma być wstawiony jako obrócony tyłem
asBaseDir = szDynamicPath + BaseDir + "/"; // McZapkie-310302 asBaseDir = szDynamicPath + BaseDir + "/"; // McZapkie-310302
asName = Name; asName = Name;
std::string asAnimName = ""; // zmienna robocza do wyszukiwania osi i wózków std::string asAnimName; // zmienna robocza do wyszukiwania osi i wózków
// Ra: zmieniamy znaczenie obsady na jednoliterowe, żeby dosadzić kierownika // Ra: zmieniamy znaczenie obsady na jednoliterowe, żeby dosadzić kierownika
if (DriverType == "headdriver") if (DriverType == "headdriver")
DriverType = "1"; // sterujący kabiną +1 DriverType = "1"; // sterujący kabiną +1
@@ -1811,7 +1811,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
} }
*/ */
// utworzenie parametrów fizyki // utworzenie parametrów fizyki
MoverParameters = new TMoverParameters(iDirection ? fVel : -fVel, Type_Name, asName, Load, LoadType, Cab); MoverParameters = new TMoverParameters(iDirection ? fVel : -fVel, Type_Name, asName, Cab);
iLights = MoverParameters->iLights; // wskaźnik na stan własnych świateł iLights = MoverParameters->iLights; // wskaźnik na stan własnych świateł
// McZapkie: TypeName musi byc nazwą CHK/MMD pojazdu // McZapkie: TypeName musi byc nazwą CHK/MMD pojazdu
if (!MoverParameters->LoadFIZ(asBaseDir)) if (!MoverParameters->LoadFIZ(asBaseDir))
@@ -1823,6 +1823,9 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
} }
return 0.0; // zerowa długość to brak pojazdu return 0.0; // zerowa długość to brak pojazdu
} }
// load the cargo now that we know whether the vehicle will allow it
MoverParameters->AssignLoad( LoadType, Load );
bool driveractive = (fVel != 0.0); // jeśli prędkość niezerowa, to aktywujemy ruch bool driveractive = (fVel != 0.0); // jeśli prędkość niezerowa, to aktywujemy ruch
if (!MoverParameters->CheckLocomotiveParameters( if (!MoverParameters->CheckLocomotiveParameters(
driveractive, driveractive,
@@ -2096,7 +2099,8 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
iAxles = std::min( MoverParameters->NAxles, MaxAxles ); // ilość osi iAxles = std::min( MoverParameters->NAxles, MaxAxles ); // ilość osi
*/ */
// wczytywanie z pliku nazwatypu.mmd, w tym model // wczytywanie z pliku nazwatypu.mmd, w tym model
LoadMMediaFile(asBaseDir, Type_Name, asReplacableSkin); erase_extension( asReplacableSkin );
LoadMMediaFile(Type_Name, asReplacableSkin);
// McZapkie-100402: wyszukiwanie submodeli sprzegów // McZapkie-100402: wyszukiwanie submodeli sprzegów
btCoupler1.Init( "coupler1", mdModel, false ); // false - ma być wyłączony btCoupler1.Init( "coupler1", mdModel, false ); // false - ma być wyłączony
btCoupler2.Init( "coupler2", mdModel, false); btCoupler2.Init( "coupler2", mdModel, false);
@@ -2235,11 +2239,11 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
// zrobiło tego // zrobiło tego
Move( 0.0001 ); Move( 0.0001 );
ABuCheckMyTrack(); // zmiana toru na ten, co oś Axle0 (oś z przodu) ABuCheckMyTrack(); // zmiana toru na ten, co oś Axle0 (oś z przodu)
TLocation loc; // Ra: ustawienie pozycji do obliczania sprzęgów // Ra: ustawienie pozycji do obliczania sprzęgów
loc.X = -vPosition.x; MoverParameters->Loc = {
loc.Y = vPosition.z; -vPosition.x,
loc.Z = vPosition.y; vPosition.z,
MoverParameters->Loc = loc; // normalnie przesuwa ComputeMovement() w Update() vPosition.y }; // normalnie przesuwa ComputeMovement() w Update()
// ABuWozki 060504 // ABuWozki 060504
if (mdModel) // jeśli ma w czym szukać if (mdModel) // jeśli ma w czym szukać
{ {
@@ -2613,13 +2617,13 @@ void TDynamicObject::update_exchange( double const Deltatime ) {
auto const exchangesize = std::min( m_exchange.unload_count, MoverParameters->UnLoadSpeed * m_exchange.speed_factor ); auto const exchangesize = std::min( m_exchange.unload_count, MoverParameters->UnLoadSpeed * m_exchange.speed_factor );
m_exchange.unload_count -= exchangesize; m_exchange.unload_count -= exchangesize;
MoverParameters->LoadStatus = 1; MoverParameters->LoadStatus = 1;
MoverParameters->Load = std::max( 0.f, MoverParameters->Load - exchangesize ); MoverParameters->LoadAmount = std::max( 0.f, MoverParameters->LoadAmount - exchangesize );
update_load_visibility(); update_load_visibility();
} }
if( m_exchange.unload_count < 0.01 ) { if( m_exchange.unload_count < 0.01 ) {
// finish any potential unloading operation before adding new load // finish any potential unloading operation before adding new load
// don't load more than can fit // don't load more than can fit
m_exchange.load_count = std::min( m_exchange.load_count, MoverParameters->MaxLoad - MoverParameters->Load ); m_exchange.load_count = std::min( m_exchange.load_count, MoverParameters->MaxLoad - MoverParameters->LoadAmount );
while( ( m_exchange.load_count > 0.01 ) while( ( m_exchange.load_count > 0.01 )
&& ( m_exchange.time >= 1.0 ) ) { && ( m_exchange.time >= 1.0 ) ) {
@@ -2627,7 +2631,7 @@ void TDynamicObject::update_exchange( double const Deltatime ) {
auto const exchangesize = std::min( m_exchange.load_count, MoverParameters->LoadSpeed * m_exchange.speed_factor ); auto const exchangesize = std::min( m_exchange.load_count, MoverParameters->LoadSpeed * m_exchange.speed_factor );
m_exchange.load_count -= exchangesize; m_exchange.load_count -= exchangesize;
MoverParameters->LoadStatus = 2; MoverParameters->LoadStatus = 2;
MoverParameters->Load = std::min( MoverParameters->MaxLoad, MoverParameters->Load + exchangesize ); // std::max not strictly needed but, eh MoverParameters->LoadAmount = std::min( MoverParameters->MaxLoad, MoverParameters->LoadAmount + exchangesize ); // std::max not strictly needed but, eh
update_load_visibility(); update_load_visibility();
} }
} }
@@ -2665,34 +2669,28 @@ void TDynamicObject::LoadUpdate() {
// przeładowanie modelu ładunku // przeładowanie modelu ładunku
// Ra: nie próbujemy wczytywać modeli miliony razy podczas renderowania!!! // Ra: nie próbujemy wczytywać modeli miliony razy podczas renderowania!!!
if( ( mdLoad == nullptr ) if( ( mdLoad == nullptr )
&& ( MoverParameters->Load > 0 ) ) { && ( MoverParameters->LoadAmount > 0 ) ) {
if( false == MoverParameters->LoadType.empty() ) { if( false == MoverParameters->LoadType.name.empty() ) {
// bieżąca ścieżka do tekstur to dynamic/...
Global.asCurrentTexturePath = asBaseDir;
Global.asCurrentTexturePath = asBaseDir; // bieżąca ścieżka do tekstur to dynamic/... mdLoad = LoadMMediaFile_mdload( MoverParameters->LoadType.name );
// TODO: discern from vehicle component which merely uses vehicle directory and has no animations, so it can be initialized outright
// try first specialized version of the load model, vehiclename_loadname // and actual vehicles which get their initialization after their animations are set up
auto const specializedloadfilename { asBaseDir + MoverParameters->TypeName + "_" + MoverParameters->LoadType };
mdLoad = TModelsManager::GetModel( specializedloadfilename, true );
if( mdLoad == nullptr ) {
// if this fails, try generic load model
auto const genericloadfilename { asBaseDir + MoverParameters->LoadType };
mdLoad = TModelsManager::GetModel( genericloadfilename, true );
}
if( mdLoad != nullptr ) { if( mdLoad != nullptr ) {
// TODO: discern from vehicle component which merely uses vehicle directory and has no animations, so it can be initialized outright
// and actual vehicles which get their initialization after their animations are set up
mdLoad->Init(); mdLoad->Init();
} }
// update bindings between lowpoly sections and potential load chunks placed inside them // update bindings between lowpoly sections and potential load chunks placed inside them
update_load_sections(); update_load_sections();
// z powrotem defaultowa sciezka do tekstur
Global.asCurrentTexturePath = std::string( szTexturePath ); // z powrotem defaultowa sciezka do tekstur Global.asCurrentTexturePath = std::string( szTexturePath );
} }
// Ra: w MMD można by zapisać położenie modelu ładunku (np. węgiel) w zależności od załadowania // Ra: w MMD można by zapisać położenie modelu ładunku (np. węgiel) w zależności od załadowania
} }
else if( MoverParameters->Load == 0 ) { else if( MoverParameters->LoadAmount == 0 ) {
// nie ma ładunku // nie ma ładunku
MoverParameters->AssignLoad( "" );
mdLoad = nullptr; mdLoad = nullptr;
// erase bindings between lowpoly sections and potential load chunks placed inside them // erase bindings between lowpoly sections and potential load chunks placed inside them
update_load_sections(); update_load_sections();
@@ -2730,7 +2728,7 @@ TDynamicObject::update_load_visibility() {
auto loadpercentage { ( auto loadpercentage { (
MoverParameters->MaxLoad == 0.0 ? MoverParameters->MaxLoad == 0.0 ?
0.0 : 0.0 :
100.0 * MoverParameters->Load / MoverParameters->MaxLoad ) }; 100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
auto const sectionloadpercentage { ( auto const sectionloadpercentage { (
SectionLoadVisibility.empty() ? SectionLoadVisibility.empty() ?
0.0 : 0.0 :
@@ -2759,14 +2757,14 @@ TDynamicObject::update_load_visibility() {
void void
TDynamicObject::update_load_offset() { TDynamicObject::update_load_offset() {
if( MoverParameters->LoadMinOffset == 0.f ) { return; } if( MoverParameters->LoadType.offset_min == 0.f ) { return; }
auto const loadpercentage { ( auto const loadpercentage { (
MoverParameters->MaxLoad == 0.0 ? MoverParameters->MaxLoad == 0.0 ?
0.0 : 0.0 :
100.0 * MoverParameters->Load / MoverParameters->MaxLoad ) }; 100.0 * MoverParameters->LoadAmount / MoverParameters->MaxLoad ) };
LoadOffset = interpolate( MoverParameters->LoadMinOffset, 0.f, clamp( 0.0, 1.0, loadpercentage * 0.01 ) ); LoadOffset = interpolate( MoverParameters->LoadType.offset_min, 0.f, clamp( 0.0, 1.0, loadpercentage * 0.01 ) );
} }
void void
@@ -2808,20 +2806,7 @@ bool TDynamicObject::Update(double dt, double dt1)
return false; // a normalnie powinny mieć bEnabled==false return false; // a normalnie powinny mieć bEnabled==false
double dDOMoveLen; double dDOMoveLen;
TLocation l;
l.X = -vPosition.x; // przekazanie pozycji do fizyki
l.Y = vPosition.z;
l.Z = vPosition.y;
TRotation r;
r.Rx = r.Ry = r.Rz = 0;
// McZapkie: parametry powinny byc pobierane z toru // McZapkie: parametry powinny byc pobierane z toru
// TTrackShape ts;
// ts.R=MyTrack->fRadius;
// if (ABuGetDirection()<0) ts.R=-ts.R;
// ts.R=MyTrack->fRadius; //ujemne promienie są już zamienione przy
// wczytywaniu
if (Axle0.vAngles.z != Axle1.vAngles.z) if (Axle0.vAngles.z != Axle1.vAngles.z)
{ // wyliczenie promienia z obrotów osi - modyfikację zgłosił youBy { // wyliczenie promienia z obrotów osi - modyfikację zgłosił youBy
ts.R = Axle0.vAngles.z - Axle1.vAngles.z; // różnica może dawać stałą ±M_2PI ts.R = Axle0.vAngles.z - Axle1.vAngles.z; // różnica może dawać stałą ±M_2PI
@@ -3233,16 +3218,15 @@ bool TDynamicObject::Update(double dt, double dt1)
} }
// fragment "z EXE Kursa" // fragment "z EXE Kursa"
if (MoverParameters->Mains) // nie wchodzić w funkcję bez potrzeby if( MoverParameters->Mains ) { // nie wchodzić w funkcję bez potrzeby
if ( ( false == MoverParameters->Battery ) if( ( false == MoverParameters->Battery )
&& ( false == MoverParameters->ConverterFlag ) // added alternative power source. TODO: more generic power check && ( false == MoverParameters->ConverterFlag ) // added alternative power source. TODO: more generic power check
/* /*
// NOTE: disabled on account of multi-unit setups, where the unmanned unit wouldn't be affected // NOTE: disabled on account of multi-unit setups, where the unmanned unit wouldn't be affected
&& ( Controller == Humandriver ) && ( Controller == Humandriver )
*/ */
&& ( MoverParameters->EngineType != TEngineType::DieselEngine ) && ( MoverParameters->EngineType != TEngineType::DieselEngine )
&& ( MoverParameters->EngineType != TEngineType::WheelsDriven ) ) && ( MoverParameters->EngineType != TEngineType::WheelsDriven ) ) { // jeśli bateria wyłączona, a nie diesel ani drezyna reczna
{ // jeśli bateria wyłączona, a nie diesel ani drezyna reczna
if( MoverParameters->MainSwitch( false, ( MoverParameters->TrainType == dt_EZT ? range_t::unit : range_t::local ) ) ) { if( MoverParameters->MainSwitch( false, ( MoverParameters->TrainType == dt_EZT ? range_t::unit : range_t::local ) ) ) {
// wyłączyć zasilanie // wyłączyć zasilanie
// NOTE: we turn off entire EMU, but only the affected unit for other multi-unit consists // NOTE: we turn off entire EMU, but only the affected unit for other multi-unit consists
@@ -3257,7 +3241,16 @@ bool TDynamicObject::Update(double dt, double dt1)
*/ */
} }
} }
}
// przekazanie pozycji do fizyki
// NOTE: coordinate system swap
// TODO: replace with regular glm vectors
TLocation const l {
-vPosition.x,
vPosition.z,
vPosition.y };
TRotation r { 0.0, 0.0, 0.0 };
// McZapkie-260202 - dMoveLen przyda sie przy stukocie kol // McZapkie-260202 - dMoveLen przyda sie przy stukocie kol
dDOMoveLen = GetdMoveLen() + MoverParameters->ComputeMovement(dt, dt1, ts, tp, tmpTraction, l, r); dDOMoveLen = GetdMoveLen() + MoverParameters->ComputeMovement(dt, dt1, ts, tp, tmpTraction, l, r);
if( Mechanik ) if( Mechanik )
@@ -3860,13 +3853,13 @@ bool TDynamicObject::FastUpdate(double dt)
if (!bEnabled) if (!bEnabled)
return false; return false;
TLocation l; // NOTE: coordinate system swap
l.X = -vPosition.x; // TODO: replace with regular glm vectors
l.Y = vPosition.z; TLocation const l {
l.Z = vPosition.y; -vPosition.x,
TRotation r; vPosition.z,
r.Rx = r.Ry = r.Rz = 0.0; vPosition.y };
TRotation r { 0.0, 0.0, 0.0 };
// McZapkie: parametry powinny byc pobierane z toru // McZapkie: parametry powinny byc pobierane z toru
// ts.R=MyTrack->fRadius; // ts.R=MyTrack->fRadius;
// ts.Len= Max0R(MoverParameters->BDist,MoverParameters->ADist); // ts.Len= Max0R(MoverParameters->BDist,MoverParameters->ADist);
@@ -4485,20 +4478,14 @@ TDynamicObject::tracing_offset() const {
// McZapkie-250202 // McZapkie-250202
// wczytywanie pliku z danymi multimedialnymi (dzwieki) // wczytywanie pliku z danymi multimedialnymi (dzwieki)
void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName, std::string ReplacableSkin ) { void TDynamicObject::LoadMMediaFile( std::string const &TypeName, std::string const &ReplacableSkin ) {
replace_slashes( BaseDir );
Global.asCurrentDynamicPath = BaseDir;
std::string asFileName = BaseDir + TypeName + ".mmd";
std::string asLoadName;
if( false == MoverParameters->LoadType.empty() ) {
asLoadName = BaseDir + MoverParameters->LoadType;
}
Global.asCurrentDynamicPath = asBaseDir;
std::string asFileName = asBaseDir + TypeName + ".mmd";
std::string asAnimName; std::string asAnimName;
bool Stop_InternalData = false; bool Stop_InternalData = false;
pants = NULL; // wskaźnik pierwszego obiektu animującego dla pantografów pants = NULL; // wskaźnik pierwszego obiektu animującego dla pantografów
cParser parser( TypeName + ".mmd", cParser::buffer_FILE, BaseDir ); cParser parser( TypeName + ".mmd", cParser::buffer_FILE, asBaseDir );
if( false == parser.ok() ) { if( false == parser.ok() ) {
ErrorLog( "Failed to load appearance data for vehicle " + MoverParameters->Name ); ErrorLog( "Failed to load appearance data for vehicle " + MoverParameters->Name );
return; return;
@@ -4532,8 +4519,8 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
} }
m_materialdata.multi_textures = clamp( m_materialdata.multi_textures, 0, 1 ); // na razie ustawiamy na 1 m_materialdata.multi_textures = clamp( m_materialdata.multi_textures, 0, 1 ); // na razie ustawiamy na 1
} }
asModel = BaseDir + asModel; // McZapkie 2002-07-20: dynamics maja swoje modele w dynamics/basedir asModel = asBaseDir + asModel; // McZapkie 2002-07-20: dynamics maja swoje modele w dynamics/basedir
Global.asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/... Global.asCurrentTexturePath = asBaseDir; // biezaca sciezka do tekstur to dynamic/...
mdModel = TModelsManager::GetModel(asModel, true); mdModel = TModelsManager::GetModel(asModel, true);
if (ReplacableSkin != "none") if (ReplacableSkin != "none")
{ {
@@ -4560,7 +4547,6 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
} }
else { else {
// otherwise try the basic approach // otherwise try the basic approach
erase_extension( ReplacableSkin );
int skinindex = 0; int skinindex = 0;
do { do {
material_handle material = GfxRenderer.Fetch_Material( ReplacableSkin + "," + std::to_string( skinindex + 1 ), true ); material_handle material = GfxRenderer.Fetch_Material( ReplacableSkin + "," + std::to_string( skinindex + 1 ), true );
@@ -4605,53 +4591,9 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
m_materialdata.textures_alpha |= 0x08080008; m_materialdata.textures_alpha |= 0x08080008;
} }
} }
if( !MoverParameters->LoadAccepted.empty() ) { if( false == MoverParameters->LoadAttributes.empty() ) {
// Ra: tu wczytywanie modelu ładunku jest w porządku
if( ( MoverParameters->EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) mdLoad = LoadMMediaFile_mdload( MoverParameters->LoadType.name );
&& ( asLoadName == "pantstate" ) ) {
// wartość niby "pantstate" - nazwa dla formalności, ważna jest ilość
if( MoverParameters->Load == 1 ) {
MoverParameters->PantFront( true );
}
else if( MoverParameters->Load == 2 ) {
MoverParameters->PantRear( true );
}
else if( MoverParameters->Load == 3 ) {
MoverParameters->PantFront( true );
MoverParameters->PantRear( true );
}
else if( MoverParameters->Load == 4 ) {
MoverParameters->DoubleTr = -1;
}
else if( MoverParameters->Load == 5 ) {
MoverParameters->DoubleTr = -1;
MoverParameters->PantRear( true );
}
else if( MoverParameters->Load == 6 ) {
MoverParameters->DoubleTr = -1;
MoverParameters->PantFront( true );
}
else if( MoverParameters->Load == 7 ) {
MoverParameters->DoubleTr = -1;
MoverParameters->PantFront( true );
MoverParameters->PantRear( true );
}
}
else {
// Ra: tu wczytywanie modelu ładunku jest w porządku
if( false == asLoadName.empty() ) {
// try first specialized version of the load model, vehiclename_loadname
auto const specializedloadfilename { BaseDir + TypeName + "_" + MoverParameters->LoadType };
if( ( true == FileExists( specializedloadfilename + ".e3d" ) )
|| ( true == FileExists( specializedloadfilename + ".t3d" ) ) ) {
mdLoad = TModelsManager::GetModel( specializedloadfilename, true );
}
if( mdLoad == nullptr ) {
// if this fails, try generic load model
mdLoad = TModelsManager::GetModel( asLoadName, true );
}
}
}
} }
Global.asCurrentTexturePath = szTexturePath; // z powrotem defaultowa sciezka do tekstur Global.asCurrentTexturePath = szTexturePath; // z powrotem defaultowa sciezka do tekstur
do { do {
@@ -4715,9 +4657,8 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
// filename can potentially begin with a slash, and we don't need it // filename can potentially begin with a slash, and we don't need it
asModel.erase( 0, 1 ); asModel.erase( 0, 1 );
} }
asModel = asBaseDir + asModel; // McZapkie-200702 - dynamics maja swoje modele w dynamic/basedir
asModel = BaseDir + asModel; // McZapkie-200702 - dynamics maja swoje modele w dynamic/basedir Global.asCurrentTexturePath = asBaseDir; // biezaca sciezka do tekstur to dynamic/...
Global.asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
mdLowPolyInt = TModelsManager::GetModel(asModel, true); mdLowPolyInt = TModelsManager::GetModel(asModel, true);
} }
@@ -5934,6 +5875,25 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
m_couplersounds[ side::rear ].dsbBufferClamp_loud.offset( rearcoupleroffset ); m_couplersounds[ side::rear ].dsbBufferClamp_loud.offset( rearcoupleroffset );
} }
TModel3d *
TDynamicObject::LoadMMediaFile_mdload( std::string const &Name ) const {
if( Name.empty() ) { return nullptr; }
// try first specialized version of the load model, vehiclename_loadname
TModel3d *loadmodel { nullptr };
auto const specializedloadfilename { asBaseDir + MoverParameters->TypeName + "_" + Name };
if( ( true == FileExists( specializedloadfilename + ".e3d" ) )
|| ( true == FileExists( specializedloadfilename + ".t3d" ) ) ) {
loadmodel = TModelsManager::GetModel( specializedloadfilename, true );
}
if( loadmodel == nullptr ) {
// if this fails, try generic load model
loadmodel = TModelsManager::GetModel( asBaseDir + Name, true );
}
return loadmodel;
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void TDynamicObject::RadioStop() void TDynamicObject::RadioStop()
{ // zatrzymanie pojazdu { // zatrzymanie pojazdu
@@ -7039,7 +6999,8 @@ vehicle_table::erase_disabled() {
&& ( true == vehicle->MyTrack->RemoveDynamicObject( vehicle ) ) ) { && ( true == vehicle->MyTrack->RemoveDynamicObject( vehicle ) ) ) {
vehicle->MyTrack = nullptr; vehicle->MyTrack = nullptr;
} }
if( simulation::Train->Dynamic() == vehicle ) { if( ( simulation::Train != nullptr )
&& ( simulation::Train->Dynamic() == vehicle ) ) {
// clear potential train binding // clear potential train binding
// TBD, TODO: manually eject the driver first ? // TBD, TODO: manually eject the driver first ?
SafeDelete( simulation::Train ); SafeDelete( simulation::Train );

View File

@@ -459,7 +459,7 @@ private:
public: public:
void ABuScanObjects(int ScanDir, double ScanDist); void ABuScanObjects(int ScanDir, double ScanDist);
protected: 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 );
void ABuCheckMyTrack(); void ABuCheckMyTrack();
@@ -581,7 +581,8 @@ private:
Axle0.GetTrack()); }; Axle0.GetTrack()); };
// McZapkie-260202 // McZapkie-260202
void LoadMMediaFile(std::string BaseDir, std::string TypeName, std::string ReplacableSkin); void LoadMMediaFile(std::string const &TypeName, std::string const &ReplacableSkin);
TModel3d *LoadMMediaFile_mdload( std::string const &Name ) const;
inline double ABuGetDirection() const { // ABu. inline double ABuGetDirection() const { // ABu.
return (Axle1.GetTrack() == MyTrack ? Axle1.GetDirection() : Axle0.GetDirection()); }; return (Axle1.GetTrack() == MyTrack ? Axle1.GetDirection() : Axle0.GetDirection()); };

View File

@@ -112,12 +112,12 @@ bool TEventLauncher::Load(cParser *parser)
*parser >> token; *parser >> token;
szText = token; szText = token;
if (token != "*") //*=nie brać command pod uwagę if (token != "*") //*=nie brać command pod uwagę
iCheckMask |= conditional_memstring; iCheckMask |= basic_event::flags::text;
parser->getTokens(); parser->getTokens();
*parser >> token; *parser >> token;
if (token != "*") //*=nie brać wartości 1. pod uwagę if (token != "*") //*=nie brać wartości 1. pod uwagę
{ {
iCheckMask |= conditional_memval1; iCheckMask |= basic_event::flags::value_1;
fVal1 = atof(token.c_str()); fVal1 = atof(token.c_str());
} }
else else
@@ -126,7 +126,7 @@ bool TEventLauncher::Load(cParser *parser)
*parser >> token; *parser >> token;
if (token.compare("*") != 0) //*=nie brać wartości 2. pod uwagę if (token.compare("*") != 0) //*=nie brać wartości 2. pod uwagę
{ {
iCheckMask |= conditional_memval2; iCheckMask |= basic_event::flags::value_2;
fVal2 = atof(token.c_str()); fVal2 = atof(token.c_str());
} }
else else
@@ -282,8 +282,8 @@ TEventLauncher::export_as_text_( std::ostream &Output ) const {
<< "condition " << "condition "
<< asMemCellName << ' ' << asMemCellName << ' '
<< szText << ' ' << szText << ' '
<< ( ( iCheckMask & conditional_memval1 ) != 0 ? to_string( fVal1 ) : "*" ) << ' ' << ( ( iCheckMask & basic_event::flags::value_1 ) != 0 ? to_string( fVal1 ) : "*" ) << ' '
<< ( ( iCheckMask & conditional_memval2 ) != 0 ? to_string( fVal2 ) : "*" ) << ' '; << ( ( iCheckMask & basic_event::flags::value_2 ) != 0 ? to_string( fVal2 ) : "*" ) << ' ';
} }
// footer // footer
Output Output

View File

@@ -32,8 +32,8 @@ public:
std::string asEvent1Name; std::string asEvent1Name;
std::string asEvent2Name; std::string asEvent2Name;
std::string asMemCellName; std::string asMemCellName;
TEvent *Event1 { nullptr }; basic_event *Event1 { nullptr };
TEvent *Event2 { nullptr }; basic_event *Event2 { nullptr };
TMemCell *MemCell { nullptr }; TMemCell *MemCell { nullptr };
int iCheckMask { 0 }; int iCheckMask { 0 };
double dRadius { 0.0 }; double dRadius { 0.0 };

3484
Event.cpp

File diff suppressed because it is too large Load Diff

686
Event.h
View File

@@ -10,133 +10,557 @@ http://mozilla.org/MPL/2.0/.
#pragma once #pragma once
#include "Classes.h" #include "Classes.h"
#include "dumb3d.h" #include "scene.h"
#include "Names.h" #include "Names.h"
#include "EvLaunch.h" #include "EvLaunch.h"
#include "Logs.h"
#include "lua.h"
enum TEventType { // common event interface
tp_Unknown, class basic_event {
tp_Sound,
tp_Exit,
tp_Disable,
tp_Velocity,
tp_Animation,
tp_Lights,
tp_UpdateValues,
tp_GetValues,
tp_PutValues,
tp_Switch,
tp_DynVel,
tp_TrackVel,
tp_Multiple,
tp_AddValues,
tp_CopyValues,
tp_WhoIs,
tp_LogValues,
tp_Visible,
tp_Voltage,
tp_Message,
tp_Friction,
tp_Lua
};
const int update_memstring = 0x0000001; // zmodyfikować tekst (UpdateValues)
const int update_memval1 = 0x0000002; // zmodyfikować pierwszą wartosć
const int update_memval2 = 0x0000004; // zmodyfikować drugą wartosć
const int update_memadd = 0x0000008; // dodać do poprzedniej zawartości
const int update_load = 0x0000010; // odczytać ładunek
const int update_only = 0x00000FF; // wartość graniczna
const int conditional_memstring = 0x0000100; // porównanie tekstu
const int conditional_memval1 = 0x0000200; // porównanie pierwszej wartości liczbowej
const int conditional_memval2 = 0x0000400; // porównanie drugiej wartości
const int conditional_trackoccupied = 0x1000000; // jeśli tor zajęty
const int conditional_trackfree = 0x2000000; // jeśli tor wolny
const int conditional_propability = 0x4000000; // zależnie od generatora lizcb losowych
const int conditional_memcompare = 0x8000000; // porównanie zawartości
union TParam
{
void *asPointer;
TMemCell *asMemCell;
scene::basic_node *asSceneNode;
glm::dvec3 const *asLocation;
TTrack *asTrack;
TAnimModel *asModel;
TAnimContainer *asAnimContainer;
TTrain *asTrain;
TDynamicObject *asDynamic;
TEvent *asEvent;
double asdouble;
int asInt;
sound_source *tsTextSound;
char *asText;
TCommandType asCommand;
TTractionPowerSource *psPower;
};
class TEvent // zmienne: ev*
{ // zdarzenie
public: public:
// types // types
// wrapper for binding between editor-supplied name, event, and execution conditional flag enum flags {
using conditional_event = std::tuple<std::string, TEvent *, bool>; // shared values
// constructors text = 1 << 0,
TEvent(std::string const &m = ""); value_1 = 1 << 1,
~TEvent(); value_2 = 1 << 2,
// metody // update values
void Load(cParser *parser, Math3D::vector3 const &org); load = 1 << 3,
mode_add = 1 << 4,
// condition values
track_busy = 1 << 3,
track_free = 1 << 4,
probability = 1 << 5
};
// constructor
basic_event() = default;
// destructor
virtual ~basic_event();
// methods
// restores event data from provided stream
virtual
void
deserialize( cParser &Input, scene::scratch_data &Scratchpad );
// prepares event for use
virtual
void
init() = 0;
// executes event
virtual
void
run();
// sends basic content of the class in legacy (text) format to provided stream // sends basic content of the class in legacy (text) format to provided stream
virtual
void void
export_as_text( std::ostream &Output ) const; export_as_text( std::ostream &Output ) const;
static void AddToQuery( TEvent *Event, TEvent *&Start ); // adds a sibling event executed together
std::string CommandGet();
TCommandType Command();
double ValueGet(int n);
glm::dvec3 PositionGet() const;
bool StopCommand();
void StopCommandSent();
void Append(TEvent *e);
void void
group( scene::group_handle Group ); append( basic_event *Event );
scene::group_handle // returns: true if the event should be executed immediately
group() const; virtual
bool
is_instant() const;
// sends content of associated data cell to specified vehicle controller
virtual
void
send_command( TController &Controller );
// returns: true if associated data cell contains a command for vehicle controller
virtual
bool
is_command() const;
// input data access
virtual std::string input_text() const;
virtual TCommandType input_command() const;
virtual double input_value( int Index ) const;
virtual glm::dvec3 input_location() const;
void group( scene::group_handle Group );
scene::group_handle group() const;
// members // members
std::string asName; basic_event *m_next { nullptr }; // następny w kolejce // TODO: replace with event list in the manager
basic_event *m_sibling { nullptr }; // kolejny event z tą samą nazwą - od wersji 378
std::string m_name;
bool m_ignored { false }; // replacement for tp_ignored bool m_ignored { false }; // replacement for tp_ignored
bool bEnabled = false; // false gdy ma nie być dodawany do kolejki (skanowanie sygnałów) bool m_passive { false }; // false gdy ma nie być dodawany do kolejki (skanowanie sygnałów)
int iQueued = 0; // ile razy dodany do kolejki int m_inqueue { 0 }; // ile razy dodany do kolejki
TEvent *evNext = nullptr; // następny w kolejce TDynamicObject const *m_activator { nullptr };
TEventType Type = tp_Unknown; double m_launchtime { 0.0 };
double fStartTime = 0.0; double m_delay { 0.0 };
double fDelay = 0.0; double m_delayrandom { 0.0 }; // zakres dodatkowego opóźnienia // standardowo nie będzie dodatkowego losowego opóźnienia
TDynamicObject const *Activator = nullptr;
TParam Params[13]; // McZapkie-070502 //Ra: zamienić to na union/struct
unsigned int iFlags = 0; // zamiast Params[8] z flagami warunku protected:
std::string asNodeName; // McZapkie-100302 - dodalem zeby zapamietac nazwe toru // types
TEvent *evJoined = nullptr; // kolejny event z tą samą nazwą - od wersji 378 using basic_node = std::tuple<std::string, scene::basic_node *>;
double fRandomDelay = 0.0; // zakres dodatkowego opóźnienia // standardowo nie będzie dodatkowego losowego opóźnienia using node_sequence = std::vector<basic_node>;
std::vector<conditional_event> m_children; // events which are placed in the query when this event is executed
bool m_conditionalelse { false }; // TODO: make a part of condition struct struct event_conditions {
unsigned int flags { 0 };
float probability { 0.0 }; // used by conditional_probability
double match_value_1 { 0.0 }; // used by conditional_memcompare
double match_value_2 { 0.0 }; // used by conditional_memcompare
std::string match_text; // used by conditional_memcompare
basic_event::node_sequence *cells; // used by conditional_memcompare
std::vector<TTrack *> tracks; // used by conditional_track
bool has_else { false };
void deserialize( cParser &Input );
void bind( basic_event::node_sequence *Nodes );
void init();
// verifies whether event meets execution condition(s)
bool test() const;
// sends basic content of the class in legacy (text) format to provided stream
void export_as_text( std::ostream &Output ) const;
};
// methods
template <class TableType_>
void init_targets( TableType_ &Repository, std::string const &Targettype, bool const Logerrors = true );
// returns true if provided token is a an event desription keyword, false otherwise
static bool is_keyword( std::string const &Token );
// members
node_sequence m_targets; // targets of operation performed when this event is executed
private: private:
// methods // methods
void Conditions( cParser *parser, std::string s ); // event type string
virtual std::string type() const = 0;
// deserialization helper, converts provided string to a list of target nodes
virtual void deserialize_targets( std::string const &Input );
// deserialize() subclass details
virtual void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) = 0;
// run() subclass details
virtual void run_() = 0;
// export_as_text() subclass details
virtual void export_as_text_( std::ostream &Output ) const = 0;
// members // members
scene::group_handle m_group { null_handle }; // group this event belongs to, if any scene::group_handle m_group { null_handle }; // group this event belongs to, if any
}; };
inline
void
TEvent::group( scene::group_handle Group ) {
m_group = Group;
}
inline
scene::group_handle // specialized event, sends received input to its target(s)
TEvent::group() const { // TBD: replace the generic module with specialized mixins
return m_group; class input_event : public basic_event {
}
friend basic_event * make_event( cParser &Input, scene::scratch_data &Scratchpad );
protected:
// types
struct input_data {
unsigned int flags { 0 };
std::string data_text;
double data_value_1 { 0.0 };
double data_value_2 { 0.0 };
basic_node data_source { "", nullptr };
glm::dvec3 location { 0.0 };
TCommandType command_type { TCommandType::cm_Unknown };
TMemCell const * data_cell() const;
TMemCell * data_cell();
};
// members
input_data m_input;
};
class updatevalues_event : public input_event {
public:
// methods
// prepares event for use
void init() override;
// returns: true if the event should be executed immediately
bool is_instant() const override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
event_conditions m_conditions;
};
class copyvalues_event : public input_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
};
class getvalues_event : public input_event {
public:
// methods
// prepares event for use
void init() override;
// sends content of associated data cell to specified vehicle controller
void send_command( TController &Controller ) override;
// returns: true if associated data cell contains a command for vehicle controller
bool is_command() const override;
// input data access
std::string input_text() const override;
TCommandType input_command() const override;
double input_value( int Index ) const override;
glm::dvec3 input_location() const override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
};
class putvalues_event : public input_event {
public:
// methods
// prepares event for use
void init() override;
// input data access
std::string input_text() const override;
TCommandType input_command() const override;
double input_value( int Index ) const override;
glm::dvec3 input_location() const override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
};
class whois_event : public input_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
};
class logvalues_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
};
class multi_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// types
// wrapper for binding between editor-supplied name, event, and execution conditional flag
using conditional_event = std::tuple<std::string, basic_event *, bool>;
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
std::vector<conditional_event> m_children; // events which are placed in the query when this event is executed
event_conditions m_conditions;
};
class sound_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// types
// wrapper for binding between editor-supplied name and sound object
using basic_sound = std::tuple<std::string, sound_source *>;
// methods
// event type string
std::string type() const override;
// deserialization helper, converts provided string to a list of target nodes
void deserialize_targets( std::string const &Input ) override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
std::vector<basic_sound> m_sounds;
int m_soundmode{ 0 };
int m_soundradiochannel{ 0 };
};
class animation_event : public basic_event {
public:
// destuctor
~animation_event() override;
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
int m_animationtype{ 0 };
std::array<double, 4> m_animationparams{ 0.0 };
std::string m_animationsubmodel;
std::vector<TAnimContainer *> m_animationcontainers;
std::string m_animationfilename;
std::size_t m_animationfilesize{ 0 };
char *m_animationfiledata{ nullptr };
};
class lights_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
std::vector<float> m_lights;
};
class switch_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
int m_switchstate{ 0 };
float m_switchmoverate{ -1.f };
float m_switchmovedelay{ -1.f };
};
class track_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
float m_velocity{ 0.f };
};
class voltage_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
float m_voltage{ -1.f };
};
class visible_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
bool m_visible{ true };
};
class friction_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
float m_friction{ -1.f };
};
class lua_event : public basic_event {
public:
lua_event(lua::eventhandler_t func);
void init() override;
private:
std::string type() const override;
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
void run_() override;
void export_as_text_( std::ostream &Output ) const override;
lua::eventhandler_t lua_func = nullptr;
};
class message_event : public basic_event {
public:
// methods
// prepares event for use
void init() override;
private:
// methods
// event type string
std::string type() const override;
// deserialize() subclass details
void deserialize_( cParser &Input, scene::scratch_data &Scratchpad ) override;
// run() subclass details
void run_() override;
// export_as_text() subclass details
void export_as_text_( std::ostream &Output ) const override;
// members
std::string m_message;
};
basic_event *
make_event( cParser &Input, scene::scratch_data &Scratchpad );
class event_manager { class event_manager {
@@ -155,20 +579,22 @@ public:
// adds provided event to the collection. returns: true on success // adds provided event to the collection. returns: true on success
// TBD, TODO: return handle to the event // TBD, TODO: return handle to the event
bool bool
insert( TEvent *Event ); insert( basic_event *Event );
inline
bool bool
insert( TEventLauncher *Launcher ) { insert( TEventLauncher *Launcher ) {
return m_launchers.insert( Launcher ); } return m_launchers.insert( Launcher ); }
// returns first event in the queue // returns first event in the queue
TEvent * inline
basic_event *
begin() { begin() {
return QueryRootEvent; } return QueryRootEvent; }
// legacy method, returns pointer to specified event, or null // legacy method, returns pointer to specified event, or null
TEvent * basic_event *
FindEvent( std::string const &Name ); FindEvent( std::string const &Name );
// legacy method, inserts specified event in the event query // legacy method, inserts specified event in the event query
bool bool
AddToQuery( TEvent *Event, TDynamicObject const *Owner, double delay = 0.0 ); AddToQuery( basic_event *Event, TDynamicObject const *Owner, double delay = 0.0 );
// legacy method, executes queued events // legacy method, executes queued events
bool bool
CheckQuery(); CheckQuery();
@@ -184,15 +610,9 @@ public:
private: private:
// types // types
using event_sequence = std::deque<TEvent *>; using event_sequence = std::deque<basic_event *>;
using event_map = std::unordered_map<std::string, std::size_t>; using event_map = std::unordered_map<std::string, std::size_t>;
using eventlauncher_sequence = std::vector<TEventLauncher *>; using eventlauncher_sequence = std::vector<TEventLauncher *>;
// methods
// legacy method, verifies condition for specified event
bool
EventConditon( TEvent *Event );
// members // members
event_sequence m_events; event_sequence m_events;
/* /*
@@ -200,11 +620,39 @@ private:
event_sequence m_eventqueue; event_sequence m_eventqueue;
*/ */
// legacy version of the above // legacy version of the above
TEvent *QueryRootEvent { nullptr }; basic_event *QueryRootEvent { nullptr };
TEvent *m_workevent { nullptr }; basic_event *m_workevent { nullptr };
event_map m_eventmap; event_map m_eventmap;
basic_table<TEventLauncher> m_launchers; basic_table<TEventLauncher> m_launchers;
eventlauncher_sequence m_launcherqueue; eventlauncher_sequence m_launcherqueue;
}; };
inline
void
basic_event::group( scene::group_handle Group ) {
m_group = Group;
}
inline
scene::group_handle
basic_event::group() const {
return m_group;
}
template <class TableType_>
void
basic_event::init_targets( TableType_ &Repository, std::string const &Targettype, bool const Logerrors ) {
for( auto &target : m_targets ) {
std::get<scene::basic_node *>( target ) = Repository.find( std::get<std::string>( target ) );
if( std::get<scene::basic_node *>( target ) == nullptr ) {
m_ignored = true; // deaktywacja
if( Logerrors )
ErrorLog( "Bad event: \"" + m_name + "\" (type: " + type() + ") can't find " + Targettype +" \"" + std::get<std::string>( target ) + "\"" );
}
}
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -294,16 +294,16 @@ enum TProblem // lista problemów taboru, które uniemożliwiają jazdę
/*lokacja*/ /*lokacja*/
struct TLocation struct TLocation
{ {
double X = 0.0; double X;
double Y = 0.0; double Y;
double Z = 0.0; double Z;
}; };
/*rotacja*/ /*rotacja*/
struct TRotation struct TRotation
{ {
double Rx = 0.0; double Rx;
double Ry = 0.0; double Ry;
double Rz = 0.0; double Rz;
}; };
/*wymiary*/ /*wymiary*/
struct TDimension struct TDimension
@@ -944,11 +944,19 @@ public:
double MED_EPVC_Time = 7; // czas korekcji sily hamowania EP, gdy nie ma dostepnego ED double MED_EPVC_Time = 7; // czas korekcji sily hamowania EP, gdy nie ma dostepnego ED
bool MED_Ncor = 0; // czy korekcja sily hamowania z uwzglednieniem nacisku bool MED_Ncor = 0; // czy korekcja sily hamowania z uwzglednieniem nacisku
/*-dla wagonow*/ /*-dla wagonow*/
struct load_attributes {
std::string name; // name of the cargo
float offset_min { 0.f }; // offset applied to cargo model when load amount is 0
load_attributes() = default;
load_attributes( std::string const &Name, float const Offsetmin ) :
name( Name ), offset_min( Offsetmin )
{}
};
std::vector<load_attributes> LoadAttributes;
float MaxLoad = 0.f; /*masa w T lub ilosc w sztukach - ladownosc*/ float MaxLoad = 0.f; /*masa w T lub ilosc w sztukach - ladownosc*/
std::string LoadAccepted; std::string LoadQuantity; /*co moze byc zaladowane, jednostki miary*/ double OverLoadFactor = 0.0; /*ile razy moze byc przekroczona ladownosc*/
double OverLoadFactor = 0.0; /*ile razy moze byc przekroczona ladownosc*/ float LoadSpeed = 0.f; float UnLoadSpeed = 0.f;/*szybkosc na- i rozladunku jednostki/s*/
float LoadMinOffset { 0.f }; // offset applied to cargo model when load amount is 0
float LoadSpeed = 0.f; float UnLoadSpeed = 0.f;/*szybkosc na- i rozladunku jednostki/s*/
int DoorOpenCtrl = 0; int DoorCloseCtrl = 0; /*0: przez pasazera, 1: przez maszyniste, 2: samoczynne (zamykanie)*/ int DoorOpenCtrl = 0; int DoorCloseCtrl = 0; /*0: przez pasazera, 1: przez maszyniste, 2: samoczynne (zamykanie)*/
double DoorStayOpen = 0.0; /*jak dlugo otwarte w przypadku DoorCloseCtrl=2*/ double DoorStayOpen = 0.0; /*jak dlugo otwarte w przypadku DoorCloseCtrl=2*/
bool DoorClosureWarning = false; /*czy jest ostrzeganie przed zamknieciem*/ bool DoorClosureWarning = false; /*czy jest ostrzeganie przed zamknieciem*/
@@ -965,8 +973,8 @@ public:
double SpeedCtrlDelay = 2; /*opoznienie dzialania tempomatu z wybieralna predkoscia*/ double SpeedCtrlDelay = 2; /*opoznienie dzialania tempomatu z wybieralna predkoscia*/
/*--sekcja zmiennych*/ /*--sekcja zmiennych*/
/*--opis konkretnego egzemplarza taboru*/ /*--opis konkretnego egzemplarza taboru*/
TLocation Loc; //pozycja pojazdów do wyznaczenia odległości pomiędzy sprzęgami TLocation Loc { 0.0, 0.0, 0.0 }; //pozycja pojazdów do wyznaczenia odległości pomiędzy sprzęgami
TRotation Rot; TRotation Rot { 0.0, 0.0, 0.0 };
std::string Name; /*nazwa wlasna*/ std::string Name; /*nazwa wlasna*/
TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami
#ifdef EU07_USE_OLD_HVCOUPLERS #ifdef EU07_USE_OLD_HVCOUPLERS
@@ -1167,9 +1175,10 @@ public:
double eAngle = M_PI * 0.5; double eAngle = M_PI * 0.5;
/*-dla wagonow*/ /*-dla wagonow*/
float Load = 0.f; /*masa w T lub ilosc w sztukach - zaladowane*/ float LoadAmount = 0.f; /*masa w T lub ilosc w sztukach - zaladowane*/
std::string LoadType; /*co jest zaladowane*/ load_attributes LoadType;
int LoadStatus = 0; //+1=trwa rozladunek,+2=trwa zaladunek,+4=zakończono,0=zaktualizowany model std::string LoadQuantity; // jednostki miary
int LoadStatus = 0; //+1=trwa rozladunek,+2=trwa zaladunek,+4=zakończono,0=zaktualizowany model
double LastLoadChangeTime = 0.0; //raz (roz)ładowania double LastLoadChangeTime = 0.0; //raz (roz)ładowania
bool DoorBlocked = false; //Czy jest blokada drzwi bool DoorBlocked = false; //Czy jest blokada drzwi
@@ -1211,7 +1220,7 @@ private:
double CouplerDist(int Coupler); double CouplerDist(int Coupler);
public: public:
TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int LoadInitial, std::string LoadTypeInitial, int Cab); TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int Cab);
// obsługa sprzęgów // obsługa sprzęgów
double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2); 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); /* double Distance(const vector3 &Loc1, const vector3 &Loc2, const vector3 &Dim1, const vector3 &Dim2);
@@ -1375,7 +1384,8 @@ public:
bool dizel_Update(double dt); bool dizel_Update(double dt);
/* funckje dla wagonow*/ /* funckje dla wagonow*/
bool LoadingDone(double LSpeed, std::string LoadInit); bool AssignLoad( std::string const &Name, float const Amount = 0.f );
bool LoadingDone(double LSpeed, std::string const &Loadname);
bool DoorLeft(bool State, range_t const Notify = range_t::consist ); //obsluga drzwi lewych bool DoorLeft(bool State, range_t const Notify = range_t::consist ); //obsluga drzwi lewych
bool DoorRight(bool State, range_t const Notify = range_t::consist ); //obsluga drzwi prawych bool DoorRight(bool State, range_t const Notify = range_t::consist ); //obsluga drzwi prawych
bool DoorBlockedFlag(void); //sprawdzenie blokady drzwi bool DoorBlockedFlag(void); //sprawdzenie blokady drzwi

View File

@@ -276,21 +276,14 @@ double TMoverParameters::Current(double n, double U)
// ************************************************************************************************* // *************************************************************************************************
// główny konstruktor // główny konstruktor
// ************************************************************************************************* // *************************************************************************************************
TMoverParameters::TMoverParameters(double VelInitial, std::string TypeNameInit, TMoverParameters::TMoverParameters(double VelInitial, std::string TypeNameInit, std::string NameInit, int Cab) :
std::string NameInit, int LoadInitial,
std::string LoadTypeInitial,
int Cab) ://: T_MoverParameters(VelInitial, TypeNameInit,
//NameInit, LoadInitial, LoadTypeInitial, Cab)
TypeName( TypeNameInit ), TypeName( TypeNameInit ),
Name( NameInit ), Name( NameInit ),
ActiveCab( Cab ), ActiveCab( Cab )
Load( LoadInitial ),
LoadType( LoadTypeInitial )
{ {
WriteLog( WriteLog(
"------------------------------------------------------"); "------------------------------------------------------");
WriteLog("init default physic values for " + NameInit + ", [" + TypeNameInit + "], [" + WriteLog("init default physic values for " + NameInit + ", [" + TypeNameInit + "]");
LoadTypeInitial + "]");
Dim = TDimension(); Dim = TDimension();
// BrakeLevelSet(-2); //Pascal ustawia na 0, przestawimy na odcięcie (CHK jest jeszcze nie wczytane!) // BrakeLevelSet(-2); //Pascal ustawia na 0, przestawimy na odcięcie (CHK jest jeszcze nie wczytane!)
@@ -352,10 +345,6 @@ LoadType( LoadTypeInitial )
} }
eimc[eimc_p_eped] = 1.5; eimc[eimc_p_eped] = 1.5;
// inicjalizacja zmiennych}
// Loc:=LocInitial; //Ra: to i tak trzeba potem przesunąć, po ustaleniu pozycji na torze
// (potrzebna długość)
// Rot:=RotInitial;
for (int b = 0; b < 2; ++b) for (int b = 0; b < 2; ++b)
{ {
Couplers[b].AllowedFlag = 3; // domyślnie hak i hamulec, inne trzeba włączyć jawnie w FIZ Couplers[b].AllowedFlag = 3; // domyślnie hak i hamulec, inne trzeba włączyć jawnie w FIZ
@@ -407,20 +396,6 @@ LoadType( LoadTypeInitial )
SecuritySystem.RadioStop = false; // domyślnie nie ma SecuritySystem.RadioStop = false; // domyślnie nie ma
SecuritySystem.AwareMinSpeed = 0.1 * Vmax; SecuritySystem.AwareMinSpeed = 0.1 * Vmax;
s_CAtestebrake = false; s_CAtestebrake = false;
// ABu 240105:
// CouplerNr[0]:=1;
// CouplerNr[1]:=0;
// TO POTEM TU UAKTYWNIC A WYWALIC Z CHECKPARAM}
//{
// if Pos(LoadTypeInitial,LoadAccepted)>0 then
// begin
//}
//{
// end
// else Load:=0;
// }
}; };
double TMoverParameters::Distance(const TLocation &Loc1, const TLocation &Loc2, double TMoverParameters::Distance(const TLocation &Loc1, const TLocation &Loc2,
@@ -1253,6 +1228,7 @@ double TMoverParameters::ComputeMovement(double dt, double dt1, const TTrackShap
OffsetTrackH = Sign(RunningShape.R) * 0.2; OffsetTrackH = Sign(RunningShape.R) * 0.2;
} }
// TODO: investigate, seems supplied NewRot is always 0 although the code here suggests some actual values are expected
Loc = NewLoc; Loc = NewLoc;
Rot = NewRot; Rot = NewRot;
NewRot.Rx = 0; NewRot.Rx = 0;
@@ -3755,27 +3731,25 @@ void TMoverParameters::ComputeConstans(void)
// ************************************************************************************************* // *************************************************************************************************
double TMoverParameters::ComputeMass(void) double TMoverParameters::ComputeMass(void)
{ {
double M; double M { 0.0 };
LoadType = ToLower(LoadType); // po co zakładać jak można mieć na pewno // TODO: unit weight table, pulled from external data file
if (Load > 0) if( LoadAmount > 0 ) {
{ // zakładamy, że ładunek jest pisany małymi literami
if (ToLower(LoadQuantity) == "tonns") if (ToLower(LoadQuantity) == "tonns")
M = Load * 1000; M = LoadAmount * 1000;
else if (LoadType == "passengers") else if (LoadType.name == "passengers")
M = Load * 80; M = LoadAmount * 80;
else if (LoadType == "luggage") else if (LoadType.name == "luggage")
M = Load * 100; M = LoadAmount * 100;
else if (LoadType == "cars") else if (LoadType.name == "cars")
M = Load * 1200; // 800 kilo to miał maluch M = LoadAmount * 1200; // 800 kilo to miał maluch
else if (LoadType == "containers") else if (LoadType.name == "containers")
M = Load * 8000; M = LoadAmount * 8000;
else if (LoadType == "transformers") else if (LoadType.name == "transformers")
M = Load * 50000; M = LoadAmount * 50000;
else else
M = Load * 1000; M = LoadAmount * 1000;
} }
else
M = 0;
// Ra: na razie tak, ale nie wszędzie masy wirujące się wliczają // Ra: na razie tak, ale nie wszędzie masy wirujące się wliczają
return Mass + M + Mred; return Mass + M + Mred;
} }
@@ -6455,58 +6429,105 @@ void TMoverParameters::dizel_Heat( double const dt ) {
*/ */
} }
bool
TMoverParameters::AssignLoad( std::string const &Name, float const Amount ) {
if( Name == "pantstate" ) {
if( EnginePowerSource.SourceType == TPowerSource::CurrentCollector ) {
// wartość niby "pantstate" - nazwa dla formalności, ważna jest ilość
auto const pantographsetup { static_cast<int>( Amount ) };
if( pantographsetup & ( 1 << 2 ) ) {
DoubleTr = -1;
}
if( pantographsetup & ( 1 << 0 ) ) {
if( DoubleTr == 1 ) { PantFront( true ); }
else { PantRear( true ); }
}
if( pantographsetup & ( 1 << 1 ) ) {
if( DoubleTr == 1 ) { PantRear( true ); }
else { PantFront( true ); }
}
return true;
}
else {
return false;
}
}
// can't mix load types, at least for the time being
if( ( LoadAmount > 0 ) && ( LoadType.name != Name ) ) { return false; }
if( Name.empty() ) {
// empty the vehicle
LoadType = load_attributes();
LoadAmount = 0.f;
return true;
}
for( auto const &loadattributes : LoadAttributes ) {
if( Name == loadattributes.name ) {
LoadType = loadattributes;
LoadAmount = Amount;
return true;
}
}
// didn't find matching load configuration, this type is unsupported
return false;
}
// ************************************************************************************************* // *************************************************************************************************
// Q: 20160713 // Q: 20160713
// Test zakończenia załadunku / rozładunku // Test zakończenia załadunku / rozładunku
// ************************************************************************************************* // *************************************************************************************************
bool TMoverParameters::LoadingDone(double LSpeed, std::string LoadInit) bool TMoverParameters::LoadingDone(double const LSpeed, std::string const &Loadname) {
{
// test zakończenia załadunku/rozładunku
long LoadChange = 0;
bool LD = false;
// ClearPendingExceptions; // zabezpieczenie dla Trunc() if( LSpeed == 0.0 ) {
// LoadingDone:=false; //nie zakończone // zerowa prędkość zmiany, to koniec
if (!LoadInit.empty()) // nazwa ładunku niepusta LoadStatus = 4;
{ return true;
if (Load > MaxLoad)
LoadChange = abs(long(LSpeed * LastLoadChangeTime / 2.0)); // przeładowanie?
else
LoadChange = abs(long(LSpeed * LastLoadChangeTime));
if (LSpeed < 0) // gdy rozładunek
{
LoadStatus = 2; // trwa rozładunek (włączenie naliczania czasu)
if (LoadChange != 0) // jeśli coś przeładowano
{
LastLoadChangeTime = 0; // naliczony czas został zużyty
Load -= LoadChange; // zmniejszenie ilości ładunku
CommandIn.Value1 =
CommandIn.Value1 - LoadChange; // zmniejszenie ilości do rozładowania
if (Load < 0)
Load = 0; //ładunek nie może być ujemny
if ((Load == 0) || (CommandIn.Value1 < 0)) // pusto lub rozładowano żądaną ilość
LoadStatus = 4; // skończony rozładunek
if (Load == 0)
LoadType.clear(); // jak nic nie ma, to nie ma też nazwy
}
}
else if (LSpeed > 0) // gdy załadunek
{
LoadStatus = 1; // trwa załadunek (włączenie naliczania czasu)
if (LoadChange != 0) // jeśli coś przeładowano
{
LastLoadChangeTime = 0; // naliczony czas został zużyty
LoadType = LoadInit; // nazwa
Load += LoadChange; // zwiększenie ładunku
CommandIn.Value1 = CommandIn.Value1 - LoadChange;
if ((Load >= MaxLoad * (1.0 + OverLoadFactor)) || (CommandIn.Value1 < 0))
LoadStatus = 4; // skończony załadunek
}
}
else
LoadStatus = 4; // zerowa prędkość zmiany, to koniec
} }
return (LoadStatus >= 4);
if( Loadname.empty() ) { return ( LoadStatus >= 4 ); }
if( Loadname != LoadType.name ) { return ( LoadStatus >= 4 ); }
// test zakończenia załadunku/rozładunku
// load exchange speed is reduced if the wagon is overloaded
auto const loadchange { static_cast<float>( std::abs( LSpeed * LastLoadChangeTime ) * ( LoadAmount > MaxLoad ? 0.5 : 1.0 ) ) };
if( LSpeed < 0 ) {
// gdy rozładunek
LoadStatus = 2; // trwa rozładunek (włączenie naliczania czasu)
if( loadchange > 0 ) // jeśli coś przeładowano
{
LastLoadChangeTime = 0; // naliczony czas został zużyty
LoadAmount -= loadchange; // zmniejszenie ilości ładunku
CommandIn.Value1 -= loadchange; // zmniejszenie ilości do rozładowania
if( ( LoadAmount <= 0 ) || ( CommandIn.Value1 <= 0 ) ) {
// pusto lub rozładowano żądaną ilość
LoadStatus = 4; // skończony rozładunek
LoadAmount = std::max( 0.f, LoadAmount ); //ładunek nie może być ujemny
}
if( LoadAmount == 0.f ) {
AssignLoad(""); // jak nic nie ma, to nie ma też nazwy
}
}
}
else if( LSpeed > 0 ) {
// gdy załadunek
LoadStatus = 1; // trwa załadunek (włączenie naliczania czasu)
if( loadchange > 0 ) // jeśli coś przeładowano
{
LastLoadChangeTime = 0; // naliczony czas został zużyty
LoadAmount += loadchange; // zwiększenie ładunku
CommandIn.Value1 -= loadchange;
if( ( LoadAmount >= MaxLoad * ( 1.0 + OverLoadFactor ) ) || ( CommandIn.Value1 <= 0 ) ) {
LoadStatus = 4; // skończony załadunek
LoadAmount = std::min<float>( MaxLoad * ( 1.0 + OverLoadFactor ), LoadAmount );
}
}
}
return ( LoadStatus >= 4 );
} }
// ************************************************************************************************* // *************************************************************************************************
@@ -7590,19 +7611,30 @@ void TMoverParameters::LoadFIZ_Param( std::string const &line ) {
void TMoverParameters::LoadFIZ_Load( std::string const &line ) { void TMoverParameters::LoadFIZ_Load( std::string const &line ) {
extract_value( LoadAccepted, "LoadAccepted", line, "" ); auto const acceptedloads { Split( extract_value( "LoadAccepted", line ), ',' ) };
if( true == LoadAccepted.empty() ) {
return; if( acceptedloads.empty() ) { return; }
auto const minoffsets { Split( extract_value( "LoadMinOffset", line ), ',' ) };
auto minoffset { 0.f };
auto minoffsetsiterator { std::begin( minoffsets ) };
// NOTE: last (if any) offset parameter retrieved from the list applies to the remainder of the list
// TBD, TODO: include other load parameters in this system
for( auto &load : acceptedloads ) {
if( minoffsetsiterator != std::end( minoffsets ) ) {
minoffset = std::stof( *minoffsetsiterator );
++minoffsetsiterator;
}
LoadAttributes.emplace_back(
ToLower( load ),
minoffset );
} }
LoadAccepted = ToLower( LoadAccepted );
extract_value( MaxLoad, "MaxLoad", line, "" ); extract_value( MaxLoad, "MaxLoad", line, "" );
extract_value( LoadQuantity, "LoadQ", line, "" ); extract_value( LoadQuantity, "LoadQ", line, "" );
extract_value( OverLoadFactor, "OverLoadFactor", line, "" ); extract_value( OverLoadFactor, "OverLoadFactor", line, "" );
extract_value( LoadSpeed, "LoadSpeed", line, "" ); extract_value( LoadSpeed, "LoadSpeed", line, "" );
extract_value( UnLoadSpeed, "UnLoadSpeed", line, "" ); extract_value( UnLoadSpeed, "UnLoadSpeed", line, "" );
extract_value( LoadMinOffset, "LoadMinOffset", line, "" );
} }
void TMoverParameters::LoadFIZ_Dimensions( std::string const &line ) { void TMoverParameters::LoadFIZ_Dimensions( std::string const &line ) {
@@ -8648,11 +8680,6 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
// WriteLogSS("aa ok", BoolToYN(OK)); // WriteLogSS("aa ok", BoolToYN(OK));
} }
if( ( LoadType.empty() == false ) && ( LoadAccepted.find( LoadType ) == std::string::npos ) ) {
// remove load if the type isn't supported
Load = 0.0;
}
if (BrakeSystem == TBrakeSystem::Individual) if (BrakeSystem == TBrakeSystem::Individual)
if (BrakeSubsystem != TBrakeSubSystem::ss_None) if (BrakeSubsystem != TBrakeSubSystem::ss_None)
OK = false; //! OK = false; //!
@@ -8886,16 +8913,16 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
if( LoadFlag > 0 ) { if( LoadFlag > 0 ) {
if( Load < MaxLoad * 0.45 ) { if( LoadAmount < MaxLoad * 0.45 ) {
IncBrakeMult(); IncBrakeMult();
IncBrakeMult(); IncBrakeMult();
DecBrakeMult(); // TODO: przeinesiono do mover.cpp DecBrakeMult(); // TODO: przeinesiono do mover.cpp
if( Load < MaxLoad * 0.35 ) if( LoadAmount < MaxLoad * 0.35 )
DecBrakeMult(); DecBrakeMult();
} }
else { else {
IncBrakeMult(); // TODO: przeinesiono do mover.cpp IncBrakeMult(); // TODO: przeinesiono do mover.cpp
if( Load >= MaxLoad * 0.55 ) if( LoadAmount >= MaxLoad * 0.55 )
IncBrakeMult(); IncBrakeMult();
} }
} }
@@ -9476,39 +9503,44 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
OK = true; // true, gdy można usunąć komendę OK = true; // true, gdy można usunąć komendę
} }
/*naladunek/rozladunek*/ /*naladunek/rozladunek*/
else if ( issection( "Load=", Command ) ) // TODO: have these commands leverage load exchange system instead
else if ( issection( "Load=", Command ) )
{ {
OK = false; // będzie powtarzane aż się załaduje OK = false; // będzie powtarzane aż się załaduje
if( ( Vel < 0.01 ) if( ( Vel < 0.1 ) // tolerance margin for small vehicle movements in the consist
&& ( MaxLoad > 0 ) && ( MaxLoad > 0 )
&& ( Load < MaxLoad * ( 1.0 + OverLoadFactor ) ) ) { && ( LoadAmount < MaxLoad * ( 1.0 + OverLoadFactor ) )
// czy można ładowac? && ( Distance( Loc, CommandIn.Location, Dim, Dim ) < 10 ) ) { // ten peron/rampa
if( Distance( Loc, CommandIn.Location, Dim, Dim ) < 10 ) {
// ten peron/rampa auto const loadname { ToLower( extract_value( "Load", Command ) ) };
auto const testload { ToLower( extract_value( "Load", Command ) ) }; if( LoadAmount == 0.f ) {
if( LoadAccepted.find( testload ) != std::string::npos ) // nazwa jest obecna w CHK AssignLoad( loadname );
OK = LoadingDone( Min0R( CValue2, LoadSpeed ), testload ); // zmienia LoadStatus
} }
OK = LoadingDone(
std::min<float>( CValue2, LoadSpeed ),
loadname ); // zmienia LoadStatus
}
else {
// no loading can be done if conditions aren't met
LastLoadChangeTime = 0.0;
} }
// if OK then LoadStatus:=0; //nie udalo sie w ogole albo juz skonczone
} }
else if( issection( "UnLoad=", Command ) ) else if( issection( "UnLoad=", Command ) )
{ {
OK = false; // będzie powtarzane aż się rozładuje OK = false; // będzie powtarzane aż się rozładuje
if( ( Vel < 0.01 ) if( ( Vel < 0.1 ) // tolerance margin for small vehicle movements in the consist
&& ( Load > 0 ) ) { && ( LoadAmount > 0 ) // czy jest co rozladowac?
// czy jest co rozladowac? && ( Distance( Loc, CommandIn.Location, Dim, Dim ) < 10 ) ) { // ten peron
if( Distance( Loc, CommandIn.Location, Dim, Dim ) < 10 ) { /*mozna to rozladowac*/
// ten peron OK = LoadingDone(
auto const testload { ToLower( extract_value( "UnLoad", Command ) ) }; // zgodność nazwy ładunku z CHK -1.f * std::min<float>( CValue2, LoadSpeed ),
if( LoadType == testload ) { ToLower( extract_value( "UnLoad", Command ) ) );
/*mozna to rozladowac*/
OK = LoadingDone( -Min0R( CValue2, LoadSpeed ), testload );
}
}
} }
// if OK then LoadStatus:=0; else {
} // no loading can be done if conditions aren't met
LastLoadChangeTime = 0.0;
}
}
else if (Command == "SpeedCntrl") else if (Command == "SpeedCntrl")
{ {
if ((EngineType == TEngineType::ElectricInductionMotor)) if ((EngineType == TEngineType::ElectricInductionMotor))

View File

@@ -25,25 +25,25 @@ TMemCell::TMemCell( scene::node_data const &Nodedata ) : basic_node( Nodedata )
void TMemCell::UpdateValues( std::string const &szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask ) void TMemCell::UpdateValues( std::string const &szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask )
{ {
if (CheckMask & update_memadd) if (CheckMask & basic_event::flags::mode_add)
{ // dodawanie wartości { // dodawanie wartości
if( TestFlag( CheckMask, update_memstring ) ) if( TestFlag( CheckMask, basic_event::flags::text ) )
szText += szNewText; szText += szNewText;
if (TestFlag(CheckMask, update_memval1)) if (TestFlag(CheckMask, basic_event::flags::value_1))
fValue1 += fNewValue1; fValue1 += fNewValue1;
if (TestFlag(CheckMask, update_memval2)) if (TestFlag(CheckMask, basic_event::flags::value_2))
fValue2 += fNewValue2; fValue2 += fNewValue2;
} }
else else
{ {
if( TestFlag( CheckMask, update_memstring ) ) if( TestFlag( CheckMask, basic_event::flags::text ) )
szText = szNewText; szText = szNewText;
if (TestFlag(CheckMask, update_memval1)) if (TestFlag(CheckMask, basic_event::flags::value_1))
fValue1 = fNewValue1; fValue1 = fNewValue1;
if (TestFlag(CheckMask, update_memval2)) if (TestFlag(CheckMask, basic_event::flags::value_2))
fValue2 = fNewValue2; fValue2 = fNewValue2;
} }
if (TestFlag(CheckMask, update_memstring)) if (TestFlag(CheckMask, basic_event::flags::text))
CommandCheck(); // jeśli zmieniony tekst, próbujemy rozpoznać komendę CommandCheck(); // jeśli zmieniony tekst, próbujemy rozpoznać komendę
} }
@@ -110,15 +110,15 @@ bool TMemCell::Load(cParser *parser)
return true; return true;
} }
void TMemCell::PutCommand( TController *Mech, glm::dvec3 const *Loc ) void TMemCell::PutCommand( TController *Mech, glm::dvec3 const *Loc ) const
{ // wysłanie zawartości komórki do AI { // wysłanie zawartości komórki do AI
if (Mech) if (Mech)
Mech->PutCommand(szText, fValue1, fValue2, Loc); Mech->PutCommand(szText, fValue1, fValue2, Loc);
} }
bool TMemCell::Compare( std::string const &szTestText, double const fTestValue1, double const fTestValue2, int const CheckMask ) { bool TMemCell::Compare( std::string const &szTestText, double const fTestValue1, double const fTestValue2, int const CheckMask ) const {
// porównanie zawartości komórki pamięci z podanymi wartościami // porównanie zawartości komórki pamięci z podanymi wartościami
if( TestFlag( CheckMask, conditional_memstring ) ) { if( TestFlag( CheckMask, basic_event::flags::text ) ) {
// porównać teksty // porównać teksty
auto range = szTestText.find( '*' ); auto range = szTestText.find( '*' );
if( range != std::string::npos ) { if( range != std::string::npos ) {
@@ -135,8 +135,8 @@ bool TMemCell::Compare( std::string const &szTestText, double const fTestValue1,
} }
} }
// tekst zgodny, porównać resztę // tekst zgodny, porównać resztę
return ( ( !TestFlag( CheckMask, conditional_memval1 ) || ( fValue1 == fTestValue1 ) ) return ( ( !TestFlag( CheckMask, basic_event::flags::value_1 ) || ( fValue1 == fTestValue1 ) )
&& ( !TestFlag( CheckMask, conditional_memval2 ) || ( fValue2 == fTestValue2 ) ) ); && ( !TestFlag( CheckMask, basic_event::flags::value_2 ) || ( fValue2 == fTestValue2 ) ) );
}; };
bool TMemCell::IsVelocity() const bool TMemCell::IsVelocity() const
@@ -159,7 +159,7 @@ void TMemCell::StopCommandSent()
} }
}; };
void TMemCell::AssignEvents(TEvent *e) void TMemCell::AssignEvents(basic_event *e)
{ // powiązanie eventu { // powiązanie eventu
OnSent = e; OnSent = e;
}; };
@@ -192,7 +192,7 @@ TMemCell::export_as_text_( std::ostream &Output ) const {
<< fValue1 << ' ' << fValue1 << ' '
<< fValue2 << ' ' << fValue2 << ' '
// associated track // associated track
<< ( asTrackName.empty() ? "none" : asTrackName ) << ' ' << ( Track ? Track->name() : asTrackName.empty() ? "none" : asTrackName ) << ' '
// footer // footer
<< "endmemcell" << "endmemcell"
<< "\n"; << "\n";
@@ -208,6 +208,13 @@ memory_table::InitCells() {
for( auto *cell : m_items ) { for( auto *cell : m_items ) {
// Ra: eventy komórek pamięci, wykonywane po wysłaniu komendy do zatrzymanego pojazdu // Ra: eventy komórek pamięci, wykonywane po wysłaniu komendy do zatrzymanego pojazdu
cell->AssignEvents( simulation::Events.FindEvent( cell->name() + ":sent" ) ); cell->AssignEvents( simulation::Events.FindEvent( cell->name() + ":sent" ) );
// bind specified path with the memory cell
if( false == cell->asTrackName.empty() ) {
cell->Track = simulation::Paths.find( cell->asTrackName );
if( cell->Track == nullptr ) {
ErrorLog( "Bad memcell: track \"" + cell->asTrackName + "\" referenced in memcell \"" + cell->name() + "\" doesn't exist" );
}
}
} }
} }

View File

@@ -16,19 +16,17 @@ http://mozilla.org/MPL/2.0/.
class TMemCell : public scene::basic_node { class TMemCell : public scene::basic_node {
public: public:
std::string asTrackName; // McZapkie-100302 - zeby nazwe toru na ktory jest Putcommand wysylane pamietac // constructors
bool is_exportable { true }; // export helper; autogenerated cells don't need to be exported
explicit TMemCell( scene::node_data const &Nodedata ); explicit TMemCell( scene::node_data const &Nodedata );
// methods
void void
UpdateValues( std::string const &szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask ); UpdateValues( std::string const &szNewText, double const fNewValue1, double const fNewValue2, int const CheckMask );
bool bool
Load(cParser *parser); Load(cParser *parser);
void void
PutCommand( TController *Mech, glm::dvec3 const *Loc ); PutCommand( TController *Mech, glm::dvec3 const *Loc ) const;
bool bool
Compare( std::string const &szTestText, double const fTestValue1, double const fTestValue2, int const CheckMask ); Compare( std::string const &szTestText, double const fTestValue1, double const fTestValue2, int const CheckMask ) const;
std::string const & std::string const &
Text() const { Text() const {
return szText; } return szText; }
@@ -47,7 +45,11 @@ public:
void StopCommandSent(); void StopCommandSent();
TCommandType CommandCheck(); TCommandType CommandCheck();
bool IsVelocity() const; bool IsVelocity() const;
void AssignEvents(TEvent *e); void AssignEvents(basic_event *e);
// members
std::string asTrackName; // McZapkie-100302 - zeby nazwe toru na ktory jest Putcommand wysylane pamietac
TTrack *Track { nullptr }; // resolved binding with the specified track
bool is_exportable { true }; // export helper; autogenerated cells don't need to be exported
private: private:
// methods // methods
@@ -66,7 +68,7 @@ private:
// other // other
TCommandType eCommand { TCommandType::cm_Unknown }; TCommandType eCommand { TCommandType::cm_Unknown };
bool bCommand { false }; // czy zawiera komendę dla zatrzymanego AI bool bCommand { false }; // czy zawiera komendę dla zatrzymanego AI
TEvent *OnSent { nullptr }; // event dodawany do kolejki po wysłaniu komendy zatrzymującej skład basic_event *OnSent { nullptr }; // event dodawany do kolejki po wysłaniu komendy zatrzymującej skład
}; };

View File

@@ -80,12 +80,12 @@ TSubModel::SetLightLevel( float const Level, bool const Includechildren, bool co
if( true == Includesiblings ) { if( true == Includesiblings ) {
auto sibling { this }; auto sibling { this };
while( ( sibling = sibling->Next ) != nullptr ) { while( ( sibling = sibling->Next ) != nullptr ) {
sibling->f4Emision.a = Level; sibling->SetLightLevel( Level, Includechildren, false ); // no need for all siblings to duplicate the work
} }
} }
if( ( true == Includechildren ) if( ( true == Includechildren )
&& ( Child != nullptr ) ) { && ( Child != nullptr ) ) {
Child->SetLightLevel( Level, true, true ); // node's children include child's siblings and children Child->SetLightLevel( Level, Includechildren, true ); // node's children include child's siblings and children
} }
} }
@@ -955,14 +955,16 @@ void TSubModel::RaAnimation(glm::mat4 &m, TAnimType a)
case TAnimType::at_DigiClk: // animacja zegara cyfrowego case TAnimType::at_DigiClk: // animacja zegara cyfrowego
{ // ustawienie animacji w submodelach potomnych { // ustawienie animacji w submodelach potomnych
TSubModel *sm = ChildGet(); TSubModel *sm = ChildGet();
do do { // pętla po submodelach potomnych i obracanie ich o kąt zależy od czasu
{ // pętla po submodelach potomnych i obracanie ich o kąt zależy od czasu if( sm->pName.size() ) {
if (sm->pName.size()) // musi mieć niepustą nazwę
{ // musi mieć niepustą nazwę if( ( sm->pName[ 0 ] >= '0' )
if ((sm->pName[0]) >= '0') && ( sm->pName[ 0 ] <= '5') ) {
if ((sm->pName[0]) <= '5') // zegarek ma 6 cyfr maksymalnie // zegarek ma 6 cyfr maksymalnie
sm->SetRotate(float3(0, 1, 0), sm->SetRotate(
-Global.fClockAngleDeg[(sm->pName[0]) - '0']); float3( 0, 1, 0 ),
-Global.fClockAngleDeg[ sm->pName[ 0 ] - '0' ] );
}
} }
sm = sm->NextGet(); sm = sm->NextGet();
} while (sm); } while (sm);

View File

@@ -43,7 +43,7 @@ public:
} }
// locates item with specified name. returns pointer to the item, or nullptr // locates item with specified name. returns pointer to the item, or nullptr
Type_ * Type_ *
find( std::string const &Name ) { find( std::string const &Name ) const {
auto lookup = m_itemmap.find( Name ); auto lookup = m_itemmap.find( Name );
return ( return (
lookup != m_itemmap.end() ? lookup != m_itemmap.end() ?

View File

@@ -124,7 +124,7 @@ void TIsolated::Modify(int i, TDynamicObject *o)
multiplayer::WyslijString(asName, 10); // wysłanie pakietu o zwolnieniu multiplayer::WyslijString(asName, 10); // wysłanie pakietu o zwolnieniu
if (pMemCell) // w powiązanej komórce if (pMemCell) // w powiązanej komórce
pMemCell->UpdateValues( "", 0, int( pMemCell->Value2() ) & ~0xFF, pMemCell->UpdateValues( "", 0, int( pMemCell->Value2() ) & ~0xFF,
update_memval2 ); //"zerujemy" ostatnią wartość basic_event::flags::value_2 ); //"zerujemy" ostatnią wartość
} }
} }
else else
@@ -137,7 +137,7 @@ void TIsolated::Modify(int i, TDynamicObject *o)
if (Global.iMultiplayer) // jeśli multiplayer if (Global.iMultiplayer) // jeśli multiplayer
multiplayer::WyslijString(asName, 11); // wysłanie pakietu o zajęciu multiplayer::WyslijString(asName, 11); // wysłanie pakietu o zajęciu
if (pMemCell) // w powiązanej komórce if (pMemCell) // w powiązanej komórce
pMemCell->UpdateValues( "", 0, int( pMemCell->Value2() ) | 1, update_memval2 ); // zmieniamy ostatnią wartość na nieparzystą pMemCell->UpdateValues( "", 0, int( pMemCell->Value2() ) | 1, basic_event::flags::value_2 ); // zmieniamy ostatnią wartość na nieparzystą
} }
} }
// pass the event to the parent // pass the event to the parent
@@ -909,7 +909,7 @@ bool TTrack::AssignEvents() {
m_events = true; m_events = true;
} }
else { else {
ErrorLog( "Bad event: event \"" + event.first + "\" assigned to track \"" + m_name + "\" does not exist" ); ErrorLog( "Bad track: \"" + m_name + "\" can't find assigned event \"" + event.first + "\"" );
lookupfail = true; lookupfail = true;
} }
} }
@@ -933,7 +933,7 @@ bool TTrack::AssignEvents() {
return ( lookupfail == false ); return ( lookupfail == false );
} }
bool TTrack::AssignForcedEvents(TEvent *NewEventPlus, TEvent *NewEventMinus) bool TTrack::AssignForcedEvents(basic_event *NewEventPlus, basic_event *NewEventMinus)
{ // ustawienie eventów sygnalizacji rozprucia { // ustawienie eventów sygnalizacji rozprucia
if (SwitchExtension) if (SwitchExtension)
{ {
@@ -959,7 +959,7 @@ void TTrack::QueueEvents( event_sequence const &Events, TDynamicObject const *Ow
for( auto const &event : Events ) { for( auto const &event : Events ) {
if( ( event.second != nullptr ) if( ( event.second != nullptr )
&& ( event.second->fDelay <= Delaylimit) ) { && ( event.second->m_delay <= Delaylimit) ) {
simulation::Events.AddToQuery( event.second, Owner ); simulation::Events.AddToQuery( event.second, Owner );
} }
} }
@@ -1115,7 +1115,7 @@ bool TTrack::InMovement()
return false; return false;
}; };
void TTrack::RaAssign( TAnimModel *am, TEvent *done, TEvent *joined ) void TTrack::RaAssign( TAnimModel *am, basic_event *done, basic_event *joined )
{ // Ra: wiązanie toru z modelem obrotnicy { // Ra: wiązanie toru z modelem obrotnicy
if (eType == tt_Table) if (eType == tt_Table)
{ {
@@ -2839,7 +2839,7 @@ TTrack::export_as_text_( std::ostream &Output ) const {
Output Output
<< eventsequence.first << ' ' << eventsequence.first << ' '
<< ( event.second != nullptr ? << ( event.second != nullptr ?
event.second->asName : event.second->m_name :
event.first ) event.first )
<< ' '; << ' ';
} }

14
Track.h
View File

@@ -44,7 +44,7 @@ enum TEnvironmentType {
}; };
// Ra: opracować alternatywny system cieni/świateł z definiowaniem koloru oświetlenia w halach // Ra: opracować alternatywny system cieni/świateł z definiowaniem koloru oświetlenia w halach
class TEvent; class basic_event;
class TTrack; class TTrack;
class TGroundNode; class TGroundNode;
class TSubRect; class TSubRect;
@@ -89,7 +89,7 @@ class TSwitchExtension
bool bMovement = false; // czy w trakcie animacji bool bMovement = false; // czy w trakcie animacji
scene::basic_cell *pOwner = nullptr; // TODO: convert this to observer pattern scene::basic_cell *pOwner = nullptr; // TODO: convert this to observer pattern
TTrack *pNextAnim = nullptr; // następny tor do animowania TTrack *pNextAnim = nullptr; // następny tor do animowania
TEvent *evPlus = nullptr, basic_event *evPlus = nullptr,
*evMinus = nullptr; // zdarzenia sygnalizacji rozprucia *evMinus = nullptr; // zdarzenia sygnalizacji rozprucia
float fVelocity = -1.0; // maksymalne ograniczenie prędkości (ustawianej eventem) float fVelocity = -1.0; // maksymalne ograniczenie prędkości (ustawianej eventem)
Math3D::vector3 vTrans; // docelowa translacja przesuwnicy Math3D::vector3 vTrans; // docelowa translacja przesuwnicy
@@ -127,8 +127,8 @@ public:
return pParent; } return pParent; }
// members // members
std::string asName; // nazwa obiektu, baza do nazw eventów std::string asName; // nazwa obiektu, baza do nazw eventów
TEvent *evBusy { nullptr }; // zdarzenie wyzwalane po zajęciu grupy basic_event *evBusy { nullptr }; // zdarzenie wyzwalane po zajęciu grupy
TEvent *evFree { nullptr }; // zdarzenie wyzwalane po całkowitym zwolnieniu zajętości grupy basic_event *evFree { nullptr }; // zdarzenie wyzwalane po całkowitym zwolnieniu zajętości grupy
TMemCell *pMemCell { nullptr }; // automatyczna komórka pamięci, która współpracuje z odcinkiem izolowanym TMemCell *pMemCell { nullptr }; // automatyczna komórka pamięci, która współpracuje z odcinkiem izolowanym
private: private:
// members // members
@@ -175,7 +175,7 @@ private:
public: public:
using dynamics_sequence = std::deque<TDynamicObject *>; using dynamics_sequence = std::deque<TDynamicObject *>;
using event_sequence = std::vector<std::pair<std::string, TEvent *> >; using event_sequence = std::vector<std::pair<std::string, basic_event *> >;
dynamics_sequence Dynamics; dynamics_sequence Dynamics;
event_sequence event_sequence
@@ -251,7 +251,7 @@ public:
1 ); } 1 ); }
void Load(cParser *parser, glm::dvec3 const &pOrigin); void Load(cParser *parser, glm::dvec3 const &pOrigin);
bool AssignEvents(); bool AssignEvents();
bool AssignForcedEvents(TEvent *NewEventPlus, TEvent *NewEventMinus); bool AssignForcedEvents(basic_event *NewEventPlus, basic_event *NewEventMinus);
void QueueEvents( event_sequence const &Events, TDynamicObject const *Owner ); void QueueEvents( event_sequence const &Events, TDynamicObject const *Owner );
void QueueEvents( event_sequence const &Events, TDynamicObject const *Owner, double const Delaylimit ); void QueueEvents( event_sequence const &Events, TDynamicObject const *Owner, double const Delaylimit );
bool CheckDynamicObject(TDynamicObject *Dynamic); bool CheckDynamicObject(TDynamicObject *Dynamic);
@@ -272,7 +272,7 @@ public:
void RaOwnerSet( scene::basic_cell *o ) { void RaOwnerSet( scene::basic_cell *o ) {
if( SwitchExtension ) { SwitchExtension->pOwner = o; } }; if( SwitchExtension ) { SwitchExtension->pOwner = o; } };
bool InMovement(); // czy w trakcie animacji? bool InMovement(); // czy w trakcie animacji?
void RaAssign( TAnimModel *am, TEvent *done, TEvent *joined ); void RaAssign( TAnimModel *am, basic_event *done, basic_event *joined );
void RaAnimListAdd(TTrack *t); void RaAnimListAdd(TTrack *t);
TTrack * RaAnimate(); TTrack * RaAnimate();

View File

@@ -601,6 +601,7 @@ TTrain::get_state() const {
btHaslerBrakes.GetValue(), btHaslerBrakes.GetValue(),
btHaslerCurrent.GetValue(), btHaslerCurrent.GetValue(),
( TestFlag( mvOccupied->SecuritySystem.Status, s_CAalarm ) || TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ), ( TestFlag( mvOccupied->SecuritySystem.Status, s_CAalarm ) || TestFlag( mvOccupied->SecuritySystem.Status, s_SHPalarm ) ),
btLampkaHVoltageB.GetValue(),
fTachoVelocity, fTachoVelocity,
static_cast<float>( mvOccupied->Compressor ), static_cast<float>( mvOccupied->Compressor ),
static_cast<float>( mvOccupied->PipePress ), static_cast<float>( mvOccupied->PipePress ),
@@ -3741,7 +3742,7 @@ void TTrain::OnCommand_generictoggle( TTrain *Train, command_data const &Command
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
// only reacting to press, so the switch doesn't flip back and forth if key is held down // only reacting to press, so the switch doesn't flip back and forth if key is held down
if( item.GetValue() < 0.25 ) { if( item.GetDesiredValue() < 0.5 ) {
// turn on // turn on
// visual feedback // visual feedback
item.UpdateValue( 1.0, Train->dsbSwitch ); item.UpdateValue( 1.0, Train->dsbSwitch );

View File

@@ -85,6 +85,7 @@ class TTrain
std::uint8_t recorder_braking; std::uint8_t recorder_braking;
std::uint8_t recorder_power; std::uint8_t recorder_power;
std::uint8_t alerter_sound; std::uint8_t alerter_sound;
std::uint8_t coupled_hv_voltage_relays;
float velocity; float velocity;
float reservoir_pressure; float reservoir_pressure;
float pipe_pressure; float pipe_pressure;

View File

@@ -200,7 +200,7 @@ commanddescription_sequence Commands_descriptions = {
{ "instrumentlighttoggle", command_target::vehicle, command_mode::oneoff }, { "instrumentlighttoggle", command_target::vehicle, command_mode::oneoff },
{ "instrumentlightenable", command_target::vehicle, command_mode::oneoff }, { "instrumentlightenable", command_target::vehicle, command_mode::oneoff },
{ "instrumentlightdisable", command_target::vehicle, command_mode::oneoff }, { "instrumentlightdisable", command_target::vehicle, command_mode::oneoff },
{ "dshboardlighttoggle", command_target::vehicle, command_mode::oneoff }, { "dashboardlighttoggle", command_target::vehicle, command_mode::oneoff },
{ "timetablelighttoggle", command_target::vehicle, command_mode::oneoff }, { "timetablelighttoggle", command_target::vehicle, command_mode::oneoff },
{ "generictoggle0", command_target::vehicle, command_mode::oneoff }, { "generictoggle0", command_target::vehicle, command_mode::oneoff },
{ "generictoggle1", command_target::vehicle, command_mode::oneoff }, { "generictoggle1", command_target::vehicle, command_mode::oneoff },

View File

@@ -80,7 +80,7 @@ private:
// members // members
drivermode_input m_input; drivermode_input m_input;
std::array<TEvent *, 10> KeyEvents { nullptr }; // eventy wyzwalane z klawiaury std::array<basic_event *, 10> KeyEvents { nullptr }; // eventy wyzwalane z klawiaury
TCamera Camera; TCamera Camera;
TCamera DebugCamera; TCamera DebugCamera;
TDynamicObject *pDynamicNearest { nullptr }; // vehicle nearest to the active camera. TODO: move to camera TDynamicObject *pDynamicNearest { nullptr }; // vehicle nearest to the active camera. TODO: move to camera

View File

@@ -385,8 +385,8 @@ debug_panel::update_section_vehicle( std::vector<text_line> &Output ) {
locale::strings[ locale::string::debug_vehicle_nameloadstatuscouplers ].c_str(), locale::strings[ locale::string::debug_vehicle_nameloadstatuscouplers ].c_str(),
mover.Name.c_str(), mover.Name.c_str(),
std::string( isowned ? locale::strings[ locale::string::debug_vehicle_owned ].c_str() + vehicle.ctOwner->OwnerName() : "" ).c_str(), std::string( isowned ? locale::strings[ locale::string::debug_vehicle_owned ].c_str() + vehicle.ctOwner->OwnerName() : "" ).c_str(),
mover.Load, mover.LoadAmount,
mover.LoadType.c_str(), mover.LoadType.name.c_str(),
mover.EngineDescription( 0 ).c_str(), mover.EngineDescription( 0 ).c_str(),
// TODO: put wheel flat reporting in the enginedescription() // TODO: put wheel flat reporting in the enginedescription()
std::string( mover.WheelFlat > 0.01 ? " Flat: " + to_string( mover.WheelFlat, 1 ) + " mm" : "" ).c_str(), std::string( mover.WheelFlat > 0.01 ? " Flat: " + to_string( mover.WheelFlat, 1 ) + " mm" : "" ).c_str(),
@@ -684,7 +684,7 @@ debug_panel::update_section_ai( std::vector<text_line> &Output ) {
if( ( mechanik.VelNext == 0.0 ) if( ( mechanik.VelNext == 0.0 )
&& ( mechanik.eSignNext ) ) { && ( mechanik.eSignNext ) ) {
// jeśli ma zapamiętany event semafora, nazwa eventu semafora // jeśli ma zapamiętany event semafora, nazwa eventu semafora
Output.emplace_back( "Current signal: " + Bezogonkow( mechanik.eSignNext->asName ), Global.UITextColor ); Output.emplace_back( "Current signal: " + Bezogonkow( mechanik.eSignNext->m_name ), Global.UITextColor );
} }
// distances // distances
@@ -805,19 +805,19 @@ debug_panel::update_section_eventqueue( std::vector<text_line> &Output ) {
&& ( eventtableindex < 30 ) ) { && ( eventtableindex < 30 ) ) {
if( ( false == event->m_ignored ) if( ( false == event->m_ignored )
&& ( true == event->bEnabled ) ) { && ( false == event->m_passive ) ) {
auto const delay { " " + to_string( std::max( 0.0, event->fStartTime - time ), 1 ) }; auto const delay { " " + to_string( std::max( 0.0, event->m_launchtime - time ), 1 ) };
textline = textline =
"Delay: " + delay.substr( delay.length() - 6 ) "Delay: " + delay.substr( delay.length() - 6 )
+ ", Event: " + event->asName + ", Event: " + event->m_name
+ ( event->Activator ? " (by: " + event->Activator->asName + ")" : "" ) + ( event->m_activator ? " (by: " + event->m_activator->asName + ")" : "" )
+ ( event->evJoined ? " (joint event)" : "" ); + ( event->m_sibling ? " (joint event)" : "" );
Output.emplace_back( textline, Global.UITextColor ); Output.emplace_back( textline, Global.UITextColor );
++eventtableindex; ++eventtableindex;
} }
event = event->evNext; event = event->m_next;
} }
if( Output.empty() ) { if( Output.empty() ) {
textline = "(no queued events)"; textline = "(no queued events)";

View File

@@ -148,7 +148,7 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
} }
textline += ( textline += (
event.second != nullptr ? event.second != nullptr ?
event.second->asName : event.second->m_name :
event.first + " (missing)" ); event.first + " (missing)" );
} }
textline += "] "; textline += "] ";

26
lua.cpp
View File

@@ -66,25 +66,23 @@ int lua::openffi(lua_State *s)
extern "C" extern "C"
{ {
EXPORT TEvent* scriptapi_event_create(const char* name, double delay, double randomdelay, lua::eventhandler_t handler) EXPORT basic_event* scriptapi_event_create(const char* name, double delay, double randomdelay, lua::eventhandler_t handler)
{ {
TEvent *event = new TEvent(); basic_event *event = new lua_event(handler);
event->bEnabled = true; event->m_name = std::string(name);
event->Type = tp_Lua; event->m_delay = delay;
event->asName = std::string(name); event->m_delayrandom = randomdelay;
event->fDelay = delay;
event->fRandomDelay = randomdelay;
event->Params[0].asPointer = (void*)handler;
if (simulation::Events.insert(event)) if (simulation::Events.insert(event))
return event; return event;
else else
return nullptr; return nullptr;
} }
EXPORT TEvent* scriptapi_event_find(const char* name) EXPORT basic_event* scriptapi_event_find(const char* name)
{ {
std::string str(name); std::string str(name);
TEvent *e = simulation::Events.FindEvent(str); basic_event *e = simulation::Events.FindEvent(str);
if (e) if (e)
return e; return e;
else else
@@ -128,10 +126,10 @@ extern "C"
return false; return false;
} }
EXPORT const char* scriptapi_event_getname(TEvent *e) EXPORT const char* scriptapi_event_getname(basic_event *e)
{ {
if (e) if (e)
return e->asName.c_str(); return e->m_name.c_str();
return nullptr; return nullptr;
} }
@@ -142,7 +140,7 @@ extern "C"
return nullptr; return nullptr;
} }
EXPORT void scriptapi_event_dispatch(TEvent *e, TDynamicObject *activator, double delay) EXPORT void scriptapi_event_dispatch(basic_event *e, TDynamicObject *activator, double delay)
{ {
if (e) if (e)
simulation::Events.AddToQuery(e, activator, delay); simulation::Events.AddToQuery(e, activator, delay);
@@ -188,7 +186,7 @@ extern "C"
if (!mc) if (!mc)
return; return;
mc->UpdateValues(std::string(str), num1, num2, mc->UpdateValues(std::string(str), num1, num2,
update_memstring | update_memval1 | update_memval2); basic_event::flags::text | basic_event::flags::value_1 | basic_event::flags::value_2);
} }
EXPORT void scriptapi_dynobj_putvalues(TDynamicObject *dyn, const char *str, double num1, double num2) EXPORT void scriptapi_dynobj_putvalues(TDynamicObject *dyn, const char *str, double num1, double num2)

4
lua.h
View File

@@ -1,7 +1,7 @@
#pragma once #pragma once
#include <lua.hpp> #include <lua.hpp>
class TEvent; class basic_event;
class TDynamicObject; class TDynamicObject;
class lua class lua
@@ -17,5 +17,5 @@ public:
void interpret(std::string file); void interpret(std::string file);
typedef void (*eventhandler_t)(TEvent*, const TDynamicObject*); typedef void (*eventhandler_t)(basic_event*, const TDynamicObject*);
}; };

View File

@@ -64,9 +64,9 @@ OnCommandGet(multiplayer::DaneRozkaz *pRozkaz)
if( Global.iMultiplayer ) { if( Global.iMultiplayer ) {
auto *event = simulation::Events.FindEvent( std::string( pRozkaz->cString + 1, (unsigned)( pRozkaz->cString[ 0 ] ) ) ); auto *event = simulation::Events.FindEvent( std::string( pRozkaz->cString + 1, (unsigned)( pRozkaz->cString[ 0 ] ) ) );
if( event != nullptr ) { if( event != nullptr ) {
if( ( event->Type == tp_Multiple ) if( ( typeid( *event ) == typeid( multi_event ) )
|| ( event->Type == tp_Lights ) || ( typeid( *event ) == typeid( lights_event ) )
|| ( event->evJoined != 0 ) ) { || ( event->m_sibling != 0 ) ) {
// tylko jawne albo niejawne Multiple // tylko jawne albo niejawne Multiple
simulation::Events.AddToQuery( event, nullptr ); // drugi parametr to dynamic wywołujący - tu brak simulation::Events.AddToQuery( event, nullptr ); // drugi parametr to dynamic wywołujący - tu brak
} }

View File

@@ -433,6 +433,9 @@ opengl_renderer::Render() {
setup_units( true, false, false ); setup_units( true, false, false );
Application.render_ui(); Application.render_ui();
// swapbuffers() could unbind current buffers so we prepare for it on our end
gfx::opengl_vbogeometrybank::reset();
Timer::subsystem.gfx_swap.start(); Timer::subsystem.gfx_swap.start();
glfwSwapBuffers( m_window ); glfwSwapBuffers( m_window );
Timer::subsystem.gfx_swap.stop(); Timer::subsystem.gfx_swap.stop();
@@ -3748,8 +3751,8 @@ opengl_renderer::Init_caps() {
+ " Vendor: " + std::string( (char *)glGetString( GL_VENDOR ) ) + " Vendor: " + std::string( (char *)glGetString( GL_VENDOR ) )
+ " OpenGL Version: " + oglversion ); + " OpenGL Version: " + oglversion );
if( !GLEW_VERSION_1_5 ) { if( !GLEW_VERSION_3_0 ) {
ErrorLog( "Requires openGL >= 1.5" ); ErrorLog( "Requires openGL >= 3.0" ); // technically 1.5 for now, but imgui wants more
return false; return false;
} }

View File

@@ -603,7 +603,7 @@ lines_node::import( cParser &Input, scene::node_data const &Nodedata ) {
m_data.vertices.emplace_back( vertex0 ); m_data.vertices.emplace_back( vertex0 );
} }
if( m_data.vertices.size() % 2 != 0 ) { if( m_data.vertices.size() % 2 != 0 ) {
ErrorLog( "Lines node specified odd number of vertices, encountered in file \"" + Input.Name() + "\" (line " + std::to_string( Input.Line() - 1 ) + ")" ); ErrorLog( "Lines node specified odd number of vertices, defined in file \"" + Input.Name() + "\" (line " + std::to_string( Input.Line() - 1 ) + ")" );
m_data.vertices.pop_back(); m_data.vertices.pop_back();
} }

View File

@@ -77,7 +77,7 @@ node_groups::insert( scene::group_handle const Group, scene::basic_node *Node )
// places provided event in specified group // places provided event in specified group
void void
node_groups::insert( scene::group_handle const Group, TEvent *Event ) { node_groups::insert( scene::group_handle const Group, basic_event *Event ) {
// TBD, TODO: automatically unregister the event from its current group? // TBD, TODO: automatically unregister the event from its current group?
Event->group( Group ); Event->group( Group );

View File

@@ -16,7 +16,7 @@ namespace scene {
struct basic_group { struct basic_group {
// members // members
std::vector<scene::basic_node *> nodes; std::vector<scene::basic_node *> nodes;
std::vector<TEvent *> events; std::vector<basic_event *> events;
}; };
// holds lists of grouped scene nodes // holds lists of grouped scene nodes
@@ -41,7 +41,7 @@ public:
insert( scene::group_handle const Group, scene::basic_node *Node ); insert( scene::group_handle const Group, scene::basic_node *Node );
// places provided event in specified group // places provided event in specified group
void void
insert( scene::group_handle const Group, TEvent *Event ); insert( scene::group_handle const Group, basic_event *Event );
// grants direct access to specified group // grants direct access to specified group
scene::basic_group & scene::basic_group &
group( scene::group_handle const Group ) { group( scene::group_handle const Group ) {

View File

@@ -105,7 +105,7 @@ state_serializer::deserialize( cParser &Input, scene::scratch_data &Scratchpad )
lookup->second(); lookup->second();
} }
else { else {
ErrorLog( "Bad scenario: unexpected token \"" + token + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( Input.Line() - 1 ) + ")" ); ErrorLog( "Bad scenario: unexpected token \"" + token + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( Input.Line() - 1 ) + ")" );
} }
timenow = std::chrono::steady_clock::now(); timenow = std::chrono::steady_clock::now();
@@ -243,15 +243,14 @@ void
state_serializer::deserialize_event( cParser &Input, scene::scratch_data &Scratchpad ) { state_serializer::deserialize_event( cParser &Input, scene::scratch_data &Scratchpad ) {
// TODO: refactor event class and its de/serialization. do offset and rotation after deserialization is done // TODO: refactor event class and its de/serialization. do offset and rotation after deserialization is done
auto *event = new TEvent(); auto *event = make_event( Input, Scratchpad );
Math3D::vector3 offset = ( if( event == nullptr ) {
Scratchpad.location.offset.empty() ? // something went wrong at initial stage, move on
Math3D::vector3() : skip_until( Input, "endevent" );
Math3D::vector3( return;
Scratchpad.location.offset.top().x, }
Scratchpad.location.offset.top().y,
Scratchpad.location.offset.top().z ) ); event->deserialize( Input, Scratchpad );
event->Load( &Input, offset );
if( true == simulation::Events.insert( event ) ) { if( true == simulation::Events.insert( event ) ) {
scene::Groups.insert( scene::Groups.handle(), event ); scene::Groups.insert( scene::Groups.handle(), event );
@@ -324,7 +323,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
if( false == simulation::Vehicles.insert( vehicle ) ) { if( false == simulation::Vehicles.insert( vehicle ) ) {
ErrorLog( "Bad scenario: vehicle with duplicate name \"" + vehicle->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" ); ErrorLog( "Bad scenario: duplicate vehicle name \"" + vehicle->name() + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
} }
if( ( vehicle->MoverParameters->CategoryFlag == 1 ) // trains only if( ( vehicle->MoverParameters->CategoryFlag == 1 ) // trains only
@@ -338,7 +337,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
auto *path { deserialize_path( Input, Scratchpad, nodedata ) }; auto *path { deserialize_path( Input, Scratchpad, nodedata ) };
// duplicates of named tracks are currently experimentally allowed // duplicates of named tracks are currently experimentally allowed
if( false == simulation::Paths.insert( path ) ) { if( false == simulation::Paths.insert( path ) ) {
ErrorLog( "Bad scenario: track with duplicate name \"" + path->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" ); ErrorLog( "Bad scenario: duplicate track name \"" + path->name() + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
/* /*
delete path; delete path;
delete pathnode; delete pathnode;
@@ -354,7 +353,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
if( traction == nullptr ) { return; } if( traction == nullptr ) { return; }
if( false == simulation::Traction.insert( traction ) ) { if( false == simulation::Traction.insert( traction ) ) {
ErrorLog( "Bad scenario: traction piece with duplicate name \"" + traction->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" ); ErrorLog( "Bad scenario: duplicate traction piece name \"" + traction->name() + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
} }
scene::Groups.insert( scene::Groups.handle(), traction ); scene::Groups.insert( scene::Groups.handle(), traction );
simulation::Region->insert_and_register( traction ); simulation::Region->insert_and_register( traction );
@@ -366,7 +365,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
if( powersource == nullptr ) { return; } if( powersource == nullptr ) { return; }
if( false == simulation::Powergrid.insert( powersource ) ) { if( false == simulation::Powergrid.insert( powersource ) ) {
ErrorLog( "Bad scenario: power grid source with duplicate name \"" + powersource->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" ); ErrorLog( "Bad scenario: duplicate power grid source name \"" + powersource->name() + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
} }
/* /*
// TODO: implement this // TODO: implement this
@@ -415,7 +414,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
if( instance == nullptr ) { return; } if( instance == nullptr ) { return; }
if( false == simulation::Instances.insert( instance ) ) { if( false == simulation::Instances.insert( instance ) ) {
ErrorLog( "Bad scenario: 3d model instance with duplicate name \"" + instance->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" ); ErrorLog( "Bad scenario: duplicate 3d model instance name \"" + instance->name() + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
} }
scene::Groups.insert( scene::Groups.handle(), instance ); scene::Groups.insert( scene::Groups.handle(), instance );
simulation::Region->insert( instance ); simulation::Region->insert( instance );
@@ -458,7 +457,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
auto *memorycell { deserialize_memorycell( Input, Scratchpad, nodedata ) }; auto *memorycell { deserialize_memorycell( Input, Scratchpad, nodedata ) };
if( false == simulation::Memory.insert( memorycell ) ) { if( false == simulation::Memory.insert( memorycell ) ) {
ErrorLog( "Bad scenario: memory memorycell with duplicate name \"" + memorycell->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" ); ErrorLog( "Bad scenario: duplicate memory cell name \"" + memorycell->name() + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
} }
scene::Groups.insert( scene::Groups.handle(), memorycell ); scene::Groups.insert( scene::Groups.handle(), memorycell );
simulation::Region->insert( memorycell ); simulation::Region->insert( memorycell );
@@ -467,7 +466,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
auto *eventlauncher { deserialize_eventlauncher( Input, Scratchpad, nodedata ) }; auto *eventlauncher { deserialize_eventlauncher( Input, Scratchpad, nodedata ) };
if( false == simulation::Events.insert( eventlauncher ) ) { if( false == simulation::Events.insert( eventlauncher ) ) {
ErrorLog( "Bad scenario: event launcher with duplicate name \"" + eventlauncher->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" ); ErrorLog( "Bad scenario: duplicate event launcher name \"" + eventlauncher->name() + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
} }
// event launchers can be either global, or local with limited range of activation // event launchers can be either global, or local with limited range of activation
// each gets assigned different caretaker // each gets assigned different caretaker
@@ -483,7 +482,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
auto *sound { deserialize_sound( Input, Scratchpad, nodedata ) }; auto *sound { deserialize_sound( Input, Scratchpad, nodedata ) };
if( false == simulation::Sounds.insert( sound ) ) { if( false == simulation::Sounds.insert( sound ) ) {
ErrorLog( "Bad scenario: sound node with duplicate name \"" + sound->name() + "\" encountered in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" ); ErrorLog( "Bad scenario: duplicate sound node name \"" + sound->name() + "\" defined in file \"" + Input.Name() + "\" (line " + std::to_string( inputline ) + ")" );
} }
simulation::Region->insert( sound ); simulation::Region->insert( sound );
} }

View File

@@ -347,10 +347,16 @@ void CSkyDome::RebuildColors() {
if( m_coloursbuffer != -1 ) { if( m_coloursbuffer != -1 ) {
// the colour buffer was already initialized, so on this run we update its content // the colour buffer was already initialized, so on this run we update its content
// cache entry state
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
// begin
::glEnableClientState( GL_VERTEX_ARRAY );
// update
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer ); ::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
::glBufferSubData( GL_ARRAY_BUFFER, 0, m_colours.size() * sizeof( glm::vec3 ), m_colours.data() ); ::glBufferSubData( GL_ARRAY_BUFFER, 0, m_colours.size() * sizeof( glm::vec3 ), m_colours.data() );
// cleanup
::glPopClientAttrib();
} }
} }
//******************************************************************************// //******************************************************************************//

View File

@@ -49,20 +49,19 @@ basic_station::update_load( TDynamicObject *First, Mtable::TTrainParameters &Sch
auto &parameters { *vehicle->MoverParameters }; auto &parameters { *vehicle->MoverParameters };
if( ( true == parameters.LoadType.empty() ) if( parameters.LoadType.name.empty() ) {
&& ( parameters.LoadAccepted.find( "passengers" ) != std::string::npos ) ) { // (try to) set the cargo type for empty cars
// set the type for empty cars parameters.AssignLoad( "passengers" );
parameters.LoadType = "passengers";
} }
if( parameters.LoadType == "passengers" ) { if( parameters.LoadType.name == "passengers" ) {
// NOTE: for the time being we're doing simple, random load change calculation // NOTE: for the time being we're doing simple, random load change calculation
// TODO: exchange driven by station parameters and time of the day // TODO: exchange driven by station parameters and time of the day
auto unloadcount = static_cast<int>( auto unloadcount = static_cast<int>(
laststop ? parameters.Load : laststop ? parameters.LoadAmount :
firststop ? 0 : firststop ? 0 :
std::min<float>( std::min<float>(
parameters.Load, parameters.LoadAmount,
Random( parameters.MaxLoad * 0.10 * stationsizemodifier ) ) ); Random( parameters.MaxLoad * 0.10 * stationsizemodifier ) ) );
auto loadcount = static_cast<int>( auto loadcount = static_cast<int>(
laststop ? laststop ?

View File

@@ -195,10 +195,10 @@ init() {
" pantograf: %.2f%cZG", " 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]", "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", "nastawnik jazdy",
"nastawnik dodatkowy", "nastawnik dodatkowy",
"sterowanie analogowe", "sterowanie analogowe",
"nastawnik jazdy", "nastawnik kierunku",
"hamulec zespolony", "hamulec zespolony",
"hamulec pomocniczy", "hamulec pomocniczy",
"hamulec reczny", "hamulec reczny",
@@ -224,7 +224,7 @@ init() {
"syrena (ton niski)", "syrena (ton niski)",
"syrena (ton wysoki)", "syrena (ton wysoki)",
"gwizdawka", "gwizdawka",
"przekaznik nadmiarowy motorow trakcyjnych", "przekaznik nadmiarowy silnikow trakcyjnych",
"przekaznik nadmiarowy przetwornicy", "przekaznik nadmiarowy przetwornicy",
"styczniki liniowe", "styczniki liniowe",
"drzwi lewe", "drzwi lewe",

View File

@@ -253,7 +253,8 @@ void uart_input::poll()
trainstate.ventilator_overload << 1 trainstate.ventilator_overload << 1
| trainstate.motor_overload_threshold << 2), | trainstate.motor_overload_threshold << 2),
//byte 3 //byte 3
0, (uint8_t)(
trainstate.coupled_hv_voltage_relays << 0),
//byte 4 //byte 4
(uint8_t)( (uint8_t)(
trainstate.train_heating << 0 trainstate.train_heating << 0

View File

@@ -101,7 +101,7 @@ ui_layer::init( GLFWwindow *Window ) {
m_imguiio->Fonts->AddFontFromFileTTF("DejaVuSansMono.ttf", 13.0f); m_imguiio->Fonts->AddFontFromFileTTF("DejaVuSansMono.ttf", 13.0f);
ImGui_ImplGlfw_InitForOpenGL(m_window); ImGui_ImplGlfw_InitForOpenGL(m_window);
ImGui_ImplOpenGL3_Init("#version 140"); ImGui_ImplOpenGL3_Init("#version 130");
ImGui::StyleColorsClassic(); ImGui::StyleColorsClassic();
ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplOpenGL3_NewFrame();
@@ -114,6 +114,7 @@ ui_layer::init( GLFWwindow *Window ) {
void void
ui_layer::shutdown() { ui_layer::shutdown() {
ImGui::EndFrame(); ImGui::EndFrame();
ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown(); ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
@@ -182,7 +183,6 @@ ui_layer::render() {
render_(); render_();
ImGui::Render(); ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplOpenGL3_NewFrame();

View File

@@ -1 +1 @@
#define VERSION_INFO "M7 16.09.2018, based on tmj e881092" #define VERSION_INFO "M7 20.09.2018, based on tmj-2448e59"