From f718dbf95dbedf45798b9053e8b73edb60d7d529 Mon Sep 17 00:00:00 2001 From: maj00r Date: Tue, 15 Sep 2026 22:09:02 +0200 Subject: [PATCH] Ask the cell itself whether its command is still pending, guard the order table The spent command was tracked in a table flag, which is lost whenever the speed table is rebuilt - the cell would go back to being a stop point. The memcell already knows: StopCommandSent() drops the pending flag and keeps the text, so the event now answers is_command_spent() and the table point follows it. OrderNextGet() read one past the end of OrderList when the current order sat in the last slot; it now reports Wait_for_orders there, which is what OrderNext() wraps to anyway. --- vehicle/Driver.cpp | 10 ++++------ vehicle/Driver.h | 5 +++-- world/Event.cpp | 14 ++++++++++++++ world/Event.h | 6 ++++++ 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/vehicle/Driver.cpp b/vehicle/Driver.cpp index 738aa84d..06085e60 100644 --- a/vehicle/Driver.cpp +++ b/vehicle/Driver.cpp @@ -274,9 +274,10 @@ void TSpeedPos::CommandCheck() // inna komenda w evencie skanowanym powoduje zatrzymanie i wysłanie tej komendy // nie manewrowa, nie przystanek, nie zatrzymać na SBL // jak nieznana komenda w komórce sygnałowej, to zatrzymujemy - // a cell keeps its text after the command has been delivered - going on standing in - // front of it would make every command cell a permanent stop point - fVelNext = ( ( iFlags & spCommandSent ) != 0 ? -1.0 : 0.0 ); + // a cell keeps its text after the command has been delivered, so asking the driver to + // stand in front of it any longer would make every command cell a permanent stop point + fVelNext = ( evEvent != nullptr && evEvent->is_command_spent() ? -1.0 : 0.0 ); + if( fVelNext < 0.0 ) { iFlags |= spCommandSent; } // TODO: check whether clearing spShuntSemaphor flag doesn't cause problems // potentially it can invalidate shunt semaphor used to transmit timetable or similar command iFlags &= ~(spShuntSemaphor | spPassengerStopPoint | spStopOnSBL); @@ -8525,9 +8526,6 @@ TController::check_route_ahead( double const Range ) { eSignNext->StopCommandSent(); // się wykonało już */ // replacement of the above eSignNext->send_command( *this ); - for( auto &point : sSpeedTable ) { - if( point.evEvent == eSignNext ) { point.iFlags |= spCommandSent; } - } } } break; diff --git a/vehicle/Driver.h b/vehicle/Driver.h index 0375c0a7..b2db5621 100644 --- a/vehicle/Driver.h +++ b/vehicle/Driver.h @@ -696,9 +696,10 @@ private: }; inline TOrders TController::OrderCurrentGet() const { - return OrderList[ OrderPos ]; + return OrderList[ std::clamp( OrderPos, 0, maxorders - 1 ) ]; } inline TOrders TController::OrderNextGet() const { - return OrderList[ OrderPos + 1 ]; + // the last slot has no successor; OrderNext() wraps to zero there anyway + return ( OrderPos + 1 < maxorders ? OrderList[ OrderPos + 1 ] : Wait_for_orders ); } diff --git a/world/Event.cpp b/world/Event.cpp index 4e042b29..eb871816 100644 --- a/world/Event.cpp +++ b/world/Event.cpp @@ -415,6 +415,13 @@ basic_event::is_command() const { return false; }; +// returns: true for a data cell whose command has already been delivered +bool +basic_event::is_command_spent() const { + + return false; +}; + std::string basic_event::input_text() const { // odczytanie komendy z eventu @@ -650,6 +657,13 @@ getvalues_event::is_command() const { return m_input.data_cell()->StopCommand(); } +// returns: true for a data cell whose command has already been delivered +bool +getvalues_event::is_command_spent() const { + // the cell keeps its text after the command was sent, only the pending flag is dropped + return false == m_input.data_cell()->StopCommand(); +} + // input data access std::string getvalues_event::input_text() const { diff --git a/world/Event.h b/world/Event.h index 52ee3468..b5217686 100644 --- a/world/Event.h +++ b/world/Event.h @@ -78,6 +78,10 @@ public: virtual bool is_command() const; + // returns: true for a data cell whose command has already been delivered + virtual + bool + is_command_spent() const; // input data access virtual std::string input_text() const; virtual TCommandType input_command() const; @@ -236,6 +240,8 @@ public: void send_command( TController &Controller ) override; // returns: true if associated data cell contains a command for vehicle controller bool is_command() const override; + // returns: true for a data cell whose command has already been delivered + bool is_command_spent() const override; // input data access std::string input_text() const override; TCommandType input_command() const override;