std::unordered_map instances and map types exposed in headers used by
other modules are left as they are.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signatures declared in files touched by PR 206 (Driver.h, EU07.cpp) and
virtual overrides are left unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sound_source and the gl::object conversion operators stay implicit; they
are relied upon by copy-list-initialisation and GL calls.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Applied only where no unqualified name in the block could be captured by
the introduced enumerators.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only local variables and definition parameters are renamed; shadowing
struct fields and enumerators in headers are left for a separate change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
make_event() lowercased the event name twice: cParser::getToken() already
folds ASCII via toLowerChar() (which intentionally leaves bytes >= 0x80
alone), then ToLower() ran std::tolower() over every byte on top of that.
With a non-"C" global locale, that second pass remaps cp1250 uppercase
accented letters (e.g. 0xAF -> 0xBF). Every lookup path - TTrack::AssignEvents(),
child-event resolution in multi_event, event-launcher name resolution -
normalizes only through the parser, so a registered name containing such a
letter can no longer be found: the track logs "can't find assigned event"
and the binding is silently dropped.
Removing the extra ToLower() makes the registration key match every lookup
site (ASCII-only folding, non-ASCII bytes compared verbatim), and matches
the direction toLowerChar()'s own comment already points at for UTF-8.
A whois with no triggering vehicle previously just wrote nothing to
the target cell with no trace in the log, which is a real pain to
diagnose from the scenery side (this is exactly the kind of thing that
cost real debugging time on a station script recently).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
whois_event::run_() dereferenced m_activator unconditionally in every
branch (this predates this PR). getvalues_event::run_() and
putvalues_event::run_() already guard the same way elsewhere in this
file; whois_event was missing it. Single early return covers every
branch, old and new.
The +8/+16/+24/+32/+40 (and the new +48) modes all pick the reporting
vehicle the same way: the activator's own Mechanik if it's the primary
driver, otherwise the consist's controlling vehicle (ctOwner) - so the
event still resolves correctly if a wagon happens to trigger it ahead
of its locomotive.
+0 (train name / stations left / stop flag) predates that pattern and
never got it: it required m_activator->Mechanik directly and silently
wrote nothing otherwise. A whois hook placed where the loco doesn't
necessarily lead (e.g. a train that reverses direction, or one being
propelled) can have a wagon trigger the event first and the memcell
stays empty, with no error - hard to diagnose from scenery side.
Same owner-selection, same guard semantics (still nothing written if
neither the activator nor its consist has a controller), only the
source of the vehicle it reads from is widened.
In TSegment there were two different formulas for a derivative. Most places called GetFirstDerivative() that used the direct formula from the curve points. However RaPositionGet() had its own calculation based on pre-computed cubic polynomial coefficients. This latter method is faster and simpler, so change GetFirstDerivative() to use it and change RaPositionGet() to just call GetFirstDerivative().
TSegment::GetTFromS() is a significant hotspot in the non-rendering part of the state_manager update (about 13%). This change introduces a FastGetTFromS() version that interpolates from precomputed values instead of doing the whole calculation on every call. Computing position from track distance is now done in constant time. This reduces the contribution to about 0.3%.