openthebox/src/OpenTheBox/Core/GameState.cs
Samuel Bouchet 04894a4906 Initial project setup: Open The Box CLI game
- .NET 10 console app with Spectre.Console and Loreline integration
- Black Box Sim architecture (simulation separated from presentation)
- Progressive CLI rendering (9 phases from basic to full layout)
- 25+ box definitions with weighted loot tables
- 100+ item definitions (meta, cosmetics, materials, adventure tokens)
- 9 Loreline adventures (Space, Medieval, Pirate, etc.)
- Bilingual content (EN/FR)
- Save/load system
- Game Design Document
2026-03-10 18:24:01 +01:00

105 lines
3.9 KiB
C#

using OpenTheBox.Core.Characters;
using OpenTheBox.Core.Enums;
using OpenTheBox.Core.Items;
namespace OpenTheBox.Core;
/// <summary>
/// Represents the current/max pair for a resource.
/// </summary>
public sealed record ResourceState(int Current, int Max);
/// <summary>
/// The complete player state, containing all inventory, progression, and configuration data.
/// </summary>
public sealed class GameState
{
public required string PlayerName { get; set; }
public required PlayerAppearance Appearance { get; set; }
public required List<ItemInstance> Inventory { get; set; }
public required Dictionary<ResourceType, ResourceState> Resources { get; set; }
public required Dictionary<StatType, int> Stats { get; set; }
public required HashSet<UIFeature> UnlockedUIFeatures { get; set; }
public required HashSet<WorkstationType> UnlockedWorkstations { get; set; }
public required HashSet<AdventureTheme> UnlockedAdventures { get; set; }
public required HashSet<string> UnlockedCosmetics { get; set; }
public required HashSet<string> CompletedAdventures { get; set; }
public required Dictionary<string, string> AdventureSaveData { get; set; }
public required HashSet<ResourceType> VisibleResources { get; set; }
public required HashSet<StatType> VisibleStats { get; set; }
public required int TotalBoxesOpened { get; set; }
public required Locale CurrentLocale { get; set; }
public required DateTime CreatedAt { get; set; }
public required TimeSpan TotalPlayTime { get; set; }
public required HashSet<FontStyle> AvailableFonts { get; set; }
public required HashSet<TextColor> AvailableTextColors { get; set; }
/// <summary>
/// Returns the current value of a resource, or 0 if the resource is not tracked.
/// </summary>
public int GetResource(ResourceType type)
=> Resources.TryGetValue(type, out var state) ? state.Current : 0;
/// <summary>
/// Returns true if the inventory contains at least one item with the given definition id.
/// </summary>
public bool HasItem(string defId)
=> Inventory.Any(i => i.DefinitionId == defId);
/// <summary>
/// Counts the total quantity of items matching the given definition id.
/// </summary>
public int CountItems(string defId)
=> Inventory.Where(i => i.DefinitionId == defId).Sum(i => i.Quantity);
/// <summary>
/// Returns true if the given UI feature has been unlocked.
/// </summary>
public bool HasUIFeature(UIFeature feature)
=> UnlockedUIFeatures.Contains(feature);
/// <summary>
/// Adds an item instance to the inventory.
/// </summary>
public void AddItem(ItemInstance item)
=> Inventory.Add(item);
/// <summary>
/// Removes an item instance from the inventory by its unique instance id.
/// Returns true if the item was found and removed.
/// </summary>
public bool RemoveItem(Guid id)
{
var item = Inventory.FirstOrDefault(i => i.Id == id);
if (item is null)
return false;
return Inventory.Remove(item);
}
/// <summary>
/// Factory method to create a new GameState with empty collections and sensible defaults.
/// </summary>
public static GameState Create(string name, Locale locale) => new()
{
PlayerName = name,
Appearance = new PlayerAppearance(),
Inventory = [],
Resources = [],
Stats = [],
UnlockedUIFeatures = [],
UnlockedWorkstations = [],
UnlockedAdventures = [],
UnlockedCosmetics = [],
CompletedAdventures = [],
AdventureSaveData = [],
VisibleResources = [],
VisibleStats = [],
TotalBoxesOpened = 0,
CurrentLocale = locale,
CreatedAt = DateTime.UtcNow,
TotalPlayTime = TimeSpan.Zero,
AvailableFonts = [],
AvailableTextColors = []
};
}