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);
}
}