diff --git a/PkmnLibRSharp/DynamicData/DamageSource.cs b/PkmnLibRSharp/DynamicData/DamageSource.cs
new file mode 100644
index 0000000..88a0f97
--- /dev/null
+++ b/PkmnLibRSharp/DynamicData/DamageSource.cs
@@ -0,0 +1,20 @@
+namespace PkmnLibSharp.DynamicData
+{
+ public enum DamageSource : byte
+ {
+ ///
+ /// The damage is done by a move.
+ ///
+ MoveDamage = 0,
+
+ ///
+ /// The damage is done by something else.
+ ///
+ Misc = 1,
+
+ ///
+ /// The damage is done because of struggling.
+ ///
+ Struggle = 2,
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/DynamicData/LearnedMove.cs b/PkmnLibRSharp/DynamicData/LearnedMove.cs
index 0a2a44a..366b724 100644
--- a/PkmnLibRSharp/DynamicData/LearnedMove.cs
+++ b/PkmnLibRSharp/DynamicData/LearnedMove.cs
@@ -1,3 +1,4 @@
+using PkmnLibSharp.FFI;
using PkmnLibSharp.StaticData;
using PkmnLibSharp.Utils;
using Interface = PkmnLibSharp.FFI.DynamicData.LearnedMove;
@@ -12,6 +13,10 @@ namespace PkmnLibSharp.DynamicData
public MoveLearnMethod? LearnMethod { get; internal set; }
}
+ internal LearnedMove(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner)
+ {
+ }
+
public LearnedMove(MoveData moveData, MoveLearnMethod learnMethod)
{
InitializePointer(Interface.learned_move_new(moveData.Ptr, learnMethod), true);
@@ -21,17 +26,17 @@ namespace PkmnLibSharp.DynamicData
/// The immutable move information of the move.
///
public MoveData MoveData => Cache.MoveData ??= new MoveData(Interface.learned_move_move_data(Ptr), true);
-
+
///
/// The maximal power points for this move.
///
public byte MaxPP => Interface.learned_move_max_pp(Ptr);
-
+
///
/// The amount of remaining power points. If this is 0, we can not use the move anymore.
///
public byte RemainingPP => Interface.learned_move_remaining_pp(Ptr);
-
+
///
/// The way the move was learned.
///
@@ -47,7 +52,7 @@ namespace PkmnLibSharp.DynamicData
/// Set the remaining PP to the max amount of PP.
///
public void RestoreAllUses() => Interface.learned_move_restore_all_uses(Ptr);
-
+
///
/// Restore the remaining PP by a certain amount. Will prevent it from going above max PP.
///
@@ -66,6 +71,7 @@ namespace PkmnLibSharp.DynamicData
{
/// We do not know the learn method.
Unknown = 0,
+
/// The move was learned through level up.
Level = 1,
}
diff --git a/PkmnLibRSharp/DynamicData/Libraries/BattleStatCalculator.cs b/PkmnLibRSharp/DynamicData/Libraries/BattleStatCalculator.cs
new file mode 100644
index 0000000..b1b30d4
--- /dev/null
+++ b/PkmnLibRSharp/DynamicData/Libraries/BattleStatCalculator.cs
@@ -0,0 +1,22 @@
+using PkmnLibSharp.FFI;
+using PkmnLibSharp.Utils;
+using Interface = PkmnLibSharp.FFI.DynamicData.Libraries.BattleStatCalculator;
+
+namespace PkmnLibSharp.DynamicData.Libraries
+{
+ public abstract class BattleStatCalculator : ExternPointer
+ {
+ public BattleStatCalculator(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner){}
+
+ protected override object CreateCache() => new();
+
+ protected override void Destructor() => Interface.battle_stat_calculator_drop(Ptr);
+ }
+
+ public class Gen7BattleStatCalculator : BattleStatCalculator
+ {
+ public Gen7BattleStatCalculator() : base(Interface.gen_7_battle_stat_calculator_new(), true)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/DynamicData/Libraries/DamageLibrary.cs b/PkmnLibRSharp/DynamicData/Libraries/DamageLibrary.cs
new file mode 100644
index 0000000..73ea652
--- /dev/null
+++ b/PkmnLibRSharp/DynamicData/Libraries/DamageLibrary.cs
@@ -0,0 +1,25 @@
+using PkmnLibSharp.FFI;
+using PkmnLibSharp.Utils;
+using Interface = PkmnLibSharp.FFI.DynamicData.Libraries.DamageLibrary;
+
+namespace PkmnLibSharp.DynamicData.Libraries
+{
+ public abstract class DamageLibrary : ExternPointer
+ {
+ protected DamageLibrary(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner)
+ {
+ }
+
+ protected override object CreateCache() => new();
+
+ protected override void Destructor() => Interface.damage_library_drop(Ptr);
+ }
+
+ public class Gen7DamageLibrary : DamageLibrary
+ {
+ public Gen7DamageLibrary(bool hasRandomness) : base(
+ Interface.gen_7_damage_library_new((byte)(hasRandomness ? 1 : 0)), true)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/DynamicData/Libraries/DynamicLibrary.cs b/PkmnLibRSharp/DynamicData/Libraries/DynamicLibrary.cs
new file mode 100644
index 0000000..81585b1
--- /dev/null
+++ b/PkmnLibRSharp/DynamicData/Libraries/DynamicLibrary.cs
@@ -0,0 +1,25 @@
+using PkmnLibSharp.FFI;
+using PkmnLibSharp.Utils;
+using Interface = PkmnLibSharp.FFI.DynamicData.Libraries.DynamicLibrary;
+
+namespace PkmnLibSharp.DynamicData.Libraries
+{
+ public class DynamicLibrary : ExternPointer
+ {
+ public class CacheData
+ {
+ }
+
+ internal DynamicLibrary(IdentifiablePointer ptr) : base(ptr, false) {}
+
+ public DynamicLibrary(StaticData.Libraries.StaticData staticData, BattleStatCalculator statCalculator,
+ DamageLibrary damageLibrary, MiscLibrary miscLibrary, ScriptResolver scriptResolver) : base(
+ Interface.dynamic_library_new(staticData.Ptr, statCalculator.Ptr, damageLibrary.Ptr, miscLibrary.Ptr,
+ scriptResolver.Ptr), true)
+ {
+ }
+
+ protected override CacheData CreateCache() => new();
+ protected override void Destructor() => Interface.dynamic_library_drop(Ptr);
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/DynamicData/Libraries/MiscLibrary.cs b/PkmnLibRSharp/DynamicData/Libraries/MiscLibrary.cs
new file mode 100644
index 0000000..35a60b8
--- /dev/null
+++ b/PkmnLibRSharp/DynamicData/Libraries/MiscLibrary.cs
@@ -0,0 +1,24 @@
+using PkmnLibSharp.FFI;
+using PkmnLibSharp.Utils;
+using Interface = PkmnLibSharp.FFI.DynamicData.Libraries.MiscLibrary;
+
+namespace PkmnLibSharp.DynamicData.Libraries
+{
+ public abstract class MiscLibrary : ExternPointer
+ {
+ protected MiscLibrary(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner)
+ {
+ }
+
+ protected override object CreateCache() => new();
+
+ protected override void Destructor() => Interface.misc_library_drop(Ptr);
+ }
+
+ public class Gen7MiscLibrary : MiscLibrary
+ {
+ public Gen7MiscLibrary() : base(Interface.gen_7_misc_library_new(), true)
+ {
+ }
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/DynamicData/Libraries/ScriptResolver.cs b/PkmnLibRSharp/DynamicData/Libraries/ScriptResolver.cs
new file mode 100644
index 0000000..09c19c8
--- /dev/null
+++ b/PkmnLibRSharp/DynamicData/Libraries/ScriptResolver.cs
@@ -0,0 +1,30 @@
+using System;
+using PkmnLibSharp.FFI;
+using PkmnLibSharp.Utils;
+using Interface = PkmnLibSharp.FFI.DynamicData.Libraries.ScriptResolver;
+
+namespace PkmnLibSharp.DynamicData.Libraries
+{
+ public abstract class ScriptResolver : ExternPointer
+ {
+ protected ScriptResolver(IdentifiablePointer ptr) : base(ptr, true){}
+ protected ScriptResolver(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner){}
+
+ public class CacheData{}
+
+ protected override CacheData CreateCache() => new();
+
+ protected override void Destructor()
+ {
+ Interface.script_resolver_drop(Ptr);
+ }
+ }
+
+ ///
+ /// An implementation of a script resolver that pretends there are no existing scripts.
+ ///
+ public class EmptyScriptResolver : ScriptResolver
+ {
+ public EmptyScriptResolver() : base(Interface.empty_script_resolver_new()){}
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/DynamicData/Libraries/WasmScriptResolver.cs b/PkmnLibRSharp/DynamicData/Libraries/WasmScriptResolver.cs
new file mode 100644
index 0000000..011c692
--- /dev/null
+++ b/PkmnLibRSharp/DynamicData/Libraries/WasmScriptResolver.cs
@@ -0,0 +1,30 @@
+#if WASM
+using PkmnLibSharp.Utils;
+using Interface = PkmnLibSharp.FFI.DynamicData.Libraries.ScriptResolver;
+
+namespace PkmnLibSharp.DynamicData.Libraries
+{
+ public class WasmScriptResolver : ScriptResolver
+ {
+ public WasmScriptResolver() : base(Interface.webassembly_script_resolver_new(), true){}
+
+ ///
+ /// Loads a compiled WASM module into the script resolver.
+ ///
+ /// The bytes of a compiled WASM module
+ public void LoadBytes(byte[] data)
+ {
+ Interface.webassembly_script_resolver_load_wasm_from_bytes(Ptr, data.ArrayPtr(), (ulong)data.LongLength);
+ }
+
+ ///
+ /// Tells the script resolver we're done loading wasm modules, and to finalize the resolver. After this it is
+ /// ready for use.
+ ///
+ public void FinalizeResolver()
+ {
+ Interface.webassembly_script_resolver_finalize(Ptr);
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/PkmnLibRSharp/DynamicData/Pokemon.cs b/PkmnLibRSharp/DynamicData/Pokemon.cs
new file mode 100644
index 0000000..efa4f50
--- /dev/null
+++ b/PkmnLibRSharp/DynamicData/Pokemon.cs
@@ -0,0 +1,151 @@
+using PkmnLibSharp.DynamicData.Libraries;
+using PkmnLibSharp.StaticData;
+using PkmnLibSharp.Utils;
+using Form = PkmnLibSharp.StaticData.Form;
+using Interface = PkmnLibSharp.FFI.DynamicData.Pokemon;
+using Item = PkmnLibSharp.StaticData.Item;
+using Species = PkmnLibSharp.StaticData.Species;
+
+namespace PkmnLibSharp.DynamicData
+{
+ public class Pokemon : ExternPointer
+ {
+ public Pokemon(DynamicLibrary dynamicLibrary, Species species, Form form, bool hiddenAbility, byte abilityIndex,
+ LevelInt level, uint uid, Gender gender, byte coloring, string nature) : base(
+ Interface.pokemon_new(dynamicLibrary.Ptr, species.Ptr, form.Ptr, hiddenAbility.ForeignBool(), abilityIndex,
+ level, uid, gender, coloring, nature.ToPtr()), true)
+ {
+ }
+
+ ///
+ /// The library data the Pokemon uses.
+ ///
+ public DynamicLibrary Library => Cache.DynamicLibrary ??= new DynamicLibrary(Interface.pokemon_library(Ptr));
+
+ ///
+ /// The species of the Pokemon.
+ ///
+ public Species Species => new(Interface.pokemon_species(Ptr));
+
+ ///
+ /// The form of the Pokemon.
+ ///
+ public Form Form => new(Interface.pokemon_form(Ptr));
+
+ ///
+ /// The species that should be displayed to the user. This handles stuff like the Illusion ability.
+ ///
+ public Species DisplaySpecies => new(Interface.pokemon_display_species(Ptr));
+
+ ///
+ /// The form that should be displayed to the user. This handles stuff like the Illusion ability.
+ ///
+ public Form DisplayForm => new(Interface.pokemon_display_form(Ptr));
+
+ public LevelInt Level => Interface.pokemon_level(Ptr);
+ public uint Experience => Interface.pokemon_experience(Ptr);
+ public uint UniqueIdentifier => Interface.pokemon_unique_identifier(Ptr);
+ public Gender Gender => Interface.pokemon_gender(Ptr);
+ public byte Coloring => Interface.pokemon_coloring(Ptr);
+ public bool IsShiny => Coloring == 1;
+
+ public Item? HeldItem
+ {
+ get
+ {
+ var ptr = Interface.pokemon_held_item(Ptr);
+ return ptr.IsNull ? null : new Item(ptr);
+ }
+ }
+
+ public bool HasHeldItem(string name) => Interface.pokemon_has_held_item(Ptr, name.ToPtr()) == 1;
+
+ public void SetHeldItem(Item? item)
+ {
+ if (item == null)
+ RemoveHeldItem();
+ else
+ Interface.pokemon_set_held_item(Ptr, item.Ptr);
+ }
+
+ public void RemoveHeldItem() => Interface.pokemon_remove_held_item(Ptr);
+
+ public bool ConsumeHeldItem() => Interface.pokemon_consume_held_item(Ptr) == 1;
+
+ public uint CurrentHealth => Interface.pokemon_current_health(Ptr);
+ public uint MaxHealth => Interface.pokemon_max_health(Ptr);
+ public float Weight => Interface.pokemon_weight(Ptr);
+ public float Height => Interface.pokemon_height(Ptr);
+
+ public string? Nickname => Interface.pokemon_nickname(Ptr).PtrString();
+ public bool HasHiddenAbility => Interface.pokemon_real_ability_is_hidden(Ptr) == 1;
+ public byte AbilityIndex => Interface.pokemon_real_ability_index(Ptr);
+
+ public ExternValueArray Types =>
+ Cache.Types ??= new ExternValueArray(() => Interface.pokemon_types_length(Ptr),
+ arg => Interface.pokemon_types_get(Ptr, arg));
+
+ public LearnedMove? LearnedMove(ulong index)
+ {
+ var ptr = Interface.pokemon_learned_move_get(Ptr, index);
+ return ptr.IsNull ? null : new LearnedMove(ptr, false);
+ }
+
+ public StatisticSet FlatStats =>
+ Cache.FlatStats ??= new StatisticSet(Interface.pokemon_flat_stats(Ptr), false);
+
+ public StatisticSet BoostedStats =>
+ Cache.BoostedStats ??= new StatisticSet(Interface.pokemon_boosted_stats(Ptr), false);
+
+ public sbyte GetStatBoost(Statistic statistic) => Interface.pokemon_get_stat_boost(Ptr, statistic);
+ public byte GetIndividualValue(Statistic statistic) => Interface.pokemon_get_individual_value(Ptr, statistic);
+ public byte GetEffortValue(Statistic statistic) => Interface.pokemon_get_effort_value(Ptr, statistic);
+
+ public void SetIndividualValue(Statistic statistic, byte value) =>
+ Interface.pokemon_set_individual_value(Ptr, statistic, value);
+
+ public void SetEffortValue(Statistic statistic, byte value) =>
+ Interface.pokemon_set_effort_value(Ptr, statistic, value);
+
+ // TODO: Battle getter
+ public byte BattleSideIndex => Interface.pokemon_get_battle_side_index(Ptr);
+ public byte BattleIndex => Interface.pokemon_get_battle_index(Ptr);
+ public bool IsAbilityOverriden => Interface.pokemon_is_ability_overriden(Ptr) == 1;
+ public Ability ActiveAbility => new(Interface.pokemon_active_ability(Ptr));
+ public bool AllowedExperienceGain => Interface.pokemon_allowed_experience_gain(Ptr) == 1;
+ public Nature Nature => new(Interface.pokemon_nature(Ptr));
+
+ public void RecalculateFlatStats() => Interface.pokemon_recalculate_flat_stats(Ptr);
+ public void RecalculateBoostedStats() => Interface.pokemon_recalculate_boosted_stats(Ptr);
+
+ public void ChangeSpecies(Species species, Form form) =>
+ Interface.pokemon_change_species(Ptr, species.Ptr, form.Ptr);
+
+ public void ChangeForm(Form form) => Interface.pokemon_change_form(Ptr, form.Ptr);
+
+ public bool IsUsable => Interface.pokemon_is_usable(Ptr) == 1;
+ public bool IsFainted => Interface.pokemon_is_fainted(Ptr) == 1;
+ public bool IsOnBattleField => Interface.pokemon_is_on_battlefield(Ptr) == 1;
+
+ public void Damage(uint amount, DamageSource source) => Interface.pokemon_damage(Ptr, amount, source);
+
+ public bool Heal(uint amount, bool allowRevive) =>
+ Interface.pokemon_heal(Ptr, amount, allowRevive.ForeignBool()) == 1;
+
+ public void LearnMove(string moveName, MoveLearnMethod learnMethod) =>
+ Interface.pokemon_learn_move(Ptr, moveName.ToPtr(), learnMethod);
+
+ public void ClearStatus() => Interface.pokemon_clear_status(Ptr);
+
+ public class CacheData
+ {
+ public DynamicLibrary? DynamicLibrary { get; set; }
+ public ExternValueArray? Types { get; set; }
+ public StatisticSet? FlatStats { get; set; }
+ public StatisticSet? BoostedStats { get; set; }
+ }
+
+ protected override CacheData CreateCache() => new();
+ protected override void Destructor() => Interface.pokemon_drop(Ptr);
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/FFI/DynamicData/Libraries/BattleStatCalculator.cs b/PkmnLibRSharp/FFI/DynamicData/Libraries/BattleStatCalculator.cs
new file mode 100644
index 0000000..0e9ae6e
--- /dev/null
+++ b/PkmnLibRSharp/FFI/DynamicData/Libraries/BattleStatCalculator.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Runtime.InteropServices;
+using PkmnLibSharp.DynamicData;
+
+namespace PkmnLibSharp.FFI.DynamicData.Libraries
+{
+ internal static class BattleStatCalculator
+ {
+ ///
+ /// Creates a new Gen 7 battle stat calculator
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer gen_7_battle_stat_calculator_new();
+
+ ///
+ /// Creates a new Gen 7 battle stat calculator
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void battle_stat_calculator_drop(IntPtr ptr);
+
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/FFI/DynamicData/Libraries/DamageLibrary.cs b/PkmnLibRSharp/FFI/DynamicData/Libraries/DamageLibrary.cs
new file mode 100644
index 0000000..900455e
--- /dev/null
+++ b/PkmnLibRSharp/FFI/DynamicData/Libraries/DamageLibrary.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace PkmnLibSharp.FFI.DynamicData.Libraries
+{
+ internal static class DamageLibrary
+ {
+ ///
+ /// Creates a new generation 7 damage library.
+ ///
+ /// whether or not a random damage modifier (0.85x - 1.00x) is applied to the
+ /// calculated damage. 0 for not, 1 for true
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer gen_7_damage_library_new(byte hasRandomness);
+
+ ///
+ /// Drops a DamageLibrary.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void damage_library_drop(IntPtr ptr);
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/FFI/DynamicData/Libraries/DynamicLibrary.cs b/PkmnLibRSharp/FFI/DynamicData/Libraries/DynamicLibrary.cs
new file mode 100644
index 0000000..c1783c9
--- /dev/null
+++ b/PkmnLibRSharp/FFI/DynamicData/Libraries/DynamicLibrary.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace PkmnLibSharp.FFI.DynamicData.Libraries
+{
+ internal static class DynamicLibrary
+ {
+ ///
+ /// Instantiates a new DynamicLibrary with given parameters.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer dynamic_library_new(IntPtr staticData, IntPtr statCalculator,
+ IntPtr damageLibrary, IntPtr miscLibrary, IntPtr scriptResolver);
+
+ ///
+ /// Drops a dynamic library.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void dynamic_library_drop(IntPtr dynamicLibrary);
+
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/FFI/DynamicData/Libraries/MiscLibrary.cs b/PkmnLibRSharp/FFI/DynamicData/Libraries/MiscLibrary.cs
new file mode 100644
index 0000000..9448093
--- /dev/null
+++ b/PkmnLibRSharp/FFI/DynamicData/Libraries/MiscLibrary.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace PkmnLibSharp.FFI.DynamicData.Libraries
+{
+ internal static class MiscLibrary
+ {
+ ///
+ /// Instantiates a new MiscLibrary.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer gen_7_misc_library_new();
+
+ ///
+ /// Drops a MiscLibrary.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void misc_library_drop(IntPtr ptr);
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/FFI/DynamicData/Libraries/ScriptResolver.cs b/PkmnLibRSharp/FFI/DynamicData/Libraries/ScriptResolver.cs
new file mode 100644
index 0000000..830eab8
--- /dev/null
+++ b/PkmnLibRSharp/FFI/DynamicData/Libraries/ScriptResolver.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace PkmnLibSharp.FFI.DynamicData.Libraries
+{
+ internal static class ScriptResolver
+ {
+ ///
+ /// Instantiates a basic empty script resolver, that always returns None.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer empty_script_resolver_new();
+
+ ///
+ /// Drops a script resolver.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void script_resolver_drop(IntPtr ptr);
+
+ // WASM is a feature flag in the crate, and can be disabled. If disabled, these entry points do not exist. In
+ // this case it's recommended to remove the WASM compile flag from the csproj as well.
+#if WASM
+ ///
+ /// Instantiates a new WebAssemblyScriptResolver.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer webassembly_script_resolver_new();
+
+ ///
+ /// Load a compiled WASM module.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void webassembly_script_resolver_load_wasm_from_bytes(IntPtr resolver, IntPtr byteArray,
+ ulong arrayLength);
+
+ ///
+ /// Tells the script resolver we're done loading wasm modules, and to finalize the resolver.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void webassembly_script_resolver_finalize(IntPtr resolver);
+#endif
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/FFI/DynamicData/Pokemon.cs b/PkmnLibRSharp/FFI/DynamicData/Pokemon.cs
new file mode 100644
index 0000000..9bdf24c
--- /dev/null
+++ b/PkmnLibRSharp/FFI/DynamicData/Pokemon.cs
@@ -0,0 +1,306 @@
+using System;
+using System.Runtime.InteropServices;
+using PkmnLibSharp.DynamicData;
+using PkmnLibSharp.FFI.StaticData;
+using PkmnLibSharp.StaticData;
+
+namespace PkmnLibSharp.FFI.DynamicData
+{
+ internal static class Pokemon
+ {
+ ///
+ /// Instantiates a new Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_new(IntPtr dynamicLibrary, IntPtr species, IntPtr form,
+ byte hiddenAbility, byte abilityIndex, LevelInt level, uint uniqueIdentifier, Gender gender, byte coloring,
+ IntPtr natureName);
+
+ ///
+ /// Drops an Arc reference held by the FFI.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void pokemon_drop(IntPtr pokemon);
+
+ ///
+ /// The library data of the Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_library(IntPtr pokemon);
+
+ ///
+ /// The species of the Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_species(IntPtr pokemon);
+
+ ///
+ /// The form of the Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_form(IntPtr pokemon);
+
+ ///
+ /// The species that should be displayed to the user. This handles stuff like the Illusion ability.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_display_species(IntPtr pokemon);
+
+ ///
+ /// The form that should be displayed to the user. This handles stuff like the Illusion ability.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_display_form(IntPtr pokemon);
+
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern LevelInt pokemon_level(IntPtr pokemon);
+
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern uint pokemon_experience(IntPtr pokemon);
+
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern uint pokemon_unique_identifier(IntPtr pokemon);
+
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern Gender pokemon_gender(IntPtr pokemon);
+
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_coloring(IntPtr pokemon);
+
+ ///
+ /// Gets the held item of a Pokemon
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_held_item(IntPtr pokemon);
+
+ ///
+ /// Checks whether the Pokemon is holding a specific item.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_has_held_item(IntPtr pokemon, IntPtr itemName);
+
+ ///
+ /// Changes the held item of the Pokemon. Returns the previously held item.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_set_held_item(IntPtr pokemon, IntPtr item);
+
+ ///
+ /// Removes the held item from the Pokemon. Returns the previously held item.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_remove_held_item(IntPtr pokemon);
+
+ ///
+ /// Makes the Pokemon uses its held item.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_consume_held_item(IntPtr pokemon);
+
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern uint pokemon_current_health(IntPtr pokemon);
+
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern uint pokemon_max_health(IntPtr pokemon);
+
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern float pokemon_weight(IntPtr pokemon);
+
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern float pokemon_height(IntPtr pokemon);
+
+ ///
+ /// An optional nickname of the Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IntPtr pokemon_nickname(IntPtr pokemon);
+
+ ///
+ /// Whether the actual ability on the form is a hidden ability.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_real_ability_is_hidden(IntPtr pokemon);
+
+ ///
+ /// The index of the actual ability on the form.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_real_ability_index(IntPtr pokemon);
+
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern ulong pokemon_types_length(IntPtr pokemon);
+
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern TypeIdentifier pokemon_types_get(IntPtr pokemon, ulong index);
+
+ ///
+ /// Gets a learned move of the Pokemon. Index should generally be below [`MAX_MOVES`], you will get
+ /// a null pointer otherwise.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_learned_move_get(IntPtr pokemon, ulong index);
+
+ ///
+ /// The stats of the Pokemon when disregarding any stat boosts.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_flat_stats(IntPtr pokemon);
+
+ ///
+ /// The stats of the Pokemon including the stat boosts.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_boosted_stats(IntPtr pokemon);
+
+ ///
+ /// Get the stat boosts for a specific stat.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern sbyte pokemon_get_stat_boost(IntPtr pokemon, Statistic statistic);
+
+ ///
+ /// Change a boosted stat by a certain amount.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern sbyte pokemon_change_stat_boost(IntPtr pokemon, Statistic statistic, sbyte diffAmount,
+ byte selfInflicted);
+
+ ///
+ /// Gets a individual value of the Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_get_individual_value(IntPtr pokemon, Statistic statistic);
+
+ ///
+ /// Modifies a individual value of the Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void pokemon_set_individual_value(IntPtr pokemon, Statistic statistic, byte value);
+
+ ///
+ /// Gets a effort value of the Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_get_effort_value(IntPtr pokemon, Statistic statistic);
+
+ ///
+ /// Modifies a effort value of the Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void pokemon_set_effort_value(IntPtr pokemon, Statistic statistic, byte value);
+
+ ///
+ /// Gets the data for the battle the Pokemon is currently in. If the Pokemon is not in a battle, this
+ /// returns null.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_get_battle(IntPtr pokemon);
+
+ ///
+ /// Get the index of the side of the battle the Pokemon is in. If the Pokemon
+ /// is not on the battlefield, this always returns 0.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_get_battle_side_index(IntPtr pokemon);
+
+ ///
+ /// Get the index of the slot on the side of the battle the Pokemon is in. If the Pokemon
+ /// is not on the battlefield, this always returns 0.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_get_battle_index(IntPtr pokemon);
+
+ ///
+ /// Returns whether something overrides the ability.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_is_ability_overriden(IntPtr pokemon);
+
+ ///
+ /// Returns the currently active ability.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_active_ability(IntPtr pokemon);
+
+ ///
+ /// Whether or not the Pokemon is allowed to gain experience.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_allowed_experience_gain(IntPtr pokemon);
+
+ ///
+ /// The nature of the Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern IdentifiablePointer pokemon_nature(IntPtr pokemon);
+
+ ///
+ /// Calculates the flat stats on the Pokemon. This should be called when for example the base
+ /// stats, level, nature, IV, or EV changes. This has a side effect of recalculating the boosted
+ /// stats, as those depend on the flat stats.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void pokemon_recalculate_flat_stats(IntPtr pokemon);
+
+ ///
+ /// Calculates the boosted stats on the Pokemon. This should be called when a stat boost changes.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void pokemon_recalculate_boosted_stats(IntPtr pokemon);
+
+ ///
+ /// Change the species of the Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void pokemon_change_species(IntPtr pokemon, IntPtr species, IntPtr form);
+
+ ///
+ /// Change the form of the Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void pokemon_change_form(IntPtr pokemon, IntPtr form);
+
+ ///
+ /// Whether or not the Pokemon is usable in a battle.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_is_usable(IntPtr pokemon);
+
+ ///
+ /// Returns whether the Pokemon is fainted.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_is_fainted(IntPtr pokemon);
+
+ ///
+ /// Whether or not the Pokemon is on the battlefield.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_is_on_battlefield(IntPtr pokemon);
+
+ ///
+ /// Damages the Pokemon by a certain amount of damage, from a damage source.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void pokemon_damage(IntPtr pokemon, uint damage, DamageSource damageSource);
+
+ ///
+ /// Heals the Pokemon by a specific amount. Unless allowRevive is set to 1, this will not
+ /// heal if the Pokemon has 0 health. If the amount healed is 0, this will return false.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern byte pokemon_heal(IntPtr pokemon, uint damage, byte allowRevive);
+
+ ///
+ /// Learn a move.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void pokemon_learn_move(IntPtr pokemon, IntPtr moveName, MoveLearnMethod learnMethod);
+
+ ///
+ /// Removes the current non-volatile status from the Pokemon.
+ ///
+ [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+ internal static extern void pokemon_clear_status(IntPtr pokemon);
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/FFI/IdentifiablePointer.cs b/PkmnLibRSharp/FFI/IdentifiablePointer.cs
index 416067a..bfe2182 100644
--- a/PkmnLibRSharp/FFI/IdentifiablePointer.cs
+++ b/PkmnLibRSharp/FFI/IdentifiablePointer.cs
@@ -8,5 +8,7 @@ namespace PkmnLibSharp.FFI
{
public readonly IntPtr Ptr;
public readonly nuint Identifier;
+
+ public bool IsNull => Ptr == IntPtr.Zero;
}
}
\ No newline at end of file
diff --git a/PkmnLibRSharp/PkmnLibRSharp.csproj b/PkmnLibRSharp/PkmnLibRSharp.csproj
index ecd94bd..7634494 100644
--- a/PkmnLibRSharp/PkmnLibRSharp.csproj
+++ b/PkmnLibRSharp/PkmnLibRSharp.csproj
@@ -11,11 +11,14 @@
6
true
;NU1605;CA2000
+ IDISP012
true
+ TRACE;WASM;
true
+ TRACE;WASM;
diff --git a/PkmnLibRSharp/StaticData/Ability.cs b/PkmnLibRSharp/StaticData/Ability.cs
index cf46bf4..918e795 100644
--- a/PkmnLibRSharp/StaticData/Ability.cs
+++ b/PkmnLibRSharp/StaticData/Ability.cs
@@ -28,7 +28,7 @@ namespace PkmnLibSharp.StaticData
true);
}
- internal Ability(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner)
+ internal Ability(IdentifiablePointer ptr) : base(ptr, true)
{
}
diff --git a/PkmnLibRSharp/StaticData/Form.cs b/PkmnLibRSharp/StaticData/Form.cs
index c6efa6b..f6cc9e4 100644
--- a/PkmnLibRSharp/StaticData/Form.cs
+++ b/PkmnLibRSharp/StaticData/Form.cs
@@ -23,7 +23,7 @@ namespace PkmnLibSharp.StaticData
public LearnableMoves? LearnableMoves { get; internal set; }
}
- internal Form(IdentifiablePointer formPtr, bool isOwner) : base(formPtr, isOwner)
+ internal Form(IdentifiablePointer formPtr) : base(formPtr, true)
{
}
diff --git a/PkmnLibRSharp/StaticData/Gender.cs b/PkmnLibRSharp/StaticData/Gender.cs
new file mode 100644
index 0000000..1efafa4
--- /dev/null
+++ b/PkmnLibRSharp/StaticData/Gender.cs
@@ -0,0 +1,20 @@
+namespace PkmnLibSharp.StaticData
+{
+ public enum Gender : byte
+ {
+ ///
+ /// The Pokemon has no gender.
+ ///
+ Genderless = 0,
+
+ ///
+ /// The Pokemon is male.
+ ///
+ Male = 1,
+
+ ///
+ /// The Pokemon is female.
+ ///
+ Female = 2,
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/StaticData/Item.cs b/PkmnLibRSharp/StaticData/Item.cs
index 6c99432..629c81d 100644
--- a/PkmnLibRSharp/StaticData/Item.cs
+++ b/PkmnLibRSharp/StaticData/Item.cs
@@ -104,7 +104,7 @@ namespace PkmnLibSharp.StaticData
InitializePointer(ptr, true);
}
- internal Item(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner)
+ internal Item(IdentifiablePointer ptr) : base(ptr, true)
{
}
diff --git a/PkmnLibRSharp/StaticData/Libraries/AbilityLibrary.cs b/PkmnLibRSharp/StaticData/Libraries/AbilityLibrary.cs
index 58aa733..5fcf0a4 100644
--- a/PkmnLibRSharp/StaticData/Libraries/AbilityLibrary.cs
+++ b/PkmnLibRSharp/StaticData/Libraries/AbilityLibrary.cs
@@ -25,7 +25,7 @@ namespace PkmnLibSharp.StaticData.Libraries
protected override Ability? GetValueByKey(string key)
{
var ptr = Interface.ability_library_get(Ptr, key.ToPtr());
- return ptr.Ptr == IntPtr.Zero ? null : new Ability(ptr, false);
+ return ptr.Ptr == IntPtr.Zero ? null : new Ability(ptr);
}
public override string? GetKeyByIndex(ulong index) =>
diff --git a/PkmnLibRSharp/StaticData/Libraries/ItemLibrary.cs b/PkmnLibRSharp/StaticData/Libraries/ItemLibrary.cs
index 45c9037..a142123 100644
--- a/PkmnLibRSharp/StaticData/Libraries/ItemLibrary.cs
+++ b/PkmnLibRSharp/StaticData/Libraries/ItemLibrary.cs
@@ -25,7 +25,7 @@ namespace PkmnLibSharp.StaticData.Libraries
protected override Item? GetValueByKey(string key)
{
var ptr = Interface.item_library_get(Ptr, key.ToPtr());
- return ptr.Ptr == IntPtr.Zero ? null : new Item(ptr, false);
+ return ptr.Ptr == IntPtr.Zero ? null : new Item(ptr);
}
public override string? GetKeyByIndex(ulong index) =>
diff --git a/PkmnLibRSharp/StaticData/Libraries/SpeciesLibrary.cs b/PkmnLibRSharp/StaticData/Libraries/SpeciesLibrary.cs
index 928cc2d..d322261 100644
--- a/PkmnLibRSharp/StaticData/Libraries/SpeciesLibrary.cs
+++ b/PkmnLibRSharp/StaticData/Libraries/SpeciesLibrary.cs
@@ -25,7 +25,7 @@ namespace PkmnLibSharp.StaticData.Libraries
protected override Species? GetValueByKey(string key)
{
var ptr = Interface.species_library_get(Ptr, key.ToPtr());
- return ptr.Ptr == IntPtr.Zero ? null : new Species(ptr, false);
+ return ptr.Ptr == IntPtr.Zero ? null : new Species(ptr);
}
public override string? GetKeyByIndex(ulong index) =>
diff --git a/PkmnLibRSharp/StaticData/Species.cs b/PkmnLibRSharp/StaticData/Species.cs
index 904fe37..8c5f7ae 100644
--- a/PkmnLibRSharp/StaticData/Species.cs
+++ b/PkmnLibRSharp/StaticData/Species.cs
@@ -19,7 +19,7 @@ namespace PkmnLibSharp.StaticData
public Dictionary Forms { get; } = new();
}
- internal Species(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner)
+ internal Species(IdentifiablePointer ptr) : base(ptr, true)
{
}
@@ -48,7 +48,8 @@ namespace PkmnLibSharp.StaticData
form = null;
return false;
}
- form = new Form(formPtr, false);
+
+ form = new Form(formPtr);
Cache.Forms.Add(formName, form);
return true;
}
@@ -67,7 +68,7 @@ namespace PkmnLibSharp.StaticData
form.Value.Invalidate();
}
}
-
+
~Species()
{
Dispose();
diff --git a/PkmnLibRSharp/StaticData/StatisticSet.cs b/PkmnLibRSharp/StaticData/StatisticSet.cs
index 8c88210..d726915 100644
--- a/PkmnLibRSharp/StaticData/StatisticSet.cs
+++ b/PkmnLibRSharp/StaticData/StatisticSet.cs
@@ -1,5 +1,6 @@
using System;
using JetBrains.Annotations;
+using PkmnLibSharp.FFI;
using PkmnLibSharp.Utils;
using Interface = PkmnLibSharp.FFI.StaticData.StatisticSet;
@@ -7,6 +8,9 @@ namespace PkmnLibSharp.StaticData
{
public class StatisticSet : ExternPointer where T : struct, IConvertible
{
+ internal StatisticSet(IdentifiablePointer ptr, bool isOwner) : base(ptr, isOwner)
+ {
+ }
public StatisticSet(T hp, T attack, T defense, T specialAttack, T specialDefense, T speed)
{
@@ -115,7 +119,7 @@ namespace PkmnLibSharp.StaticData
else if (typeof(T) == typeof(short)) Interface.statistic_set_i16_drop(Ptr);
else if (typeof(T) == typeof(int)) Interface.statistic_set_i32_drop(Ptr);
}
-
+
~StatisticSet()
{
Dispose();
diff --git a/PkmnLibRSharp/Utils/ExternValueArray.cs b/PkmnLibRSharp/Utils/ExternValueArray.cs
new file mode 100644
index 0000000..d64a0a8
--- /dev/null
+++ b/PkmnLibRSharp/Utils/ExternValueArray.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace PkmnLibSharp.Utils
+{
+ public class ExternValueArray : IReadOnlyList where T : struct
+ {
+ private readonly Func _getLength;
+ private readonly Func _getItem;
+
+ public ExternValueArray(Func getSize, Func getItem)
+ {
+ _getLength = getSize;
+ _getItem = getItem;
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ for (var i = 0; i < Count; i++)
+ {
+ yield return this[i];
+ }
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public int Count => (int)_getLength();
+
+ public T this[int index] => _getItem((ulong)index);
+ }
+}
\ No newline at end of file
diff --git a/PkmnLibRSharp/libpkmn_lib.so b/PkmnLibRSharp/libpkmn_lib.so
index 1454a0f..8361eca 100755
--- a/PkmnLibRSharp/libpkmn_lib.so
+++ b/PkmnLibRSharp/libpkmn_lib.so
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:ac83a8f9c15b0073673967d1a9be39bc8df15d9ae235458237e9cd5c1c956a2b
-size 118173856
+oid sha256:39cf9d7a787d19ba082f2a6fd036ef384292c76f0018077951e504e0f2738d6a
+size 118266520