openthebox/src/OpenTheBox/Data/ContentRegistry.cs
2026-03-11 22:19:25 +01:00

93 lines
3.5 KiB
C#

using System.Text.Json;
using OpenTheBox.Core.Boxes;
using OpenTheBox.Core.Crafting;
using OpenTheBox.Core.Interactions;
using OpenTheBox.Core.Items;
namespace OpenTheBox.Data;
/// <summary>
/// Central registry for all game content definitions (items, boxes, interaction rules).
/// Content is loaded from data files and registered here for lookup by the simulation engines.
/// </summary>
public class ContentRegistry
{
private readonly Dictionary<string, ItemDefinition> _items = [];
private readonly Dictionary<string, BoxDefinition> _boxes = [];
private readonly List<InteractionRule> _interactionRules = [];
private readonly Dictionary<string, Recipe> _recipes = [];
public void RegisterItem(ItemDefinition item) => _items[item.Id] = item;
public void RegisterBox(BoxDefinition box) => _boxes[box.Id] = box;
public void RegisterInteractionRule(InteractionRule rule) => _interactionRules.Add(rule);
public void RegisterRecipe(Recipe recipe) => _recipes[recipe.Id] = recipe;
public ItemDefinition? GetItem(string id) => _items.GetValueOrDefault(id);
public BoxDefinition? GetBox(string id) => _boxes.GetValueOrDefault(id);
/// <summary>
/// Returns true if the given definition id corresponds to a registered box.
/// </summary>
public bool IsBox(string id) => _boxes.ContainsKey(id);
public IReadOnlyDictionary<string, ItemDefinition> Items => _items;
public IReadOnlyDictionary<string, BoxDefinition> Boxes => _boxes;
public IReadOnlyList<InteractionRule> InteractionRules => _interactionRules;
public IReadOnlyDictionary<string, Recipe> Recipes => _recipes;
/// <summary>
/// Loads content definitions from JSON files and returns a populated registry.
/// Files that do not exist are silently skipped.
/// </summary>
public static ContentRegistry LoadFromFiles(
string itemsPath, string boxesPath, string interactionsPath, string? recipesPath = null)
{
var registry = new ContentRegistry();
if (File.Exists(itemsPath))
{
var json = File.ReadAllText(itemsPath);
var items = JsonSerializer.Deserialize(json, ContentJsonContext.Default.ListItemDefinition);
if (items is not null)
{
foreach (var item in items)
registry.RegisterItem(item);
}
}
if (File.Exists(boxesPath))
{
var json = File.ReadAllText(boxesPath);
var boxes = JsonSerializer.Deserialize(json, ContentJsonContext.Default.ListBoxDefinition);
if (boxes is not null)
{
foreach (var box in boxes)
registry.RegisterBox(box);
}
}
if (File.Exists(interactionsPath))
{
var json = File.ReadAllText(interactionsPath);
var rules = JsonSerializer.Deserialize(json, ContentJsonContext.Default.ListInteractionRule);
if (rules is not null)
{
foreach (var rule in rules)
registry.RegisterInteractionRule(rule);
}
}
if (recipesPath is not null && File.Exists(recipesPath))
{
var json = File.ReadAllText(recipesPath);
var recipes = JsonSerializer.Deserialize(json, ContentJsonContext.Default.ListRecipe);
if (recipes is not null)
{
foreach (var recipe in recipes)
registry.RegisterRecipe(recipe);
}
}
return registry;
}
}