diff --git a/Driver.cpp b/Driver.cpp index d569c429..dac6baf9 100644 --- a/Driver.cpp +++ b/Driver.cpp @@ -4023,9 +4023,9 @@ TController::UpdateSituation(double dt) { // podłączanie do składu if (iDrivigFlags & moveConnect) { // jeśli stanął już blisko, unikając zderzenia i można próbować podłączyć - fMinProximityDist = -0.5; + fMinProximityDist = -1.0; fMaxProximityDist = 0.0; //[m] dojechać maksymalnie - fVelPlus = 0.5; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania + fVelPlus = 1.0; // dopuszczalne przekroczenie prędkości na ograniczeniu bez hamowania fVelMinus = 0.5; // margines prędkości powodujący załączenie napędu if (AIControllFlag) { // to robi tylko AI, wersję dla człowieka trzeba dopiero zrobić @@ -4033,21 +4033,17 @@ TController::UpdateSituation(double dt) { bool ok; // true gdy się podłączy (uzyskany sprzęg będzie zgodny z żądanym) if (pVehicles[0]->DirectionGet() > 0) // jeśli sprzęg 0 { // sprzęg 0 - próba podczepienia - if (pVehicles[0]->MoverParameters->Couplers[0].Connected) // jeśli jest coś - // wykryte (a - // chyba jest, - // nie?) - if (pVehicles[0]->MoverParameters->Attach( - 0, 2, pVehicles[0]->MoverParameters->Couplers[0].Connected, - iCoupler)) - { - // pVehicles[0]->dsbCouplerAttach->SetVolume(DSBVOLUME_MAX); - // pVehicles[0]->dsbCouplerAttach->Play(0,0,0); + if( pVehicles[ 0 ]->MoverParameters->Couplers[ 0 ].Connected ) { + // jeśli jest coś wykryte (a chyba jest, nie?) + if( pVehicles[ 0 ]->MoverParameters->Attach( + 0, 2, pVehicles[ 0 ]->MoverParameters->Couplers[ 0 ].Connected, + iCoupler ) ) { + // pVehicles[0]->dsbCouplerAttach->SetVolume(DSBVOLUME_MAX); + // pVehicles[0]->dsbCouplerAttach->Play(0,0,0); } - // WriteLog("CoupleDist[0]="+AnsiString(pVehicles[0]->MoverParameters->Couplers[0].CoupleDist)+", - // Connected[0]="+AnsiString(pVehicles[0]->MoverParameters->Couplers[0].CouplingFlag)); - ok = (pVehicles[0]->MoverParameters->Couplers[0].CouplingFlag == - iCoupler); // udało się? (mogło częściowo) + } + // udało się? (mogło częściowo) + ok = (pVehicles[0]->MoverParameters->Couplers[0].CouplingFlag == iCoupler); } else // if (pVehicles[0]->MoverParameters->DirAbsolute<0) //jeśli sprzęg 1 { // sprzęg 1 - próba podczepienia @@ -4060,10 +4056,8 @@ TController::UpdateSituation(double dt) { // pVehicles[0]->dsbCouplerAttach->Play(0,0,0); } } - // WriteLog("CoupleDist[1]="+AnsiString(Controlling->Couplers[1].CoupleDist)+", - // Connected[0]="+AnsiString(Controlling->Couplers[1].CouplingFlag)); - ok = (pVehicles[0]->MoverParameters->Couplers[1].CouplingFlag == - iCoupler); // udało się? (mogło częściowo) + // udało się? (mogło częściowo) + ok = (pVehicles[0]->MoverParameters->Couplers[1].CouplingFlag == iCoupler); } if (ok) { // jeżeli został podłączony diff --git a/Event.cpp b/Event.cpp index 761c95f6..7721cd92 100644 --- a/Event.cpp +++ b/Event.cpp @@ -536,8 +536,7 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org) *parser >> token; break; case tp_Multiple: { - int paramidx { 0 }; - bool ti { false }; // flaga dla else + bool conditionalelse { false }; // flaga dla else parser->getTokens(); *parser >> token; @@ -548,18 +547,7 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org) if( token != "else" ) { if( token.substr( 0, 5 ) != "none_" ) { // eventy rozpoczynające się od "none_" są ignorowane - if( paramidx < 8 ) { - Params[ paramidx ].asText = new char[ token.size() + 1 ]; - strcpy( Params[ paramidx ].asText, token.c_str() ); - if( ti ) { - // oflagowanie dla eventów "else" - iFlags |= conditional_else << paramidx; - } - ++paramidx; - } - else { - ErrorLog( "Bad event: multi-event \"" + asName + "\" with more than 8 events; discarding link to event \"" + token + "\"" ); - } + m_children.emplace_back( token, nullptr, ( conditionalelse == false ) ); } else { WriteLog( "Multi-event \"" + asName + "\" ignored link to event \"" + token + "\"" ); @@ -567,7 +555,8 @@ void TEvent::Load(cParser *parser, Math3D::vector3 const &org) } else { // zmiana flagi dla słowa "else" - ti = !ti; + conditionalelse = !conditionalelse; + m_conditionalelse = true; } parser->getTokens(); *parser >> token; @@ -655,25 +644,19 @@ TEvent::export_as_text( std::ostream &Output ) const { break; } case tp_Multiple: { - // NOTE: conditional_anyelse won't work when event cap is removed - bool hasconditionalelse { false }; - for( auto eventidx = 0; eventidx < 8; ++eventidx ) { - if( Params[ eventidx ].asEvent == nullptr ) { continue; } - if( ( iFlags & ( conditional_else << eventidx ) ) == 0 ) { - Output << Params[ eventidx ].asEvent->asName << ' '; - } - else { - // this event is executed as part of the 'else' block - hasconditionalelse = true; + for( auto const &childevent : m_children ) { + if( std::get( childevent ) == nullptr ) { continue; } + if( true == std::get( childevent ) ) { + Output << std::get( childevent ) << ' '; } } // optional 'else' block - if( true == hasconditionalelse ) { + if( true == m_conditionalelse ) { Output << "else "; - for( auto eventidx = 0; eventidx < 8; ++eventidx ) { - if( Params[ eventidx ].asEvent == nullptr ) { continue; } - if( ( iFlags & ( conditional_else << eventidx ) ) != 0 ) { - Output << Params[ eventidx ].asEvent->asName << ' '; + for( auto const &childevent : m_children ) { + if( std::get( childevent ) == nullptr ) { continue; } + if( false == std::get( childevent ) ) { + Output << std::get( childevent ) << ' '; } } } @@ -1317,29 +1300,30 @@ event_manager::CheckQuery() { Error("Event \"DynVel\" is obsolete"); break; case tp_Multiple: { - auto const bCondition = EventConditon(m_workevent); - if( ( bCondition ) - || ( m_workevent->iFlags & conditional_anyelse ) ) { + auto const condition { EventConditon( m_workevent ) }; + if( ( true == condition ) + || ( true == m_workevent->m_conditionalelse ) ) { // warunek spelniony albo było użyte else WriteLog("Type: Multi-event"); - for (i = 0; i < 8; ++i) { - // dodawane do kolejki w kolejności zapisania - if( m_workevent->Params[ i ].asEvent ) { - if( bCondition != ( ( ( m_workevent->iFlags & ( conditional_else << i ) ) != 0 ) ) ) { - if( m_workevent->Params[ i ].asEvent != m_workevent ) - AddToQuery( m_workevent->Params[ i ].asEvent, m_workevent->Activator ); // normalnie dodać - else { - // jeśli ma być rekurencja to musi mieć sensowny okres powtarzania - if( m_workevent->fDelay >= 5.0 ) { - AddToQuery( m_workevent, m_workevent->Activator ); - } - } + for( auto &childevent : m_workevent->m_children ) { + auto *childeventdata { std::get( childevent ) }; + if( childeventdata == nullptr ) { continue; } + if( std::get( childevent ) != condition ) { continue; } + + if( childeventdata != m_workevent ) { + // normalnie dodać + AddToQuery( childeventdata, m_workevent->Activator ); + } + else { + // jeśli ma być rekurencja to musi mieć sensowny okres powtarzania + if( m_workevent->fDelay >= 5.0 ) { + AddToQuery( m_workevent, m_workevent->Activator ); } } } if( Global.iMultiplayer ) { // dajemy znać do serwera o wykonaniu - if( ( m_workevent->iFlags & conditional_anyelse ) == 0 ) { + if( false == m_workevent->m_conditionalelse ) { // jednoznaczne tylko, gdy nie było else if( m_workevent->Activator ) { multiplayer::WyslijEvent( m_workevent->asName, m_workevent->Activator->name() ); @@ -1711,15 +1695,10 @@ event_manager::InitEvents() { event->iFlags &= ~( conditional_memstring | conditional_memval1 | conditional_memval2 ); } } - for( int i = 0; i < 8; ++i ) { - if( event->Params[ i ].asText != nullptr ) { - cellastext = event->Params[ i ].asText; - SafeDeleteArray( event->Params[ i ].asText ); - event->Params[ i ].asEvent = FindEvent( cellastext ); - if( event->Params[ i ].asEvent == nullptr ) { - // Ra: tylko w logu informacja o braku - ErrorLog( "Bad event: multi-event \"" + event->asName + "\" cannot find event \"" + cellastext + "\"" ); - } + for( auto &childevent : event->m_children ) { + std::get( childevent ) = FindEvent( std::get( childevent ) ); + if( std::get( childevent ) == nullptr ) { + ErrorLog( "Bad event: multi-event \"" + event->asName + "\" cannot find event \"" + std::get( childevent ) + "\"" ); } } break; diff --git a/Event.h b/Event.h index 13d62043..3fcf87bc 100644 --- a/Event.h +++ b/Event.h @@ -48,8 +48,6 @@ 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_else = 0x0010000; // flaga odwrócenia warunku (przesuwana bitowo) -const int conditional_anyelse = 0x0FF0000; // do sprawdzania, czy są odwrócone warunki 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 @@ -67,7 +65,6 @@ union TParam TTrain *asTrain; TDynamicObject *asDynamic; TEvent *asEvent; - bool asBool; double asdouble; int asInt; sound_source *tsTextSound; @@ -78,10 +75,27 @@ union TParam class TEvent // zmienne: ev* { // zdarzenie - private: - void Conditions(cParser *parser, std::string s); - - public: +public: +// types + // wrapper for binding between editor-supplied name, event, and execution conditional flag + using conditional_event = std::tuple; +// constructors + TEvent(std::string const &m = ""); + ~TEvent(); +// metody + void Load(cParser *parser, Math3D::vector3 const &org); + // sends basic content of the class in legacy (text) format to provided stream + void + export_as_text( std::ostream &Output ) const; + static void AddToQuery( TEvent *Event, TEvent *&Start ); + std::string CommandGet(); + TCommandType Command(); + double ValueGet(int n); + glm::dvec3 PositionGet() const; + bool StopCommand(); + void StopCommandSent(); + void Append(TEvent *e); +// members std::string asName; bool m_ignored { false }; // replacement for tp_ignored bool bEnabled = false; // false gdy ma nie być dodawany do kolejki (skanowanie sygnałów) @@ -96,22 +110,11 @@ class TEvent // zmienne: ev* std::string asNodeName; // McZapkie-100302 - dodalem zeby zapamietac nazwe toru TEvent *evJoined = nullptr; // kolejny event z tą samą nazwą - od wersji 378 double fRandomDelay = 0.0; // zakres dodatkowego opóźnienia // standardowo nie będzie dodatkowego losowego opóźnienia -public: - // metody - TEvent(std::string const &m = ""); - ~TEvent(); - void Load(cParser *parser, Math3D::vector3 const &org); - // sends basic content of the class in legacy (text) format to provided stream - void - export_as_text( std::ostream &Output ) const; - static void AddToQuery( TEvent *Event, TEvent *&Start ); - std::string CommandGet(); - TCommandType Command(); - double ValueGet(int n); - glm::dvec3 PositionGet() const; - bool StopCommand(); - void StopCommandSent(); - void Append(TEvent *e); + std::vector 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 + +private: + void Conditions( cParser *parser, std::string s ); }; class event_manager { diff --git a/scene.cpp b/scene.cpp index ea251a9b..59de3c15 100644 --- a/scene.cpp +++ b/scene.cpp @@ -432,7 +432,7 @@ basic_cell::find( glm::dvec3 const &Point, float const Radius, bool const Onlyco std::tie( vehiclenearest, leastdistance ) = std::tie( vehicle, distance ); } } - return std::tie( vehiclenearest, leastdistance ); + return { vehiclenearest, leastdistance }; } // finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint @@ -449,7 +449,7 @@ basic_cell::find( glm::dvec3 const &Point, TTrack const *Exclude ) const { endpointid = path->TestPoint( &point ); if( endpointid >= 0 ) { - return std::tie( path, endpointid ); + return { path, endpointid }; } } return { nullptr, -1 }; @@ -468,7 +468,7 @@ basic_cell::find( glm::dvec3 const &Point, TTraction const *Exclude ) const { endpointid = traction->TestPoint( Point ); if( endpointid >= 0 ) { - return std::tie( traction, endpointid ); + return { traction, endpointid }; } } return { nullptr, -1 }; @@ -729,7 +729,7 @@ basic_section::find( glm::dvec3 const &Point, float const Radius, bool const Onl std::tie( vehiclenearest, distancenearest ) = std::tie( vehiclefound, distancefound ); } } - return std::tie( vehiclenearest, distancenearest ); + return { vehiclenearest, distancenearest }; } // finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint @@ -1245,7 +1245,7 @@ basic_region::find_vehicle( glm::dvec3 const &Point, float const Radius, bool co std::tie( nearestvehicle, nearestdistance ) = std::tie( foundvehicle, founddistance ); } } - return std::tie( nearestvehicle, nearestdistance ); + return { nearestvehicle, nearestdistance }; } // finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint @@ -1258,7 +1258,7 @@ basic_region::find_path( glm::dvec3 const &Point, TTrack const *Exclude ) { return section( Point ).find( Point, Exclude ); } - return std::make_tuple( nullptr, -1 ); + return { nullptr, -1 }; } // finds a traction piece with one of its ends located in specified point. returns: located traction piece and id of the matching endpoint @@ -1271,7 +1271,7 @@ basic_region::find_traction( glm::dvec3 const &Point, TTraction const *Exclude ) return section( Point ).find( Point, Exclude ); } - return std::make_tuple( nullptr, -1 ); + return { nullptr, -1 }; } // finds a traction piece located nearest to specified point, sharing section with specified other piece and powered in specified direction. returns: located traction piece diff --git a/version.h b/version.h index 020fbc89..5058f5a7 100644 --- a/version.h +++ b/version.h @@ -1,5 +1,5 @@ #pragma once #define VERSION_MAJOR 18 -#define VERSION_MINOR 609 +#define VERSION_MINOR 614 #define VERSION_REVISION 0