From 2dcae05c77bfd4b2b427b9f188bf792da3df7cec Mon Sep 17 00:00:00 2001
From: Piotr Warszawski
Date: Sat, 5 Sep 2026 19:10:58 +0200
Subject: [PATCH] event names: drop redundant locale-dependent ToLower() at
registration
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.
---
world/Event.cpp | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/world/Event.cpp b/world/Event.cpp
index eb679e72..34617196 100644
--- a/world/Event.cpp
+++ b/world/Event.cpp
@@ -2195,7 +2195,13 @@ message_event::export_as_text_( std::ostream &Output ) const {
basic_event *
make_event( cParser &Input, scene::scratch_data &Scratchpad ) {
- auto const name = ToLower( Input.getToken() );
+ // getToken() already lowercases ASCII letters via the parser's toLowerChar(),
+ // which deliberately leaves bytes >= 0x80 untouched. The extra ToLower() here
+ // ran std::tolower() over every byte, so under a non-"C" global locale it
+ // remapped cp1250 uppercase accented letters (e.g. 0xAF -> 0xBF) - producing a
+ // registered name that no lookup site (Track::AssignEvents, child-event and
+ // launcher resolution) could match, since those normalize with the parser only.
+ auto const name = Input.getToken();
auto const type = Input.getToken();
basic_event *event { nullptr };