From 4575f61cc8d8919571a72c9023b7cd584c81cba1 Mon Sep 17 00:00:00 2001 From: Piotr Warszawski Date: Fri, 4 Sep 2026 15:52:38 +0200 Subject: [PATCH] whois: add lookahead mode for the timetable entry after the next stop Dispatcher scripts that route trains at a station based on where they go afterwards (e.g. a big terminal throat with several outbound directions) have no way to read that: whois +40 only exposes the current/next timetable entry (NextStop()/IsStop()), which while the train is at that very station is that station itself. Adds flags::whois_ahead (bit 6, previously unused) plus TTrainParameters::StationNameAhead(Offset)/StationIsStopAhead(Offset), returning the raw TimeTable[] entry Offset positions past StationIndex (name and whether it's a booked stop, "none"/false past the end of the timetable). The new whois branch calls both with Offset=1, mirroring the existing +40 branch's UpdateValues()/WriteLog() shape. Logic-verified with an isolated harness mirroring the touched types (TTrainParameters/TController/TMemCell shapes and the exact function bodies); not yet build-tested against the full engine locally - relying on CI for that. --- world/Event.cpp | 31 ++++++++++++++++++++++++++++++- world/Event.h | 1 + world/mtable.cpp | 16 ++++++++++++++++ world/mtable.h | 4 ++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/world/Event.cpp b/world/Event.cpp index eb679e72..e47dbea2 100644 --- a/world/Event.cpp +++ b/world/Event.cpp @@ -1018,13 +1018,42 @@ whois_event::run_() { auto *targetcell { static_cast( std::get( target ) ) }; if( targetcell == nullptr ) { continue; } // event effect code + // +64: station after the next one, unused, stop there or passthrough // +40: next station name, unused, stop at next station (duplicate of +0 2nd numeric value) // +32: vehicle name // +24: vehicle type, consist brake level, obstacle distance // +16: load type, load amount, max load amount // +8: destination, direction, engine power // +0: train name, station count, stop on next station - if( m_input.flags & flags::whois_name ) { + if( m_input.flags & flags::whois_ahead ) { + // +64 + // the timetable entry one past the next stop, and whether the train stops there + auto const *owner { ( + m_activator->Mechanik != nullptr && m_activator->Mechanik->primary() ? + m_activator->Mechanik : + m_activator->ctOwner ) }; + auto const aheadname { ( + owner != nullptr ? + owner->TrainTimetable().StationNameAhead( 1 ) : + "none" ) }; + auto const aheadstop { ( + owner != nullptr && owner->TrainTimetable().StationIsStopAhead( 1 ) ? + 1 : + 0 ) }; + + targetcell->UpdateValues( + aheadname, // station after the next one + 0, // unused + aheadstop, // stop there or passthrough + m_input.flags & ( flags::text | flags::value1 | flags::value2 ) ); + + WriteLog( + "Type: WhoIs (" + std::to_string( m_input.flags ) + ") - " + + "[station after next: " + aheadname + "], " + + "[X], " + + "[stop there: " + ( aheadstop != 0 ? "yes" : "no" ) + "]" ); + } + else if( m_input.flags & flags::whois_name ) { // +32 or +40 // next station name if( m_input.flags & flags::mode_alt ) { diff --git a/world/Event.h b/world/Event.h index 52ee3468..55be65de 100644 --- a/world/Event.h +++ b/world/Event.h @@ -37,6 +37,7 @@ public: mode_alt = 1 << 3, whois_load = 1 << 4, whois_name = 1 << 5, + whois_ahead = 1 << 6, // condition values track_busy = 1 << 3, track_free = 1 << 4, diff --git a/world/mtable.cpp b/world/mtable.cpp index cec54f87..75e6c8ad 100644 --- a/world/mtable.cpp +++ b/world/mtable.cpp @@ -77,6 +77,22 @@ bool TTrainParameters::IsLastStop() const { return StationIndex >= StationCount; } +std::string TTrainParameters::StationNameAhead( int Offset ) const +{ // nazwa wpisu rozkladu Offset pozycji za aktualnym (bez pomijania przelotow) + int const idx { StationIndex + Offset }; + if( ( idx < 1 ) || ( idx > StationCount ) ) + return "none"; + return TimeTable[idx].StationName; +} + +bool TTrainParameters::StationIsStopAhead( int Offset ) const +{ // czy wpis Offset pozycji za aktualnym to zaplanowany postoj + int const idx { StationIndex + Offset }; + if( ( idx < 1 ) || ( idx > StationCount ) ) + return false; + return TimeTable[idx].Ah >= 0; //-1 to brak postoju +} + bool TTrainParameters::IsMaintenance() const { if( StationIndex <= StationCount ) diff --git a/world/mtable.h b/world/mtable.h index c58d120f..701b0c6c 100644 --- a/world/mtable.h +++ b/world/mtable.h @@ -70,6 +70,10 @@ class TTrainParameters std::string ShowRelation() const; double WatchMTable(double DistCounter); std::string NextStop() const; + // nazwa wpisu rozkladu Offset pozycji za StationIndex (Offset>=1); "none" poza koncem rozkladu + std::string StationNameAhead( int Offset ) const; + // true, gdy ten wpis to zaplanowany postoj (ma godzine przyjazdu), false dla przelotu / poza koncem + bool StationIsStopAhead( int Offset ) const; sound_source next_stop_sound() const; sound_source last_stop_sound() const; bool IsStop() const;