using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using PkmnLibSharp.Library; using PkmnLibSharp.Utilities; using Item = PkmnLibSharp.Library.Items.Item; using Nature = PkmnLibSharp.Library.Nature; namespace PkmnLibSharp.Battling { public class Pokemon : PointerWrapper { public Pokemon(){} internal Pokemon(IntPtr ptr) : base(ptr) { Initialize(ptr); } public Pokemon([NotNull] BattleLibrary library, [NotNull] Species species, [NotNull] Forme forme, byte level, uint experience, uint uid, Gender gender, byte coloring, [MaybeNull] Item heldItem, [MaybeNull] string nickname, bool hiddenAbility, byte abilityIndex, [NotNull] IReadOnlyCollection moves, StatisticSet ivs, StatisticSet evs, [NotNull] Nature nature) : base(Pkmnlib.Generated.Pokemon.Construct( library.Ptr, species.Ptr, forme.Ptr, level, experience, uid, (Pkmnlib.Gender) gender, coloring, heldItem?.Ptr ?? IntPtr.Zero, nickname.ToPtr(), hiddenAbility.ToNative(), abilityIndex, moves.Select(x => x?.Ptr ?? IntPtr.Zero).ToArray().ArrayPtr(), (ulong) moves.Count, ivs.HP, ivs.Attack, ivs.Defense, ivs.SpecialAttack, ivs.SpecialDefense, ivs.Speed, evs.HP, evs.Attack, evs.Defense, evs.SpecialAttack, evs.SpecialDefense, evs.Speed, nature.Ptr)) { Library = library; } protected internal override void Initialize(IntPtr ptr) { base.Initialize(ptr); Library = new BattleLibrary(Creaturelib.Generated.Creature.GetLibrary(Ptr)); } public BattleLibrary Library { get; private set; } public Species Species { get { if (_species != null) return _species; var ptr = Creaturelib.Generated.Creature.GetSpecies(Ptr); if (TryResolvePointer(ptr, out _species)) return _species; _species = new Species(ptr); return _species; } } public Forme Forme { get { if (_forme != null) return _forme; var ptr = Creaturelib.Generated.Creature.GetVariant(Ptr); if (TryResolvePointer(ptr, out _forme)) return _forme; _forme = new Forme(ptr); return _forme; } } public Species DisplaySpecies { get { if (_displaySpecies != null) return _displaySpecies; var ptr = Creaturelib.Generated.Creature.GetDisplaySpecies(Ptr); if (TryResolvePointer(ptr, out _displaySpecies)) return _displaySpecies; _displaySpecies = new Species(ptr); return _displaySpecies; } set => Creaturelib.Generated.Creature.SetDisplaySpecies(Ptr, value.Ptr); } public Forme DisplayForme { get { if (_displayForme != null) return _displayForme; var ptr = Creaturelib.Generated.Creature.GetDisplayVariant(Ptr); if (TryResolvePointer(ptr, out _displayForme)) return _displayForme; _displayForme = new Forme(ptr); return _displayForme; } set => Creaturelib.Generated.Creature.SetDisplayVariant(Ptr, value.Ptr); } public byte Level => Creaturelib.Generated.Creature.GetLevel(Ptr); public uint Experience => Creaturelib.Generated.Creature.GetExperience(Ptr); public Gender Gender => (Gender) Creaturelib.Generated.Creature.GetGender(Ptr); public byte Coloring => Creaturelib.Generated.Creature.GetColoring(Ptr); public bool IsShiny => Pkmnlib.Generated.Pokemon.IsShiny(Ptr) == 1; public uint CurrentHealth => Creaturelib.Generated.Creature.GetCurrentHealth(Ptr); public uint MaxHealth => Creaturelib.Generated.Creature.GetMaxHealth(Ptr); public string ActiveAbility { get { var ptr = IntPtr.Zero; Creaturelib.Generated.Creature.GetActiveTalent(Ptr, ref ptr).Assert(); return ptr.PtrString(); } } public Battle Battle { get { var ptr = Creaturelib.Generated.Creature.GetBattle(Ptr); if (_battle != null && _battle.Ptr == ptr) return _battle; if (TryResolvePointer(ptr, out _battle)) return _battle; _battle = new Battle(ptr); return _battle; } } public BattleSide BattleSide { get { var ptr = Creaturelib.Generated.Creature.GetBattleSide(Ptr); if (_battleSide != null && _battleSide.Ptr == ptr) return _battleSide; if (TryResolvePointer(ptr, out _battleSide)) return _battleSide; _battleSide = new BattleSide(ptr); return _battleSide; } } public bool IsOnBattleField => Creaturelib.Generated.Creature.IsOnBattleField(Ptr) == 1; public Item HeldItem { get { var ptr = Creaturelib.Generated.Creature.GetHeldItem(Ptr); if (ptr == IntPtr.Zero) return null; if (!TryResolvePointer(ptr, out Item item)) { item = new Item(ptr); } return item; } set => Creaturelib.Generated.Creature.SetHeldItemFromItem(Ptr, value?.Ptr ?? IntPtr.Zero); } public string Nickname { get { if (_nickname != null) return _nickname; _nickname = Creaturelib.Generated.Creature.GetNickname(Ptr).PtrString(); return _nickname; } } public ReadOnlyNativePtrArray Moves { get { if (_moves != null) return _moves; var movesLength = Creaturelib.Generated.Creature.GetAttacksCount(Ptr); var movesPtr = Creaturelib.Generated.Creature.GetAttacks(Ptr); _moves = new ReadOnlyNativePtrArray(movesPtr, (int) movesLength); return _moves; } } public sbyte HpBoost => GetStatBoost(Statistic.Health); public sbyte AttackBoost => GetStatBoost(Statistic.Attack); public sbyte DefenseBoost => GetStatBoost(Statistic.Defense); public sbyte SpecialAttackBoost => GetStatBoost(Statistic.SpecialAttack); public sbyte SpecialDefenseBoost => GetStatBoost(Statistic.SpecialDefense); public sbyte SpeedBoost => GetStatBoost(Statistic.Speed); public uint BaseHp => GetBaseStat(Statistic.Health); public uint BaseAttack => GetBaseStat(Statistic.Attack); public uint BaseDefense => GetBaseStat(Statistic.Defense); public uint BaseSpecialAttack => GetBaseStat(Statistic.SpecialAttack); public uint BaseSpecialDefense => GetBaseStat(Statistic.SpecialDefense); public uint BaseSpeed => GetBaseStat(Statistic.Speed); public uint FlatHp => GetFlatStat(Statistic.Health); public uint FlatAttack => GetFlatStat(Statistic.Attack); public uint FlatDefense => GetFlatStat(Statistic.Defense); public uint FlatSpecialAttack => GetFlatStat(Statistic.SpecialAttack); public uint FlatSpecialDefense => GetFlatStat(Statistic.SpecialDefense); public uint FlatSpeed => GetFlatStat(Statistic.Speed); public uint BoostedHp => GetBoostedStat(Statistic.Health); public uint BoostedAttack => GetBoostedStat(Statistic.Attack); public uint BoostedDefense => GetBoostedStat(Statistic.Defense); public uint BoostedSpecialAttack => GetBoostedStat(Statistic.SpecialAttack); public uint BoostedSpecialDefense => GetBoostedStat(Statistic.SpecialDefense); public uint BoostedSpeed => GetBoostedStat(Statistic.Speed); public byte HpIv => GetIndividualValue(Statistic.Health); public byte AttackIv => GetIndividualValue(Statistic.Attack); public byte DefenseIv => GetIndividualValue(Statistic.Defense); public byte SpecialAttackIv => GetIndividualValue(Statistic.SpecialAttack); public byte SpecialDefenseIv => GetIndividualValue(Statistic.SpecialDefense); public byte SpeedIv => GetIndividualValue(Statistic.Speed); public byte HpEv => GetEffortValue(Statistic.Health); public byte AttackEv => GetEffortValue(Statistic.Attack); public byte DefenseEv => GetEffortValue(Statistic.Defense); public byte SpecialAttackEv => GetEffortValue(Statistic.SpecialAttack); public byte SpecialDefenseEv => GetEffortValue(Statistic.SpecialDefense); public byte SpeedEv => GetEffortValue(Statistic.Speed); public Nature Nature { get { if (_nature != null) return _nature; var ptr = Pkmnlib.Generated.Pokemon.GetNature(Ptr); if (TryResolvePointer(ptr, out _nature)) return _nature; _nature = new Nature(ptr); return _nature; } } public string StatusName => Pkmnlib.Generated.Pokemon.GetStatusName(Ptr).PtrString(); public void ChangeForme(Forme forme) { _forme = null; Creaturelib.Generated.Creature.ChangeVariant(Ptr, forme.Ptr); } public bool HasHeldItem(string itemName) { return Creaturelib.Generated.Creature.HasHeldItem(Ptr, itemName.ToPtr()) == 1; } public void SetHeldItem(string item) { if (string.IsNullOrEmpty(item)) Creaturelib.Generated.Creature.SetHeldItemFromItem(Ptr, IntPtr.Zero); else Creaturelib.Generated.Creature.SetHeldItem(Ptr, item.ToPtr()); } public bool HasType(string type) { var typeByte = Library.StaticLibrary.TypeLibrary.GetTypeId(type); return Creaturelib.Generated.Creature.HasType(Ptr, typeByte) == 1; } public void ChangeLevelBy(sbyte amount) { Creaturelib.Generated.Creature.ChangeLevelBy(Ptr, amount).Assert(); } public void AddExperience(uint experience) { Creaturelib.Generated.Creature.AddExperience(Ptr, experience).Assert(); } public void Damage(uint damage, DamageSource source) { Creaturelib.Generated.Creature.Damage(Ptr, damage, (Creaturelib.DamageSource) source); } public void Heal(uint damage, bool canRevive) { Creaturelib.Generated.Creature.Heal(Ptr, damage, canRevive.ToNative()); } public void RestoreAllPP() { Creaturelib.Generated.Creature.RestoreAllAttackUses(Ptr); } public void OverrideActiveAbility(string ability) { Creaturelib.Generated.Creature.OverrideActiveTalent(Ptr, ability.ToPtr()).Assert(); } public void ClearVolatileScripts() { Creaturelib.Generated.Creature.ClearVolatileScripts(Ptr).Assert(); } public void AddVolatileScript(string scriptName) { Creaturelib.Generated.Creature.AddVolatileScriptByName(Ptr, scriptName.ToPtr()).Assert(); } public void AddVolatileScript(Script script) { Creaturelib.Generated.Creature.AddVolatileScript(Ptr, script.Ptr).Assert(); } public void RemoveVolatileScript(string scriptName) { Creaturelib.Generated.Creature.RemoveVolatileScriptByName(Ptr, scriptName.ToPtr()).Assert(); } public void RemoveVolatileScript(Script script) { Creaturelib.Generated.Creature.RemoveVolatileScript(Ptr, script.Ptr).Assert(); } public bool HasVolatileScript(string scriptName) { return Creaturelib.Generated.Creature.HasVolatileScript(Ptr, scriptName.ToPtr()) == 1; } public sbyte GetStatBoost(Statistic stat) { return Creaturelib.Generated.Creature.GetStatBoost(Ptr, (Creaturelib.Statistic) stat); } public void ChangeStatBoost(Statistic stat, sbyte amount) { Creaturelib.Generated.Creature.ChangeStatBoost(Ptr, (Creaturelib.Statistic) stat, amount); } public uint GetBaseStat(Statistic stat) { return Creaturelib.Generated.Creature.GetBaseStat(Ptr, (Creaturelib.Statistic) stat); } public uint GetFlatStat(Statistic stat) { return Creaturelib.Generated.Creature.GetFlatStat(Ptr, (Creaturelib.Statistic) stat); } public uint GetBoostedStat(Statistic stat) { return Creaturelib.Generated.Creature.GetBoostedStat(Ptr, (Creaturelib.Statistic) stat); } public byte GetIndividualValue(Statistic stat) { return Pkmnlib.Generated.Pokemon.GetIndividualValue(Ptr, (Pkmnlib.Statistic) stat); } public byte GetEffortValue(Statistic stat) { return Pkmnlib.Generated.Pokemon.GetEffortValue(Ptr, (Pkmnlib.Statistic) stat); } public void SetStatus(string name) { Pkmnlib.Generated.Pokemon.SetStatus(Ptr, name.ToPtr()); } public void ClearStatus() { Pkmnlib.Generated.Pokemon.ClearStatus(Ptr); } private Species _displaySpecies; private Forme _displayForme; private Species _species; private Forme _forme; private string _nickname; private ReadOnlyNativePtrArray _moves; private Nature _nature; private Battle _battle; private BattleSide _battleSide; protected override void DeletePtr() { Pkmnlib.Generated.Pokemon.Destruct(Ptr); } protected internal override void MarkAsDeleted() { foreach (var move in Moves) { move?.MarkAsDeleted(); } base.MarkAsDeleted(); } } }