diff --git a/src/OpenTheBox/Program.cs b/src/OpenTheBox/Program.cs index 0754a79..119410b 100644 --- a/src/OpenTheBox/Program.cs +++ b/src/OpenTheBox/Program.cs @@ -237,18 +237,31 @@ public static class Program private static async Task RenderEvents(List events) { + // Collect IDs of items that are auto-consumed (auto-opening boxes) + // so we don't show "You received" for items the player never actually gets + var autoConsumedIds = events.OfType().Select(e => e.InstanceId).ToHashSet(); + foreach (var evt in events) { switch (evt) { case BoxOpenedEvent boxEvt: var boxDef = _registry.GetBox(boxEvt.BoxId); - _renderer.ShowBoxOpening( - _loc.Get(boxDef?.NameKey ?? boxEvt.BoxId), - boxDef?.Rarity.ToString() ?? "Common"); + var boxName = _loc.Get(boxDef?.NameKey ?? boxEvt.BoxId); + if (boxEvt.IsAutoOpen) + { + _renderer.ShowMessage(_loc.Get("box.auto_open", boxName)); + } + else + { + _renderer.ShowBoxOpening(boxName, boxDef?.Rarity.ToString() ?? "Common"); + } break; case ItemReceivedEvent itemEvt: + // Skip loot reveal for auto-consumed items (auto-opening boxes) + if (autoConsumedIds.Contains(itemEvt.Item.Id)) + break; _state.AddItem(itemEvt.Item); var itemDef = _registry.GetItem(itemEvt.Item.DefinitionId); var itemBoxDef = itemDef is null ? _registry.GetBox(itemEvt.Item.DefinitionId) : null; diff --git a/src/OpenTheBox/Simulation/BoxEngine.cs b/src/OpenTheBox/Simulation/BoxEngine.cs index b7dc271..6914c67 100644 --- a/src/OpenTheBox/Simulation/BoxEngine.cs +++ b/src/OpenTheBox/Simulation/BoxEngine.cs @@ -17,7 +17,7 @@ public class BoxEngine(ContentRegistry registry) /// Opens a box, evaluating its loot table against the current game state and returning /// all resulting events (items received, nested box opens, etc.). /// - public List Open(string boxDefId, GameState state, Random rng) + public List Open(string boxDefId, GameState state, Random rng, bool isAutoOpen = false) { var events = new List(); var boxDef = registry.GetBox(boxDefId); @@ -47,7 +47,7 @@ public class BoxEngine(ContentRegistry registry) } } - events.Add(new BoxOpenedEvent(boxDefId, droppedItemDefIds)); + events.Add(new BoxOpenedEvent(boxDefId, droppedItemDefIds, isAutoOpen)); // Create item instances for each dropped item foreach (var itemDefId in droppedItemDefIds) @@ -62,7 +62,7 @@ public class BoxEngine(ContentRegistry registry) { state.RemoveItem(instance.Id); events.Add(new ItemConsumedEvent(instance.Id)); - events.AddRange(Open(itemDefId, state, rng)); + events.AddRange(Open(itemDefId, state, rng, isAutoOpen: true)); } } diff --git a/src/OpenTheBox/Simulation/Events/GameEvent.cs b/src/OpenTheBox/Simulation/Events/GameEvent.cs index e40985e..cabf9ea 100644 --- a/src/OpenTheBox/Simulation/Events/GameEvent.cs +++ b/src/OpenTheBox/Simulation/Events/GameEvent.cs @@ -14,7 +14,7 @@ public abstract record GameEvent /// /// A box was opened, producing dropped items. /// -public sealed record BoxOpenedEvent(string BoxId, List DroppedItemDefIds) : GameEvent; +public sealed record BoxOpenedEvent(string BoxId, List DroppedItemDefIds, bool IsAutoOpen = false) : GameEvent; /// /// An item was received and added to inventory.