using System; using System.Collections.Immutable; using System.Linq; using System.Runtime.InteropServices; using Creatureliblibrary; using Creatureliblibrary.Generated; using PkmnLibSharp.Utilities; namespace PkmnLibSharp.Library { public class Forme : PointerWrapper { private string _name; private ImmutableArray _types; private ImmutableArray _abilities; private ImmutableArray _hiddenAbilities; private LearnableMoves _moves; public string Name => _name ??= SpeciesVariant.GetName(Ptr).PtrString(); public float Height => SpeciesVariant.GetHeight(Ptr); public float Weight => SpeciesVariant.GetWeight(Ptr); public float BaseExperience => SpeciesVariant.GetBaseExperience(Ptr); public ImmutableArray Types { get { if (_types != null) return _types; var typesCount = SpeciesVariant.GetTypeCount(Ptr); var types = new byte[typesCount]; for (ulong i = 0; i < typesCount; i++) { types[i] = SpeciesVariant.GetType(Ptr, i); } _types = types.ToImmutableArray(); return _types; } } public uint BaseHealth => SpeciesVariant.GetStatistic(Ptr, (byte) Statistic.Health); public uint BaseAttack => SpeciesVariant.GetStatistic(Ptr, (Creatureliblibrary.Statistic) Statistic.Attack); public uint BaseDefense => SpeciesVariant.GetStatistic(Ptr, (Creatureliblibrary.Statistic) Statistic.Defense); public uint BaseSpecialAttack => SpeciesVariant.GetStatistic(Ptr, (Creatureliblibrary.Statistic) Statistic.SpecialAttack); public uint BaseSpecialDefense => SpeciesVariant.GetStatistic(Ptr, (Creatureliblibrary.Statistic) Statistic.SpecialDefense); public uint BaseSpeed => SpeciesVariant.GetStatistic(Ptr, (Creatureliblibrary.Statistic) Statistic.Speed); public ImmutableArray Abilities { get { if (_abilities != null) return _abilities; var abilityCount = SpeciesVariant.GetTalentCount(Ptr); var abilities = new string[abilityCount]; for (byte i = 0; i < abilityCount; i++) { IntPtr s = IntPtr.Zero; SpeciesVariant.GetTalent(Ptr, MarshalHelper.False, i, ref s).Assert(); abilities[i] = s.PtrString(); } _abilities = abilities.ToImmutableArray(); return _abilities; } } public ImmutableArray HiddenAbilities { get { if (_hiddenAbilities != null) return _hiddenAbilities; var abilityCount = SpeciesVariant.GetSecretTalentCount(Ptr); var abilities = new string[abilityCount]; for (byte i = 0; i < abilityCount; i++) { IntPtr s = IntPtr.Zero; SpeciesVariant.GetTalent(Ptr, MarshalHelper.True, i, ref s).Assert(); abilities[i] = s.PtrString(); } _hiddenAbilities = abilities.ToImmutableArray(); return _hiddenAbilities; } } public LearnableMoves Moves { get { if (_moves != null) return _moves; var movesPtr = SpeciesVariant.GetLearnableAttacks(Ptr); if (!TryResolvePointer(movesPtr, out _moves)) { _moves = new LearnableMoves(movesPtr); } return _moves; } } public int GetPkmnType(int index) { return Types[index]; } public static unsafe Forme Create(string name, float height, float weight, uint baseExperience, byte[] types, ushort baseHealth, ushort baseAttack, ushort baseDefense, ushort baseSpecialAttack, ushort baseSpecialDefense, ushort baseSpeed, string[] abilities, string[] hiddenAbilities, LearnableMoves moves) { var abilitiesConverted = abilities.Select(x => x.ToPtr()).ToArray(); var hiddenAbilitiesConverted = hiddenAbilities.Select(x => x.ToPtr()).ToArray(); fixed (IntPtr* ab = abilitiesConverted) { fixed (IntPtr* hab = hiddenAbilitiesConverted) { var ptr = SpeciesVariant.Construct(name.ToPtr(), height, weight, baseExperience, types.ArrayPtr(), (ulong) types.Length, baseHealth, baseAttack, baseDefense, baseSpecialAttack, baseSpecialDefense, baseSpeed, (IntPtr) ab, (ulong) abilities.Length, (IntPtr) hab, (ulong) hiddenAbilities.Length, moves.Ptr); var f = new Forme(ptr); foreach (var intPtr in abilitiesConverted) Marshal.FreeHGlobal(intPtr); foreach (var intPtr in hiddenAbilitiesConverted) Marshal.FreeHGlobal(intPtr); return f; } } } internal Forme(IntPtr parent) : base(parent) { } protected override void DeletePtr() { SpeciesVariant.Destruct(Ptr); } } }