using System.Collections.Immutable; using System.Text.Json; using JetBrains.Annotations; using PkmnLib.Dynamic.Libraries.DataLoaders.Models; using PkmnLib.Static; using PkmnLib.Static.Libraries; using PkmnLib.Static.Moves; using PkmnLib.Static.Utils; namespace PkmnLib.Dynamic.Libraries.DataLoaders; /// /// Loads item data from a JSON file. /// public static class ItemDataLoader { /// /// Loads the item library from a JSON file. /// public static ItemLibrary LoadItems(Stream stream, Action>? onAfterLoad = null) { var library = new ItemLibrary(); var obj = JsonSerializer.Deserialize>(stream, JsonOptions.DefaultOptions); if (obj == null) throw new InvalidDataException("Item data is empty."); onAfterLoad?.Invoke(obj); var items = obj.Select(DeserializeItem); foreach (var i in items) library.Add(i); return library; } /// /// Factory delegate for creating items. /// public delegate IItem ItemFactoryDelegate(SerializedItem serialized, StringKey name, ItemCategory type, BattleItemCategory battleType, int price, ImmutableHashSet flags, ISecondaryEffect? effect, ISecondaryEffect? battleTriggerEffect, Dictionary additionalData); /// /// The item constructor. This is used to create items from the JSON data. /// [PublicAPI] public static ItemFactoryDelegate ItemConstructor { get; set; } = (_, name, type, battleType, price, flags, effect, battleTriggerEffect, additionalData) => new ItemImpl(name, type, battleType, price, flags, effect, battleTriggerEffect, additionalData); private static IItem DeserializeItem(SerializedItem serialized) { if (!Enum.TryParse(serialized.ItemType, true, out var itemType)) throw new InvalidDataException($"Item type {serialized.ItemType} is not valid for item {serialized.Name}."); Enum.TryParse(serialized.BattleType, true, out BattleItemCategory battleType); var effect = serialized.Effect?.ParseEffect(); var battleTriggerEffect = serialized.BattleEffect?.ParseEffect(); var additionalData = serialized.AdditionalData?.ToDictionary(x => (StringKey)x.Key, x => x.Value.ToParameter()) ?? new Dictionary(); return ItemConstructor(serialized, serialized.Name, itemType, battleType, serialized.Price, serialized.Flags.Select(x => (StringKey)x).ToImmutableHashSet(), effect, battleTriggerEffect, additionalData); } }