PkmnLibSharp/PkmnLibSharp/Library/Species/Forme.cs

158 lines
5.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using Creaturelib.Generated;
using Pkmnlib.Generated;
using PkmnLibSharp.Utilities;
using Random = PkmnLibSharp.Utilities.Random;
namespace PkmnLibSharp.Library
{
public class Forme : PointerWrapper
{
private ReadOnlyArray<Ability>? _abilities;
private ReadOnlyArray<Ability>? _hiddenAbilities;
private LearnableMoves? _moves;
private string? _name;
private ReadOnlyArray<byte>? _types;
public Forme(string name, float height, float weight, uint baseExperience, byte[] types, ushort baseHealth,
ushort baseAttack, ushort baseDefense, ushort baseSpecialAttack, ushort baseSpecialDefense,
ushort baseSpeed, IReadOnlyCollection<Ability> abilities, IReadOnlyCollection<Ability> hiddenAbilities,
LearnableMoves moves, IReadOnlyCollection<string> tags)
{
var abilitiesConverted = abilities.Select(x => x.Ptr).ToArray();
var hiddenAbilitiesConverted = hiddenAbilities.Select(x => x.Ptr).ToArray();
var tagsConverted = tags.Select(x => x.ToPtr()).ToArray();
var ab = abilitiesConverted.ArrayPtr();
var hab = hiddenAbilitiesConverted.ArrayPtr();
var tagsPtr = tagsConverted.ArrayPtr();
var ptr = PokemonForme.Construct(name.ToPtr(), height, weight, baseExperience, types.ArrayPtr(),
(ulong)types.Length, baseHealth, baseAttack, baseDefense, baseSpecialAttack, baseSpecialDefense,
baseSpeed, ab, (ulong)abilities.Count, hab, (ulong)hiddenAbilities.Count, moves.Ptr, tagsPtr,
(ulong)tags.Count);
Initialize(ptr);
}
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 ReadOnlyArray<byte> 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.ToReadOnly();
return _types;
}
}
public uint BaseHealth => SpeciesVariant.GetStatistic(Ptr, (byte)Statistic.Health);
public uint BaseAttack => SpeciesVariant.GetStatistic(Ptr, (Creaturelib.Statistic)Statistic.Attack);
public uint BaseDefense => SpeciesVariant.GetStatistic(Ptr, (Creaturelib.Statistic)Statistic.Defense);
public uint BaseSpecialAttack =>
SpeciesVariant.GetStatistic(Ptr, (Creaturelib.Statistic)Statistic.SpecialAttack);
public uint BaseSpecialDefense =>
SpeciesVariant.GetStatistic(Ptr, (Creaturelib.Statistic)Statistic.SpecialDefense);
public uint BaseSpeed => SpeciesVariant.GetStatistic(Ptr, (Creaturelib.Statistic)Statistic.Speed);
public ReadOnlyArray<Ability> Abilities
{
get
{
if (_abilities != null)
return _abilities;
var abilityCount = SpeciesVariant.GetTalentCount(Ptr);
var abilities = new Ability[abilityCount];
for (byte i = 0; i < abilityCount; i++)
{
var s = IntPtr.Zero;
SpeciesVariant.GetTalent(Ptr, MarshalHelper.False, i, ref s).Assert();
abilities[i] = Constructor.Active.ConstructAbility(s)!;
}
_abilities = abilities.ToReadOnly();
return _abilities;
}
}
public ReadOnlyArray<Ability> HiddenAbilities
{
get
{
if (_hiddenAbilities != null)
return _hiddenAbilities;
var abilityCount = SpeciesVariant.GetSecretTalentCount(Ptr);
var abilities = new Ability[abilityCount];
for (byte i = 0; i < abilityCount; i++)
{
var s = IntPtr.Zero;
SpeciesVariant.GetTalent(Ptr, MarshalHelper.True, i, ref s).Assert();
abilities[i] = Constructor.Active.ConstructAbility(s)!;
}
_hiddenAbilities = abilities.ToReadOnly();
return _hiddenAbilities;
}
}
public LearnableMoves Moves
{
get
{
if (_moves != null) return _moves;
var movesPtr = SpeciesVariant.GetLearnableAttacks(Ptr);
if (!TryResolvePointer(movesPtr, out _moves))
_moves = Constructor.Active.ConstructLearnableMoves(movesPtr);
return _moves!;
}
}
public byte GetPkmnType(int index)
{
return Types[index];
}
public byte GetRandomAbility(Random rand)
{
return SpeciesVariant.GetRandomTalent(Ptr, rand.Ptr);
}
public bool HasFlag(string flag)
{
return SpeciesVariant.HasFlag(Ptr, flag.ToPtr()) == 1;
}
public override string ToString()
{
return base.ToString() + $": {Name}";
}
protected internal override void MarkAsDeleted()
{
base.MarkAsDeleted();
_moves?.MarkAsDeleted();
}
protected override void DeletePtr()
{
SpeciesVariant.Destruct(Ptr);
}
}
}