using System.Text.Json;
using OpenTheBox.Core.Boxes;
using OpenTheBox.Core.Crafting;
using OpenTheBox.Core.Interactions;
using OpenTheBox.Core.Items;
namespace OpenTheBox.Data;
///
/// 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.
///
public class ContentRegistry
{
private static readonly JsonSerializerOptions JsonOptions = new()
{
PropertyNameCaseInsensitive = true,
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() }
};
private readonly Dictionary _items = [];
private readonly Dictionary _boxes = [];
private readonly List _interactionRules = [];
private readonly Dictionary _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);
///
/// Returns true if the given definition id corresponds to a registered box.
///
public bool IsBox(string id) => _boxes.ContainsKey(id);
public IReadOnlyDictionary Items => _items;
public IReadOnlyDictionary Boxes => _boxes;
public IReadOnlyList InteractionRules => _interactionRules;
public IReadOnlyDictionary Recipes => _recipes;
///
/// Loads content definitions from JSON files and returns a populated registry.
/// Files that do not exist are silently skipped.
///
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, JsonOptions);
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, JsonOptions);
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, JsonOptions);
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, JsonOptions);
if (recipes is not null)
{
foreach (var recipe in recipes)
registry.RegisterRecipe(recipe);
}
}
return registry;
}
}