From af13380a26895a7f61152f2458e38132fa6c7dcf Mon Sep 17 00:00:00 2001 From: Samuel Bouchet Date: Sat, 14 Mar 2026 20:43:30 +0100 Subject: [PATCH] Defer interaction messages after loot reveal and replace Unicode with ASCII MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Collect InteractionTriggeredEvent during box opening and display them after the loot reveal sequence for better context - Replace โ˜… with * and โ†’ with -> for cmd.exe compatibility (CP437) - Remove emoji (๐Ÿงช๐Ÿ“œ) from event log entries --- src/OpenTheBox/Program.cs | 35 ++++++++++++++++----- src/OpenTheBox/Rendering/SpectreRenderer.cs | 12 +++---- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/OpenTheBox/Program.cs b/src/OpenTheBox/Program.cs index 6c3cad5..9b33d1d 100644 --- a/src/OpenTheBox/Program.cs +++ b/src/OpenTheBox/Program.cs @@ -460,6 +460,10 @@ public static class Program // Collect all received items to show as a single grouped loot reveal var allLoot = new List<(string name, string rarity, string category)>(); + // Collect interactions to show after loot reveal with context + var deferredInteractions = new List(); + // Track consumed item names for interaction context + var consumedItemNames = new Dictionary(); // Show only the primary box opening (not auto-opened intermediaries) bool primaryBoxShown = false; @@ -497,18 +501,28 @@ public static class Program RefreshRenderer(); var featureLabel = _loc.Get(GetUIFeatureLocKey(uiEvt.Feature)); _renderer.ShowUIFeatureUnlocked(featureLabel); - AddEventLog($"โ˜… {featureLabel}"); + AddEventLog($"* {featureLabel}"); _renderer.WaitForKeyPress(_loc.Get("prompt.press_key")); break; + case ItemConsumedEvent consumedEvt: + // Track consumed item names for interaction context + consumedItemNames[consumedEvt.InstanceId] = GetLocalizedName( + _state.Inventory.FirstOrDefault(i => i.Id == consumedEvt.InstanceId)?.DefinitionId + ?? events.OfType() + .FirstOrDefault(r => r.Item.Id == consumedEvt.InstanceId)?.Item.DefinitionId + ?? "?"); + break; + case InteractionTriggeredEvent interEvt: - _renderer.ShowInteraction(_loc.Get(interEvt.DescriptionKey)); + // Defer interaction display until after loot reveal + deferredInteractions.Add(_loc.Get(interEvt.DescriptionKey)); break; case ResourceChangedEvent resEvt: var resName = _loc.Get($"resource.{resEvt.Type.ToString().ToLower()}"); _renderer.ShowMessage($"{resName}: {resEvt.OldValue} -> {resEvt.NewValue}"); - AddEventLog($"{resName}: {resEvt.OldValue} โ†’ {resEvt.NewValue}"); + AddEventLog($"{resName}: {resEvt.OldValue} -> {resEvt.NewValue}"); break; case MessageEvent msgEvt: @@ -526,7 +540,7 @@ public static class Program case AdventureUnlockedEvent advUnlockedEvt: var advName = GetAdventureName(advUnlockedEvt.Theme); _renderer.ShowMessage(_loc.Get("adventure.unlocked", advName)); - AddEventLog($"๐Ÿ—บ {advName}"); + AddEventLog($">> {advName}"); break; case AdventureStartedEvent advEvt: @@ -581,6 +595,13 @@ public static class Program } } + // Show deferred interactions after the loot reveal, with context + foreach (var interactionMsg in deferredInteractions) + { + _renderer.ShowMessage(""); + _renderer.ShowInteraction(interactionMsg); + } + _renderer.WaitForKeyPress(_loc.Get("prompt.press_key")); } @@ -737,8 +758,8 @@ public static class Program ? _loc.Get("inventory.item_used_qty", itemName, remaining.ToString()) : _loc.Get("inventory.item_used", itemName); _renderer.ShowMessage(usedMsg); - _renderer.ShowMessage($"{resName}: {resEvt.OldValue} โ†’ {resEvt.NewValue}"); - AddEventLog($"๐Ÿงช {itemName} โ†’ {resName} {resEvt.OldValue}โ†’{resEvt.NewValue}"); + _renderer.ShowMessage($"{resName}: {resEvt.OldValue} -> {resEvt.NewValue}"); + AddEventLog($"{itemName} -> {resName} {resEvt.OldValue}->{resEvt.NewValue}"); break; case MessageEvent msgEvt: _renderer.ShowMessage(_loc.Get(msgEvt.MessageKey, msgEvt.Args ?? [])); @@ -787,7 +808,7 @@ public static class Program string loreText = _loc.Get(loreKey); var panel = new Panel($"[italic]{Markup.Escape(loreText)}[/]") - .Header($"[bold yellow]๐Ÿ“œ {Markup.Escape(name)}[/]") + .Header($"[bold yellow]{Markup.Escape(name)}[/]") .Border(BoxBorder.Double) .BorderStyle(new Style(Color.Yellow)) .Padding(2, 1) diff --git a/src/OpenTheBox/Rendering/SpectreRenderer.cs b/src/OpenTheBox/Rendering/SpectreRenderer.cs index 2978352..9dba95d 100644 --- a/src/OpenTheBox/Rendering/SpectreRenderer.cs +++ b/src/OpenTheBox/Rendering/SpectreRenderer.cs @@ -323,7 +323,7 @@ public sealed class SpectreRenderer : IRenderer { if (_context.HasColors) { - var panel = new Panel($"[bold yellow]โ˜… {Markup.Escape(featureName)} โ˜…[/]") + var panel = new Panel($"[bold yellow]* {Markup.Escape(featureName)} *[/]") .Border(BoxBorder.Double) .BorderStyle(new Style(Color.Yellow)) .Padding(2, 0) @@ -333,7 +333,7 @@ public sealed class SpectreRenderer : IRenderer else { Console.WriteLine("========================================"); - Console.WriteLine($" โ˜… {featureName} โ˜…"); + Console.WriteLine($" * {featureName} *"); Console.WriteLine("========================================"); } } @@ -431,10 +431,10 @@ public sealed class SpectreRenderer : IRenderer /// private static string RarityStars(string rarity) => rarity.ToLowerInvariant() switch { - "rare" => "โ˜… ", - "epic" => "โ˜…โ˜… ", - "legendary" => "โ˜…โ˜…โ˜… ", - "mythic" => "โ˜…โ˜…โ˜…โ˜… ", + "rare" => "* ", + "epic" => "** ", + "legendary" => "*** ", + "mythic" => "**** ", _ => "" };