93 lines
3.5 KiB
C#
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;
|
|
}
|
|
}
|