diff --git a/PkmnLibSharp/Battling/Pokemon.cs b/PkmnLibSharp/Battling/Pokemon.cs index 24257b6..9a94bed 100644 --- a/PkmnLibSharp/Battling/Pokemon.cs +++ b/PkmnLibSharp/Battling/Pokemon.cs @@ -55,11 +55,37 @@ namespace PkmnLibSharp.Battling return _forme; } } + public Species DisplaySpecies + { + get + { + if (_displaySpecies != null) return _displaySpecies; + var ptr = Creaturelibbattling.Generated.Creature.GetDisplaySpecies(Ptr); + if (TryResolvePointer(ptr, out _displaySpecies)) + return _displaySpecies; + _displaySpecies = new Species(ptr); + return _displaySpecies; + } + set => Creaturelibbattling.Generated.Creature.SetDisplaySpecies(Ptr, value.Ptr); + } + public Forme DisplayForme + { + get + { + if (_displayForme != null) return _displayForme; + var ptr = Creaturelibbattling.Generated.Creature.GetDisplayVariant(Ptr); + if (TryResolvePointer(ptr, out _displayForme)) + return _displayForme; + _displayForme = new Forme(ptr); + return _displayForme; + } + set => Creaturelibbattling.Generated.Creature.SetDisplayVariant(Ptr, value.Ptr); + } public byte Level => Creaturelibbattling.Generated.Creature.GetLevel(Ptr); public uint Experience => Creaturelibbattling.Generated.Creature.GetExperience(Ptr); public Gender Gender => (Gender) Creaturelibbattling.Generated.Creature.GetGender(Ptr); public byte Coloring => Creaturelibbattling.Generated.Creature.GetColoring(Ptr); - public bool IsShiny => Coloring == 1; + public bool IsShiny => Pkmnlib.Generated.Pokemon.IsShiny(Ptr) == 1; public uint CurrentHealth => Creaturelibbattling.Generated.Creature.GetCurrentHealth(Ptr); public uint MaxHealth => Creaturelibbattling.Generated.Creature.GetMaxHealth(Ptr); @@ -72,13 +98,11 @@ namespace PkmnLibSharp.Battling return ptr.PtrString(); } } - // TODO: Change to wrapped public IntPtr Battle => Creaturelibbattling.Generated.Creature.GetBattle(Ptr); // TODO: Change to wrapped public IntPtr BattleSide => Creaturelibbattling.Generated.Creature.GetBattleSide(Ptr); public bool IsOnBattleField => Creaturelibbattling.Generated.Creature.IsOnBattleField(Ptr) == 1; - public Item HeldItem { get @@ -95,7 +119,6 @@ namespace PkmnLibSharp.Battling Creaturelibbattling.Generated.Creature.SetHeldItemFromItem(Ptr, value?.Ptr ?? IntPtr.Zero); } - public string Nickname { get @@ -105,18 +128,82 @@ namespace PkmnLibSharp.Battling return _nickname; } } + public ReadOnlyNativePtrArray Moves + { + get + { + if (_moves != null) return _moves; + var movesLength = Creaturelibbattling.Generated.Creature.GetAttacksCount(Ptr); + var movesPtr = Creaturelibbattling.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 void ChangeForme(Forme forme) { _forme = null; Creaturelibbattling.Generated.Creature.ChangeVariant(Ptr, forme.Ptr); } - public bool HasHeldItem(string itemName) { return Creaturelibbattling.Generated.Creature.HasHeldItem(Ptr, itemName.ToPtr()) == 1; } - public void SetHeldItem(string item) { if (string.IsNullOrEmpty(item)) @@ -124,83 +211,95 @@ namespace PkmnLibSharp.Battling else Creaturelibbattling.Generated.Creature.SetHeldItem(Ptr, item.ToPtr()); } - public bool HasType(string type) { var typeByte = Library.StaticLibrary.TypeLibrary.GetTypeId(type); return Creaturelibbattling.Generated.Creature.HasType(Ptr, typeByte) == 1; } - public void ChangeLevelBy(sbyte amount) { Creaturelibbattling.Generated.Creature.ChangeLevelBy(Ptr, amount).Assert(); } - public void AddExperience(uint experience) { Creaturelibbattling.Generated.Creature.AddExperience(Ptr, experience).Assert(); } - public void Damage(uint damage, DamageSource source) { Creaturelibbattling.Generated.Creature.Damage(Ptr, damage, (Creaturelibbattling.DamageSource) source); } - public void Heal(uint damage, bool canRevive) { Creaturelibbattling.Generated.Creature.Heal(Ptr, damage, canRevive.ToNative()); } - public void OverrideActiveAbility(string ability) { Creaturelibbattling.Generated.Creature.OverrideActiveTalent(Ptr, ability.ToPtr()).Assert(); } - public void ClearVolatileScripts() { Creaturelibbattling.Generated.Creature.ClearVolatileScripts(Ptr).Assert(); } - public void AddVolatileScript(string scriptName) { Creaturelibbattling.Generated.Creature.AddVolatileScriptByName(Ptr, scriptName.ToPtr()).Assert(); } - //TODO: Change to wrapper public void AddVolatileScript(IntPtr script) { Creaturelibbattling.Generated.Creature.AddVolatileScript(Ptr, script).Assert(); } - public void RemoveVolatileScript(string scriptName) { Creaturelibbattling.Generated.Creature.RemoveVolatileScriptByName(Ptr, scriptName.ToPtr()).Assert(); } - //TODO: Change to wrapper public void RemoveVolatileScript(IntPtr script) { Creaturelibbattling.Generated.Creature.RemoveVolatileScript(Ptr, script).Assert(); } - public bool HasVolatileScript(string scriptName) { return Creaturelibbattling.Generated.Creature.HasVolatileScript(Ptr, scriptName.ToPtr()) == 1; } - public NativePtrArray GetMoves() + public sbyte GetStatBoost(Statistic stat) { - if (_moves != null) return _moves; - var movesLength = Creaturelibbattling.Generated.Creature.GetAttacksCount(Ptr); - var movesPtr = Creaturelibbattling.Generated.Creature.GetAttacks(Ptr); - _moves = new NativePtrArray(movesPtr, (int) movesLength); - return _moves; + return Creaturelibbattling.Generated.Creature.GetStatBoost(Ptr, (Creaturelibbattling.Statistic) stat); + } + public void ChangeStatBoost(Statistic stat, sbyte amount) + { + Creaturelibbattling.Generated.Creature.ChangeStatBoost(Ptr, (Creaturelibbattling.Statistic) stat, amount); } + public uint GetBaseStat(Statistic stat) + { + return Creaturelibbattling.Generated.Creature.GetBaseStat(Ptr, (Creaturelibbattling.Statistic) stat); + } + public uint GetFlatStat(Statistic stat) + { + return Creaturelibbattling.Generated.Creature.GetFlatStat(Ptr, (Creaturelibbattling.Statistic) stat); + } + public uint GetBoostedStat(Statistic stat) + { + return Creaturelibbattling.Generated.Creature.GetBoostedStat(Ptr, (Creaturelibbattling.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); + } + + private Species _displaySpecies; + private Forme _displayForme; private Species _species; private Forme _forme; private string _nickname; - private NativePtrArray _moves; + private ReadOnlyNativePtrArray _moves; + private Nature _nature; protected override void DeletePtr() { diff --git a/PkmnLibSharp/Utilities/NativePtrArray.cs b/PkmnLibSharp/Utilities/ReadOnlyNativePtrArray.cs similarity index 68% rename from PkmnLibSharp/Utilities/NativePtrArray.cs rename to PkmnLibSharp/Utilities/ReadOnlyNativePtrArray.cs index eadf6d5..c59e1c6 100644 --- a/PkmnLibSharp/Utilities/NativePtrArray.cs +++ b/PkmnLibSharp/Utilities/ReadOnlyNativePtrArray.cs @@ -4,11 +4,11 @@ using System.Collections.Generic; namespace PkmnLibSharp.Utilities { - public class NativePtrArray : IList where T : PointerWrapper, new() + public class ReadOnlyNativePtrArray : IReadOnlyList where T : PointerWrapper, new() { private readonly IntPtr _ptr; - internal NativePtrArray(IntPtr ptr, int length) + internal ReadOnlyNativePtrArray(IntPtr ptr, int length) { _ptr = ptr; Count = length; @@ -26,17 +26,7 @@ namespace PkmnLibSharp.Utilities { return GetEnumerator(); } - - public void Add(T item) - { - throw new NotImplementedException(); - } - - public void Clear() - { - throw new NotImplementedException(); - } - + public bool Contains(T item) { foreach (var v in this) @@ -52,20 +42,9 @@ namespace PkmnLibSharp.Utilities } return false; } - - public void CopyTo(T[] array, int arrayIndex) - { - throw new NotImplementedException(); - } - - public bool Remove(T item) - { - throw new NotImplementedException(); - } - + public int Count { get; } - public bool IsReadOnly => true; public int IndexOf(T item) { for (var i = 0; i < Count; i++) @@ -78,17 +57,7 @@ namespace PkmnLibSharp.Utilities } return -1; } - - public void Insert(int index, T item) - { - throw new NotImplementedException(); - } - - public void RemoveAt(int index) - { - throw new NotImplementedException(); - } - + public T this[int index] { get @@ -96,7 +65,7 @@ namespace PkmnLibSharp.Utilities unsafe { // Where's your god now? - // (We add the offset of the index to the pointer, then dereference the pointer pointer to get the actual pointer.) + // (We add the offset of the index to the pointer, then dereference the pointer pointer to get the actual pointer to the object we want.) var p = new IntPtr(*(void**)IntPtr.Add(_ptr, index * IntPtr.Size).ToPointer()); if (PointerWrapper.TryResolvePointer(p, out T t)) return t; @@ -105,7 +74,6 @@ namespace PkmnLibSharp.Utilities return t; } } - set => throw new NotImplementedException(); } } } \ No newline at end of file diff --git a/PkmnLibSharpTests/Battling/PokemonBuilderTests.cs b/PkmnLibSharpTests/Battling/PokemonBuilderTests.cs index a00ca54..38d9420 100644 --- a/PkmnLibSharpTests/Battling/PokemonBuilderTests.cs +++ b/PkmnLibSharpTests/Battling/PokemonBuilderTests.cs @@ -44,8 +44,8 @@ namespace PkmnLibSharpTests.Battling .LearnMove("testMove", MoveLearnMethod.Unknown) .LearnMove("testMove2", MoveLearnMethod.Level) .Build(); - Assert.AreEqual("testMove", pokemon.GetMoves()[0].Move.Name); - Assert.AreEqual("testMove2", pokemon.GetMoves()[1].Move.Name); + Assert.AreEqual("testMove", pokemon.Moves[0].Move.Name); + Assert.AreEqual("testMove2", pokemon.Moves[1].Move.Name); } }