84 lines
3 KiB
C#
84 lines
3 KiB
C#
|
|
using System.Text.Json;
|
||
|
|
using OpenTheBox.Core.Boxes;
|
||
|
|
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 static readonly JsonSerializerOptions JsonOptions = new()
|
||
|
|
{
|
||
|
|
PropertyNameCaseInsensitive = true,
|
||
|
|
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() }
|
||
|
|
};
|
||
|
|
|
||
|
|
private readonly Dictionary<string, ItemDefinition> _items = [];
|
||
|
|
private readonly Dictionary<string, BoxDefinition> _boxes = [];
|
||
|
|
private readonly List<InteractionRule> _interactionRules = [];
|
||
|
|
|
||
|
|
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 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;
|
||
|
|
|
||
|
|
/// <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)
|
||
|
|
{
|
||
|
|
var registry = new ContentRegistry();
|
||
|
|
|
||
|
|
if (File.Exists(itemsPath))
|
||
|
|
{
|
||
|
|
var json = File.ReadAllText(itemsPath);
|
||
|
|
var items = JsonSerializer.Deserialize<List<ItemDefinition>>(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<List<BoxDefinition>>(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<List<InteractionRule>>(json, JsonOptions);
|
||
|
|
if (rules is not null)
|
||
|
|
{
|
||
|
|
foreach (var rule in rules)
|
||
|
|
registry.RegisterInteractionRule(rule);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return registry;
|
||
|
|
}
|
||
|
|
}
|