diff --git a/PkmnLibRSharp/DynamicData/DamageSource.cs b/PkmnLibRSharp/DynamicData/DamageSource.cs index 88a0f97..e532d45 100644 --- a/PkmnLibRSharp/DynamicData/DamageSource.cs +++ b/PkmnLibRSharp/DynamicData/DamageSource.cs @@ -1,5 +1,8 @@ namespace PkmnLibSharp.DynamicData { + /// + /// A source of damage. + /// public enum DamageSource : byte { /// diff --git a/PkmnLibRSharp/DynamicData/LearnedMove.cs b/PkmnLibRSharp/DynamicData/LearnedMove.cs index ce9e852..8cc7af1 100644 --- a/PkmnLibRSharp/DynamicData/LearnedMove.cs +++ b/PkmnLibRSharp/DynamicData/LearnedMove.cs @@ -4,10 +4,17 @@ using Interface = PkmnLibSharp.FFI.DynamicData.LearnedMove; namespace PkmnLibSharp.DynamicData { + /// + /// A learned move is the data attached to a Pokemon for a move it has learned. It has information + /// such as the remaining amount of users, how it has been learned, etc. + /// public class LearnedMove : HandleType { private LearnedMove(FFIHandle handle) : base(handle){} + /// + /// Creates a new learned move. + /// public static LearnedMove Create(MoveData moveData, MoveLearnMethod learnMethod) { var handle = Interface.learned_move_new(moveData.Handle, learnMethod); @@ -53,6 +60,9 @@ namespace PkmnLibSharp.DynamicData public void RestoreUses(byte amount) => Interface.learned_move_restore_uses(Handle, amount); } + /// + /// The different ways a move can be learned. + /// public enum MoveLearnMethod : byte { /// We do not know the learn method. diff --git a/PkmnLibRSharp/DynamicData/Libraries/BattleStatCalculator.cs b/PkmnLibRSharp/DynamicData/Libraries/BattleStatCalculator.cs index 9964f4b..0c5a737 100644 --- a/PkmnLibRSharp/DynamicData/Libraries/BattleStatCalculator.cs +++ b/PkmnLibRSharp/DynamicData/Libraries/BattleStatCalculator.cs @@ -4,19 +4,30 @@ using Interface = PkmnLibSharp.FFI.DynamicData.Libraries.BattleStatCalculator; namespace PkmnLibSharp.DynamicData.Libraries { + /// + /// A battle stat calculator is used to calculate stats for a Pokemon. + /// public abstract class BattleStatCalculator : HandleType { + /// protected BattleStatCalculator(FFIHandle handle) : base(handle){} } + /// + /// A basic implementation of the Gen 7 stat calculator. + /// public class Gen7BattleStatCalculator : BattleStatCalculator { + /// protected Gen7BattleStatCalculator(FFIHandle handle) : base(handle){} + /// + /// Creates a new Gen 7 battle stat calculator + /// public static Gen7BattleStatCalculator Create() { var handle = Interface.gen_7_battle_stat_calculator_new(); - return Resolver.Instance.ResolveGen7BattleStatCalculator(handle.Resolve()); + return (Gen7BattleStatCalculator)Resolver.Instance.ResolveBattleStatCalculator(handle.Resolve()); } } } \ No newline at end of file diff --git a/PkmnLibRSharp/DynamicData/Libraries/DamageLibrary.cs b/PkmnLibRSharp/DynamicData/Libraries/DamageLibrary.cs index db817d9..2403d1d 100644 --- a/PkmnLibRSharp/DynamicData/Libraries/DamageLibrary.cs +++ b/PkmnLibRSharp/DynamicData/Libraries/DamageLibrary.cs @@ -4,23 +4,38 @@ using Interface = PkmnLibSharp.FFI.DynamicData.Libraries.DamageLibrary; namespace PkmnLibSharp.DynamicData.Libraries { + /// + /// A damage library holds the functions related to the calculation of damage. + /// public abstract class DamageLibrary : HandleType { + /// protected DamageLibrary(FFIHandle ptr) : base(ptr) { } } + /// + /// The implementation of a Damage Library for generation 7. + /// public class Gen7DamageLibrary : DamageLibrary { + /// public Gen7DamageLibrary(FFIHandle ptr) : base(ptr) { } + /// + /// Creates a new generation 7 damage library + /// + /// + /// Whether or not a random damage modifier (0.85x - 1.00x) is applied to the calculated damage + /// + /// public static Gen7DamageLibrary Create(bool hasRandomness) { var handle = Interface.gen_7_damage_library_new((byte)(hasRandomness ? 1 : 0)); - return Resolver.Instance.ResolveGen7DamageLibrary(handle.Resolve()); + return (Gen7DamageLibrary)Resolver.Instance.ResolveDamageLibrary(handle.Resolve()); } } } \ No newline at end of file diff --git a/PkmnLibRSharp/DynamicData/Libraries/DynamicLibrary.cs b/PkmnLibRSharp/DynamicData/Libraries/DynamicLibrary.cs index 3900d72..55725ab 100644 --- a/PkmnLibRSharp/DynamicData/Libraries/DynamicLibrary.cs +++ b/PkmnLibRSharp/DynamicData/Libraries/DynamicLibrary.cs @@ -4,12 +4,20 @@ using Interface = PkmnLibSharp.FFI.DynamicData.Libraries.DynamicLibrary; namespace PkmnLibSharp.DynamicData.Libraries { + /// + /// The dynamic library stores a static data library, as well as holding different libraries and + /// calculators that might be customized between different generations and implementations. + /// public class DynamicLibrary : HandleType { + /// protected DynamicLibrary(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new DynamicLibrary with given libraries. + /// public static DynamicLibrary Create(StaticData.Libraries.StaticData staticData, BattleStatCalculator statCalculator, DamageLibrary damageLibrary, MiscLibrary miscLibrary, ScriptResolver scriptResolver) @@ -21,6 +29,9 @@ namespace PkmnLibSharp.DynamicData.Libraries return lib; } + /// + /// The static data is the immutable storage data for this library. + /// public StaticData.Libraries.StaticData StaticData { get; private set; } = null!; } } \ No newline at end of file diff --git a/PkmnLibRSharp/DynamicData/Libraries/MiscLibrary.cs b/PkmnLibRSharp/DynamicData/Libraries/MiscLibrary.cs index b67a456..4002978 100644 --- a/PkmnLibRSharp/DynamicData/Libraries/MiscLibrary.cs +++ b/PkmnLibRSharp/DynamicData/Libraries/MiscLibrary.cs @@ -4,23 +4,34 @@ using Interface = PkmnLibSharp.FFI.DynamicData.Libraries.MiscLibrary; namespace PkmnLibSharp.DynamicData.Libraries { + /// + /// The misc library holds several misc functions required for the battle to run. + /// public abstract class MiscLibrary : HandleType { + /// protected MiscLibrary(FFIHandle handle) : base(handle) { } } + /// + /// A gen 7 implementation for the MiscLibrary. + /// public class Gen7MiscLibrary : MiscLibrary { + /// protected Gen7MiscLibrary(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new MiscLibrary. + /// public static Gen7MiscLibrary Create() { var handle = Interface.gen_7_misc_library_new(); - return Resolver.Instance.ResolveGen7MiscLibrary(handle.Resolve()); + return (Gen7MiscLibrary)Resolver.Instance.ResolveMiscLibrary(handle.Resolve()); } } } \ No newline at end of file diff --git a/PkmnLibRSharp/DynamicData/Libraries/ScriptResolver.cs b/PkmnLibRSharp/DynamicData/Libraries/ScriptResolver.cs index bf8f17a..3b31313 100644 --- a/PkmnLibRSharp/DynamicData/Libraries/ScriptResolver.cs +++ b/PkmnLibRSharp/DynamicData/Libraries/ScriptResolver.cs @@ -5,8 +5,14 @@ using Interface = PkmnLibSharp.FFI.DynamicData.Libraries.ScriptResolver; namespace PkmnLibSharp.DynamicData.Libraries { + /// + /// A script resolver deals with the resolving of scripts. These scripts are non-hardcoded + /// implementations of different effects in Pokemon. This allows for things such as generational + /// differences, and custom implementations. + /// public abstract class ScriptResolver : HandleType { + /// protected ScriptResolver(FFIHandle handle) : base(handle){} } @@ -15,8 +21,12 @@ namespace PkmnLibSharp.DynamicData.Libraries /// public class EmptyScriptResolver : ScriptResolver { + /// protected EmptyScriptResolver(FFIHandle handle) : base(handle){} + /// + /// Creates a new empty script resolver. + /// public static EmptyScriptResolver Create() { var handle = Interface.empty_script_resolver_new(); diff --git a/PkmnLibRSharp/DynamicData/Libraries/WasmScriptResolver.cs b/PkmnLibRSharp/DynamicData/Libraries/WasmScriptResolver.cs index a350d7c..9dc3ea2 100644 --- a/PkmnLibRSharp/DynamicData/Libraries/WasmScriptResolver.cs +++ b/PkmnLibRSharp/DynamicData/Libraries/WasmScriptResolver.cs @@ -4,16 +4,23 @@ using Interface = PkmnLibSharp.FFI.DynamicData.Libraries.ScriptResolver; namespace PkmnLibSharp.DynamicData.Libraries { + /// + /// A WebAssembly script resolver implements the dynamic scripts functionality with WebAssembly. + /// public class WasmScriptResolver : ScriptResolver { + /// protected WasmScriptResolver(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new WebAssemblyScriptResolver. + /// public static WasmScriptResolver Create() { var handle = Interface.webassembly_script_resolver_new(); - return Resolver.Instance.ResolveWasmScriptResolver(handle.Resolve()); + return (WasmScriptResolver)Resolver.Instance.ResolveScriptResolver(handle.Resolve()); } /// diff --git a/PkmnLibRSharp/DynamicData/Pokemon.cs b/PkmnLibRSharp/DynamicData/Pokemon.cs index da97dca..df367f0 100644 --- a/PkmnLibRSharp/DynamicData/Pokemon.cs +++ b/PkmnLibRSharp/DynamicData/Pokemon.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using PkmnLibSharp.DynamicData.Libraries; using PkmnLibSharp.StaticData; using PkmnLibSharp.Utils; @@ -8,20 +9,40 @@ using Species = PkmnLibSharp.StaticData.Species; namespace PkmnLibSharp.DynamicData { + /// + /// The data of a Pokemon. + /// public class Pokemon : HandleType { - protected Pokemon(FFIHandle handle) : base(handle){} - - public static Pokemon Create(DynamicLibrary dynamicLibrary, Species species, Form form, bool hiddenAbility, byte abilityIndex, - LevelInt level, uint uid, Gender gender, byte coloring, string nature) + /// + protected Pokemon(FFIHandle handle) : base(handle) { - var handle = Interface.pokemon_new(dynamicLibrary.Handle, species.Handle, form.Handle, hiddenAbility.ForeignBool(), - abilityIndex, level, uid, gender, coloring, nature.ToPtr()) + } + + /// + /// Instantiates a new Pokemon. + /// + /// The library the Pokemon should fetch its data from + /// The species of the Pokemon + /// The form the Pokemon should be + /// Whether or not the ability the Pokemon has is hidden + /// The index of the ability + /// The level of the Pokemon + /// The unique identifier of the Pokemon + /// The gender of the Pokemon + /// The coloring of the Pokemon. This should be 0 for regular, 1 for shiny, and any other value for custom implementations + /// The nature of the Pokemon + public static Pokemon Create(DynamicLibrary dynamicLibrary, Species species, Form form, bool hiddenAbility, + byte abilityIndex, LevelInt level, uint uid, Gender gender, byte coloring, string nature) + { + var handle = Interface.pokemon_new(dynamicLibrary.Handle, species.Handle, form.Handle, + hiddenAbility.ForeignBool(), abilityIndex, level, uid, gender, coloring, nature.ToPtr()) .Result(); return Resolver.Instance.ResolvePokemon(handle.Resolve()); } private DynamicLibrary? _library; + /// /// The library data the Pokemon uses. /// @@ -49,13 +70,43 @@ namespace PkmnLibSharp.DynamicData /// public Form DisplayForm => Resolver.Instance.ResolveForm(Interface.pokemon_display_form(Handle).Resolve()); + /// + /// The level of the Pokemon. + /// See also + /// public LevelInt Level => Interface.pokemon_level(Handle); + + /// + /// The experience of the Pokemon. + /// See also + /// public uint Experience => Interface.pokemon_experience(Handle); - public uint UniqueIdentifier => Interface.pokemon_unique_identifier(Handle); + + /// + /// The personality value of the Pokemon. + /// See also + /// + public uint PersonalityValue => Interface.pokemon_personality_value(Handle); + + /// + /// The gender of the Pokemon. + /// public Gender Gender => Interface.pokemon_gender(Handle); + + /// + /// The coloring of the Pokemon. If this is 1, the Pokemon is shiny, otherwise it is not. This can + /// also be used for other custom coloring schemes. + /// public byte Coloring => Interface.pokemon_coloring(Handle); + + /// + /// Whether or not the Pokemon is shiny. + /// public bool IsShiny => Coloring == 1; + /// + /// Gets the held item of a Pokemon. If the Pokemon does not have a held item, this will return null. + /// public Item? HeldItem { get @@ -65,91 +116,241 @@ namespace PkmnLibSharp.DynamicData } } + /// + /// Checks whether the Pokemon is holding an item with a specific name. + /// + /// The name of the item to check for public bool HasHeldItem(string name) => Interface.pokemon_has_held_item(Handle, name.ToPtr()) == 1; - public void SetHeldItem(Item? item) + /// + /// Changes the held item of the Pokemon. Returns the previously held item. + /// + /// The new item to use. If this is given null, it will call + public Item? SetHeldItem(Item? item) { if (item == null) - RemoveHeldItem(); - else - Interface.pokemon_set_held_item(Handle, item.Handle); + { + return RemoveHeldItem(); + } + + var handle = Interface.pokemon_set_held_item(Handle, item.Handle); + return handle.IsNull ? null : Resolver.Instance.ResolveItem(handle.Resolve()); } - public void RemoveHeldItem() => Interface.pokemon_remove_held_item(Handle); + /// + /// Removes the held item from the Pokemon. Returns the previously held item. + /// + /// The previous held item. If no item was previously held, this returns null + public Item? RemoveHeldItem() + { + var handle = Interface.pokemon_remove_held_item(Handle); + return handle.IsNull ? null : Resolver.Instance.ResolveItem(handle.Resolve()); + } + /// + /// Makes the Pokemon uses its held item. + /// + /// Whether or not the held item was successfully consumed public bool ConsumeHeldItem() => Interface.pokemon_consume_held_item(Handle).Result() == 1; + /// + /// The current health of the Pokemon. + /// public uint CurrentHealth => Interface.pokemon_current_health(Handle); + + /// + /// The max health of the Pokemon. + /// public uint MaxHealth => Interface.pokemon_max_health(Handle); + + /// + /// The current weight of the Pokemon. + /// public float Weight => Interface.pokemon_weight(Handle); + + /// + /// The current height of the Pokemon. + /// public float Height => Interface.pokemon_height(Handle); + /// + /// An optional nickname of the Pokemon. If the Pokemon does not have a nickname, this will return null. + /// public string? Nickname => Interface.pokemon_nickname(Handle).Result().PtrString(); + + /// + /// Whether the actual ability the Pokemon has (so not its potentially overriden ability) is a hidden ability. + /// public bool HasHiddenAbility => Interface.pokemon_real_ability_is_hidden(Handle) == 1; + + /// + /// The index of the actual ability the Pokemon has (so not its potentially overriden ability). + /// public byte AbilityIndex => Interface.pokemon_real_ability_index(Handle); private ExternValueArray? _types; - public ExternValueArray Types => + + /// + /// An array of the types of the Pokemon. + /// + public IReadOnlyList Types => _types ??= new ExternValueArray(() => Interface.pokemon_types_length(Handle), arg => Interface.pokemon_types_get(Handle, arg).Result()); - public LearnedMove? LearnedMove(ulong index) - { - var ptr = Interface.pokemon_learned_move_get(Handle, index); - return ptr.IsNull ? null : Resolver.Instance.ResolveLearnedMove(ptr.Resolve()); - } + private ExternValueArray? _moves; + /// + /// The moves the Pokemon has learned and can use. + /// + public IReadOnlyList LearnedMoves => + _moves ??= new ExternValueArray(() => 4, arg => + { + var ptr = Interface.pokemon_learned_move_get(Handle, arg); + return ptr.IsNull ? null : Resolver.Instance.ResolveLearnedMove(ptr.Resolve()); + }); + private StatisticSet? _flatStats; + + /// + /// The stats of the Pokemon when disregarding any stat boosts. + /// public StatisticSet FlatStats => - _flatStats ??= - Resolver.Instance.ResolveStatisticSet(Interface.pokemon_flat_stats(Handle).Resolve()); + _flatStats ??= Resolver.Instance.ResolveStatisticSet(Interface.pokemon_flat_stats(Handle).Resolve()); private StatisticSet? _boostedStats; + + /// + /// The stats of the Pokemon including the stat boosts. + /// public StatisticSet BoostedStats => _boostedStats ??= Resolver.Instance.ResolveStatisticSet(Interface.pokemon_boosted_stats(Handle).Resolve()); + /// + /// Get the stat boosts for a specific stat. Between -6 and 6. + /// public sbyte GetStatBoost(Statistic statistic) => Interface.pokemon_get_stat_boost(Handle, statistic); - public byte GetIndividualValue(Statistic statistic) => Interface.pokemon_get_individual_value(Handle, statistic); + + /// + /// Gets an individual value of the Pokemon. + /// See also + /// + public byte GetIndividualValue(Statistic statistic) => + Interface.pokemon_get_individual_value(Handle, statistic); + + /// + /// Gets an effort value of the Pokemon. + /// See also + /// public byte GetEffortValue(Statistic statistic) => Interface.pokemon_get_effort_value(Handle, statistic); + /// + /// Modifies an individual value of the Pokemon. + /// See also + /// public void SetIndividualValue(Statistic statistic, byte value) => Interface.pokemon_set_individual_value(Handle, statistic, value).Result(); + /// + /// Modifies a effort value of the Pokemon. + /// See also + /// public void SetEffortValue(Statistic statistic, byte value) => Interface.pokemon_set_effort_value(Handle, statistic, value).Result(); // TODO: Battle getter + + /// + /// 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. + /// public byte BattleSideIndex => Interface.pokemon_get_battle_side_index(Handle); + + /// + /// 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. + /// public byte BattleIndex => Interface.pokemon_get_battle_index(Handle); + + /// + /// Returns whether something overrides the ability. + /// public bool IsAbilityOverriden => Interface.pokemon_is_ability_overriden(Handle) == 1; + /// + /// Returns the currently active ability. + /// public Ability ActiveAbility => Resolver.Instance.ResolveAbility(Interface.pokemon_active_ability(Handle).Result().Resolve()); + /// + /// Whether or not the Pokemon is allowed to gain experience. + /// public bool AllowedExperienceGain => Interface.pokemon_allowed_experience_gain(Handle) == 1; + /// + /// The nature of the Pokemon. + /// See also + /// public Nature Nature => Resolver.Instance.ResolveNature(Interface.pokemon_nature(Handle).Resolve()); + /// + /// 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. + /// public void RecalculateFlatStats() => Interface.pokemon_recalculate_flat_stats(Handle).Result(); + + /// + /// Calculates the boosted stats on the Pokemon. This should be called when a stat boost changes. + /// public void RecalculateBoostedStats() => Interface.pokemon_recalculate_boosted_stats(Handle).Result(); + /// + /// Change the species of the Pokemon. + /// public void ChangeSpecies(Species species, Form form) => Interface.pokemon_change_species(Handle, species.Handle, form.Handle).Result(); + /// + /// Change the form of the Pokemon. + /// public void ChangeForm(Form form) => Interface.pokemon_change_form(Handle, form.Handle).Result(); + /// + /// Whether or not the Pokemon is useable in a battle. + /// public bool IsUsable => Interface.pokemon_is_usable(Handle) == 1; + /// + /// Returns whether the Pokemon is fainted. + /// public bool IsFainted => Interface.pokemon_is_fainted(Handle) == 1; + /// + /// Whether or not the Pokemon is on the battlefield. + /// public bool IsOnBattleField => Interface.pokemon_is_on_battlefield(Handle) == 1; - public void Damage(uint amount, DamageSource source) => Interface.pokemon_damage(Handle, amount, source).Result(); + /// + /// Damages the Pokemon by a certain amount of damage, from a damage source. + /// + public void Damage(uint amount, DamageSource source) => + Interface.pokemon_damage(Handle, amount, source).Result(); + /// + /// Heals the Pokemon by a specific amount. Unless allow_revive is set to true, this will not + /// heal if the Pokemon has 0 health. If the amount healed is 0, this will return false. + /// public bool Heal(uint amount, bool allowRevive) => Interface.pokemon_heal(Handle, amount, allowRevive.ForeignBool()) == 1; + /// + /// Learn a move. + /// public void LearnMove(string moveName, MoveLearnMethod learnMethod) => Interface.pokemon_learn_move(Handle, moveName.ToPtr(), learnMethod).Result(); + /// + /// Removes the current non-volatile status from the Pokemon. + /// public void ClearStatus() => Interface.pokemon_clear_status(Handle); } } \ No newline at end of file diff --git a/PkmnLibRSharp/DynamicData/PokemonBuilder.cs b/PkmnLibRSharp/DynamicData/PokemonBuilder.cs index 8e7bf30..c3cd3ff 100644 --- a/PkmnLibRSharp/DynamicData/PokemonBuilder.cs +++ b/PkmnLibRSharp/DynamicData/PokemonBuilder.cs @@ -6,6 +6,9 @@ using PkmnLibSharp.Utils; namespace PkmnLibSharp.DynamicData { + /// + /// A builder class for creating instances. + /// public class PokemonBuilder { private static readonly Random DefaultRandom = new(); @@ -29,6 +32,10 @@ namespace PkmnLibSharp.DynamicData private byte _abilityIndex; private byte _coloring; + /// + /// The library the Pokemon should use for data + /// The name of the species of Pokemon + /// The level the Pokemon should be public PokemonBuilder(DynamicLibrary library, string species, LevelInt level) { _library = library; @@ -38,54 +45,82 @@ namespace PkmnLibSharp.DynamicData _random = new Random(_randomSeed); } + /// + /// Sets the name of the form of the Pokemon. + /// public PokemonBuilder WithForm(string form) { _form = form; return this; } + /// + /// Force the Pokemon to be shiny or not shiny, instead of letting this be determined randomly. + /// public PokemonBuilder ForceShiny(bool value) { _forceShininess = value; return this; } + /// + /// Sets the gender of the Pokemon to a specific value, instead of letting this be determined randomly. + /// public PokemonBuilder WithGender(Gender gender) { _gender = gender; return this; } + /// + /// Sets the identifier of the Pokemon to a specific value, instead of letting this be determined randomly. + /// public PokemonBuilder WithIdentifier(uint identifier) { _identifier = identifier; return this; } + /// + /// Sets the nature of the Pokemon to a specific value, instead of letting this be determined randomly. + /// public PokemonBuilder WithNature(string nature) { _natureName = nature; return this; } + /// + /// Sets the ability of the Pokemon to a specific value, instead of letting this be determined randomly. + /// public PokemonBuilder WithAbility(string ability) { _ability = ability; return this; } + /// + /// Gives the Pokemon a specific amount of experience. If not set, the experience will be calculated based on + /// the Pokemon's level and growth rate. + /// public PokemonBuilder WithExperience(uint experience) { _experience = experience; return this; } + /// + /// Teaches the Pokemon a move. + /// public PokemonBuilder LearnMove(string moveName, MoveLearnMethod learnMethod) { _moves.Add((moveName, learnMethod)); return this; } + /// + /// This method is called after all properties have been set, and will create the Pokemon. + /// protected virtual Pokemon Finalize(Species species, Form form, Item? heldItem) { var pokemon = Pokemon.Create(_library, species, form, _hiddenAbility, _abilityIndex, _level, @@ -100,6 +135,9 @@ namespace PkmnLibSharp.DynamicData return pokemon; } + /// + /// Populates any properties that have not been set with random values. + /// protected virtual void PopulateUninitialized(Species species, Form form, Random random) { _experience ??= _library.StaticData.GrowthRateLibrary.CalculateExperience(species.GrowthRate, _level); @@ -146,6 +184,9 @@ namespace PkmnLibSharp.DynamicData return (true, (byte)i); } + /// + /// Builds the Pokemon, based on the properties that have been set. + /// public Pokemon Build() { if (!_library.StaticData.SpeciesLibrary.TryGetValue(_species, out var species)) diff --git a/PkmnLibRSharp/DynamicData/PokemonParty.cs b/PkmnLibRSharp/DynamicData/PokemonParty.cs new file mode 100644 index 0000000..3257c62 --- /dev/null +++ b/PkmnLibRSharp/DynamicData/PokemonParty.cs @@ -0,0 +1,102 @@ +using System.Collections; +using System.Collections.Generic; +using PkmnLibSharp.Utils; +using Interface = PkmnLibSharp.FFI.DynamicData.PokemonParty; + +namespace PkmnLibSharp.DynamicData +{ + /// + /// A list of Pokemon belonging to a trainer. + /// + public class PokemonParty : HandleType, IReadOnlyList + { + /// + /// A cache of the Pokemon in the party. + /// + private Pokemon?[] _cachedPokemon = null!; + + internal PokemonParty(FFIHandle handle) : base(handle) + { + } + + /// + /// Instantiates a party with a set size. + /// + /// The length of the party + public static PokemonParty Create(ulong capacity) + { + var handle = Interface.pokemon_party_new(capacity).Resolve(); + var party = Resolver.Instance.ResolvePokemonParty(handle); + party._cachedPokemon = new Pokemon?[capacity]; + return party; + } + + /// + public IEnumerator GetEnumerator() + { + return ((IEnumerable)_cachedPokemon).GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + + /// + public int Count => _cachedPokemon.Length; + + /// + public Pokemon? this[int index] => _cachedPokemon[index]; + + /// + /// Swaps two Pokemon in the party around. + /// + public void Switch(int a, int b) + { + Interface.pokemon_party_switch(Handle, (ulong)a, (ulong)b).Result(); + (_cachedPokemon[a], _cachedPokemon[b]) = (_cachedPokemon[b], _cachedPokemon[a]); + } + + /// + /// Sets the Pokemon at an index to a Pokemon, returning the old Pokemon. + /// + /// The index to switch at + /// The pokemon to switch into the slot + /// The previous Pokemon in the slot + public Pokemon? SwapInto(int index, Pokemon? pokemon) + { + var handle = Interface.pokemon_party_swap_into(Handle, (ulong)index, pokemon?.Handle ?? FFIHandle.Zero) + .Result(); + var p = handle.IsNull ? null : Resolver.Instance.ResolvePokemon(handle.Resolve()); + _cachedPokemon[index] = pokemon; + return p; + } + + /// + /// Whether or not the party still has Pokemon that can be used in battle. + /// + public bool HasUsablePokemon() => Interface.pokemon_party_has_usable_pokemon(Handle) == 1; + /// + /// Checks if the party contains a given pokemon. + /// + /// The pokemon to check for + public bool HasPokemon(Pokemon pokemon) => Interface.pokemon_party_has_pokemon(Handle, pokemon.Handle) == 1; + + /// + /// Makes sure there are no empty spots in the party anymore, leaving the length the same. + /// + public void PackParty() + { + Interface.pokemon_party_pack_party(Handle); + // Ensure the old cache is kept alive while we update the new one. + var oldCache = _cachedPokemon; + + // Update the cache. + _cachedPokemon = new Pokemon?[oldCache.Length]; + for (var i = 0; i < oldCache.Length; i++) + { + var handle = Interface.pokemon_party_at(Handle, (ulong)i).Resolve(); + _cachedPokemon[i] = Resolver.Instance.ResolvePokemon(handle); + } + } + + } +} \ No newline at end of file diff --git a/PkmnLibRSharp/FFI/DynamicData/Pokemon.cs b/PkmnLibRSharp/FFI/DynamicData/Pokemon.cs index 24be029..45d9f7c 100644 --- a/PkmnLibRSharp/FFI/DynamicData/Pokemon.cs +++ b/PkmnLibRSharp/FFI/DynamicData/Pokemon.cs @@ -54,7 +54,7 @@ namespace PkmnLibSharp.FFI.DynamicData internal static extern uint pokemon_experience(FFIHandleValue pokemon); [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] - internal static extern uint pokemon_unique_identifier(FFIHandleValue pokemon); + internal static extern uint pokemon_personality_value(FFIHandleValue pokemon); [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal static extern Gender pokemon_gender(FFIHandleValue pokemon); @@ -78,13 +78,13 @@ namespace PkmnLibSharp.FFI.DynamicData /// 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(FFIHandleValue pokemon, FFIHandle item); + internal static extern FFIHandleValue pokemon_set_held_item(FFIHandleValue pokemon, FFIHandle 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(FFIHandleValue pokemon); + internal static extern FFIHandleValue pokemon_remove_held_item(FFIHandleValue pokemon); /// /// Makes the Pokemon uses its held item. @@ -191,7 +191,7 @@ namespace PkmnLibSharp.FFI.DynamicData /// returns null. /// [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] - internal static extern IdentifiablePointer pokemon_get_battle(FFIHandleValue pokemon); + internal static extern FFIHandleValue pokemon_get_battle(FFIHandleValue pokemon); /// /// Get the index of the side of the battle the Pokemon is in. If the Pokemon diff --git a/PkmnLibRSharp/FFI/DynamicData/PokemonParty.cs b/PkmnLibRSharp/FFI/DynamicData/PokemonParty.cs new file mode 100644 index 0000000..2267d53 --- /dev/null +++ b/PkmnLibRSharp/FFI/DynamicData/PokemonParty.cs @@ -0,0 +1,59 @@ +using System; +using System.Runtime.InteropServices; +using PkmnLibSharp.StaticData; +using PkmnLibSharp.Utils; + +namespace PkmnLibSharp.FFI.DynamicData +{ + internal static class PokemonParty + { + /// + /// Instantiates a party with a set size. + /// + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + internal static extern FFIHandleValue pokemon_party_new(ulong capacity); + + /// + /// Gets a Pokemon at an index in the party. + /// + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + internal static extern FFIHandleValue pokemon_party_at(FFIHandleValue party, ulong index); + + /// + /// Swaps two Pokemon in the party around. + /// + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + internal static extern NativeResult pokemon_party_switch(FFIHandle party, ulong a, ulong b); + + /// + /// Sets the Pokemon at an index to a Pokemon, returning the old Pokemon. + /// + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + internal static extern NativeResult pokemon_party_swap_into(FFIHandleValue party, ulong index, + FFIHandleValue pokemon); + + /// + /// Whether or not the party still has Pokemon that can be used in battle. + /// + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + internal static extern byte pokemon_party_has_usable_pokemon(FFIHandleValue party); + + /// + /// Get the length of the underlying list of Pokemon. + /// + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + internal static extern ulong pokemon_party_length(FFIHandleValue party); + + /// + /// Makes sure there are no empty spots in the party anymore, leaving the length the same. + /// + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + internal static extern NativeResult pokemon_party_pack_party(FFIHandleValue party); + + /// + /// Checks if the party contains a given pokemon. + /// + [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] + internal static extern byte pokemon_party_has_pokemon(FFIHandleValue party, FFIHandleValue pokemon); + } +} \ No newline at end of file diff --git a/PkmnLibRSharp/FFI/IdentifiablePointer.cs b/PkmnLibRSharp/FFI/IdentifiablePointer.cs deleted file mode 100644 index bfe2182..0000000 --- a/PkmnLibRSharp/FFI/IdentifiablePointer.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Runtime.InteropServices; - -namespace PkmnLibSharp.FFI -{ - [StructLayout(LayoutKind.Sequential)] - public struct IdentifiablePointer - { - public readonly IntPtr Ptr; - public readonly nuint Identifier; - - public bool IsNull => Ptr == IntPtr.Zero; - } -} \ No newline at end of file diff --git a/PkmnLibRSharp/FFI/NativeResult.cs b/PkmnLibRSharp/FFI/NativeResult.cs index 231f2b3..0779ce1 100644 --- a/PkmnLibRSharp/FFI/NativeResult.cs +++ b/PkmnLibRSharp/FFI/NativeResult.cs @@ -43,6 +43,9 @@ namespace PkmnLibSharp.FFI } } + /// + /// An error thrown by the library. + /// public class PkmnLibException : Exception { internal PkmnLibException(string message) : base(message){} diff --git a/PkmnLibRSharp/FFI/StaticData/Libraries/MoveLibrary.cs b/PkmnLibRSharp/FFI/StaticData/Libraries/MoveLibrary.cs index d2ffec5..83e31f7 100644 --- a/PkmnLibRSharp/FFI/StaticData/Libraries/MoveLibrary.cs +++ b/PkmnLibRSharp/FFI/StaticData/Libraries/MoveLibrary.cs @@ -10,7 +10,7 @@ namespace PkmnLibSharp.FFI.StaticData.Libraries internal static extern FFIHandleValue move_library_new(ulong capacity); [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] - internal static extern IdentifiablePointer move_library_get(FFIHandleValue ptr, IntPtr key); + internal static extern FFIHandleValue move_library_get(FFIHandleValue ptr, IntPtr key); [DllImport(Data.DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] internal static extern IntPtr move_library_get_key_by_index(FFIHandleValue ptr, ulong index); diff --git a/PkmnLibRSharp/PkmnLibRSharp.csproj b/PkmnLibRSharp/PkmnLibRSharp.csproj index 16470e8..769139e 100644 --- a/PkmnLibRSharp/PkmnLibRSharp.csproj +++ b/PkmnLibRSharp/PkmnLibRSharp.csproj @@ -14,11 +14,13 @@ IDISP012 true TRACE;WASM; + bin\Debug\PkmnLibRSharp.xml true TRACE;WASM; + true diff --git a/PkmnLibRSharp/StaticData/Ability.cs b/PkmnLibRSharp/StaticData/Ability.cs index a2b35a7..562b28d 100644 --- a/PkmnLibRSharp/StaticData/Ability.cs +++ b/PkmnLibRSharp/StaticData/Ability.cs @@ -5,20 +5,38 @@ using Interface = PkmnLibSharp.FFI.StaticData.Ability; namespace PkmnLibSharp.StaticData { + /// + /// An ability is a passive effect in battle that is attached to a Pokemon. + /// public class Ability : HandleType { private string? _name; + + /// + /// The name of the ability. + /// public string Name => _name ??= Interface.ability_name(Handle).Result().PtrString()!; private string? _effect; + + /// + /// The name of the script effect of the ability. + /// public string Effect => _effect ??= Interface.ability_effect(Handle).Result().PtrString()!; + /// + /// The parameters for the script effect of the ability. + /// public IReadOnlyList Parameters { get; private set; } = null!; + /// protected Ability(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new ability. + /// public static Ability Create(string name, string effect, IReadOnlyList parameters) { var parameterArray = parameters.Select(x => (FFIHandleValue)x.Handle).ToArray(); diff --git a/PkmnLibRSharp/StaticData/EffectParameter.cs b/PkmnLibRSharp/StaticData/EffectParameter.cs index b2e6318..5cca9db 100644 --- a/PkmnLibRSharp/StaticData/EffectParameter.cs +++ b/PkmnLibRSharp/StaticData/EffectParameter.cs @@ -4,13 +4,27 @@ using Interface = PkmnLibSharp.FFI.StaticData.EffectParameter; namespace PkmnLibSharp.StaticData { + /// + /// A parameter for an effect. This is basically a simple way to dynamically store multiple different + /// primitives on data. + /// public class EffectParameter : HandleType { private ParameterType? _type; + + /// + /// The underlying type of the parameter. + /// public ParameterType? Type => _type ??= (ParameterType)Interface.effect_parameter_get_type(Handle); private object? _data; + /// + /// The data stored in the parameter. + /// + /// + /// Thrown when the parameter type is not recognized. This should never happen. + /// public object Data { get @@ -27,35 +41,75 @@ namespace PkmnLibSharp.StaticData } } + /// protected EffectParameter(FFIHandle handle) : base(handle) { } + /// + /// Creates a new parameter from a boolean. + /// public static EffectParameter FromBool(bool b) => Resolver.Instance.ResolveEffectParameter(Interface.effect_parameter_new_bool(b.ForeignBool()).Resolve()); + /// + /// Creates a new parameter from a 64 bit integer. + /// public static EffectParameter FromLong(long l) => Resolver.Instance.ResolveEffectParameter(Interface.effect_parameter_new_int(l).Resolve()); + /// + /// Creates a new parameter from a float. + /// public static EffectParameter FromFloat(float f) => Resolver.Instance.ResolveEffectParameter(Interface.effect_parameter_new_float(f).Resolve()); + /// + /// Creates a new parameter from a string. + /// public static EffectParameter FromString(string s) => - Resolver.Instance.ResolveEffectParameter(Interface.effect_parameter_new_string(s.ToPtr()).Result().Resolve()); - + Resolver.Instance.ResolveEffectParameter( + Interface.effect_parameter_new_string(s.ToPtr()).Result().Resolve()); + + /// public static implicit operator EffectParameter(bool b) => FromBool(b); + + /// public static implicit operator EffectParameter(long l) => FromLong(l); + + /// public static implicit operator EffectParameter(float f) => FromFloat(f); + + /// public static implicit operator EffectParameter(string s) => FromString(s); + /// + /// The different types of parameters. + /// public enum ParameterType : byte { + /// + /// A boolean parameter. + /// Bool = 0, + + /// + /// A 64 bit integer parameter. + /// Int = 1, + + /// + /// A 32 bit floating point parameter. + /// Float = 2, + + /// + /// A string parameter. + /// String = 3, } + /// public override string ToString() { var data = Data; diff --git a/PkmnLibRSharp/StaticData/Form.cs b/PkmnLibRSharp/StaticData/Form.cs index f1175d5..14a7959 100644 --- a/PkmnLibRSharp/StaticData/Form.cs +++ b/PkmnLibRSharp/StaticData/Form.cs @@ -5,12 +5,20 @@ using Interface = PkmnLibSharp.FFI.StaticData.Form; namespace PkmnLibSharp.StaticData { + /// + /// A form is a variant of a specific species. A species always has at least one form, but can have + /// many more. + /// public class Form : HandleType { + /// protected Form(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new form. + /// public static Form Create(string name, float height, float weight, uint baseExperience, TypeIdentifier[] types, StaticStatisticSet baseStats, IReadOnlyCollection abilities, IReadOnlyCollection hiddenAbilities, LearnableMoves learnableMoves, @@ -32,34 +40,69 @@ namespace PkmnLibSharp.StaticData private string? _name; + /// + /// The name of the form. + /// public string Name => _name ??= Interface.form_name(Handle).Result().PtrString()!; private float? _height; + + /// + /// The height of the form in meters. + /// public float Height => _height ??= Interface.form_height(Handle); private float? _weight; + + /// + /// The weight of the form in kilograms. + /// public float Weight => _weight ??= Interface.form_weight(Handle); private uint? _baseExperience; + + /// + /// The base amount of experience that is gained when beating a Pokemon with this form. + /// public uint BaseExperience => _baseExperience ??= Interface.form_base_experience(Handle); private IReadOnlyList? _types; + + /// + /// The normal types a Pokemon with this form has. + /// public IReadOnlyList Types => _types ??= new CachedExternValueArray(Interface.form_types_length(Handle), arg => Interface.form_types_get(Handle, arg)); private StaticStatisticSet? _baseStats; + + /// + /// The inherent values of a form of species that are used for the stats of a Pokemon. + /// public StaticStatisticSet BaseStats => _baseStats ??= Resolver.Instance.ResolveStaticStatisticSet(Interface.form_base_stats(Handle).Resolve()); private IReadOnlyList? _abilities; + + /// + /// The possible abilities a Pokemon with this form can have. + /// public IReadOnlyList Abilities => _abilities ??= new CachedExternArray(Interface.form_abilities_length(Handle), arg => Interface.form_abilities_get(Handle, arg).PtrString()!); private IReadOnlyList? _hiddenAbilities; + + /// + /// The possible hidden abilities a Pokemon with this form can have. + /// public IReadOnlyList HiddenAbilities => _hiddenAbilities ??= new CachedExternArray(Interface.form_hidden_abilities_length(Handle), arg => Interface.form_hidden_abilities_get(Handle, arg).PtrString()!); private LearnableMoves? _learnableMoves; + + /// + /// The moves a Pokemon with this form can learn. + /// public LearnableMoves LearnableMoves => _learnableMoves ??= Resolver.Instance.ResolveLearnableMoves(Interface.form_moves(Handle).Resolve()); } diff --git a/PkmnLibRSharp/StaticData/Gender.cs b/PkmnLibRSharp/StaticData/Gender.cs index 1efafa4..1f9645f 100644 --- a/PkmnLibRSharp/StaticData/Gender.cs +++ b/PkmnLibRSharp/StaticData/Gender.cs @@ -1,5 +1,11 @@ namespace PkmnLibSharp.StaticData { + /// + /// Gender is a Pokemon characteristic. + /// + /// Required for standard pokemon functions, but somewhat controversial nowadays. Consider adding a feature + /// that allows for a more progressive gender system for those that want it? + /// public enum Gender : byte { /// diff --git a/PkmnLibRSharp/StaticData/GrowthRate.cs b/PkmnLibRSharp/StaticData/GrowthRate.cs index 99ea4d1..c85d693 100644 --- a/PkmnLibRSharp/StaticData/GrowthRate.cs +++ b/PkmnLibRSharp/StaticData/GrowthRate.cs @@ -5,28 +5,45 @@ using Interface = PkmnLibSharp.FFI.StaticData.GrowthRate; namespace PkmnLibSharp.StaticData { + /// + /// A growth rate defines how much experience is required per level. + /// public abstract class GrowthRate : HandleType { - + /// protected internal GrowthRate(FFIHandle ptr) : base(ptr) { } + /// + /// Calculate the level something with this growth rate would have at a certain experience. + /// public LevelInt CalculateLevel(uint experience) { return Interface.growth_rate_calculate_level(Handle, experience); } + /// + /// Calculate the experience something with this growth rate would have at a certain level. + /// public uint CalculateExperience(LevelInt level) { return Interface.growth_rate_calculate_experience(Handle, level).Result(); } } + /// + /// An implementation of the growth rate that uses a lookup table for experience. + /// public class LookupGrowthRate : GrowthRate { + /// protected LookupGrowthRate(FFIHandle handle) : base(handle){} + /// + /// Instantiates a new lookup growth rate. The experience vec should be the amount of experience + /// required per level, with the first element being the experience required for level 1 (generally 0). + /// public static LookupGrowthRate Create(uint[] experienceArray) { var arrayPtr = experienceArray.ArrayPtr(); @@ -52,6 +69,10 @@ namespace PkmnLibSharp.StaticData return i * i * i; } + /// + /// The Fast experience group + /// See also + /// public static LookupGrowthRate Fast(LevelInt maxLevel) { var arr = new uint[maxLevel]; @@ -64,6 +85,10 @@ namespace PkmnLibSharp.StaticData return LookupGrowthRate.Create(arr); } + /// + /// The Medium Fast experience group + /// See also + /// public static LookupGrowthRate MediumFast(LevelInt maxLevel) { var arr = new uint[maxLevel]; @@ -76,6 +101,10 @@ namespace PkmnLibSharp.StaticData return LookupGrowthRate.Create(arr); } + /// + /// The Medium Slow experience group + /// See also + /// public static LookupGrowthRate MediumSlow(LevelInt maxLevel) { var arr = new uint[maxLevel]; @@ -88,6 +117,10 @@ namespace PkmnLibSharp.StaticData return LookupGrowthRate.Create(arr); } + /// + /// The Slow experience group + /// See also + /// public static LookupGrowthRate Slow(LevelInt maxLevel) { var arr = new uint[maxLevel]; @@ -99,6 +132,10 @@ namespace PkmnLibSharp.StaticData return LookupGrowthRate.Create(arr); } + /// + /// The Erratic experience group + /// See also + /// public static LookupGrowthRate Erratic(LevelInt maxLevel) { var arr = new uint[maxLevel]; @@ -127,6 +164,10 @@ namespace PkmnLibSharp.StaticData return LookupGrowthRate.Create(arr); } + /// + /// The fluctuating experience group + /// See also + /// public static LookupGrowthRate Fluctuating(LevelInt maxLevel) { var arr = new uint[maxLevel]; diff --git a/PkmnLibRSharp/StaticData/Item.cs b/PkmnLibRSharp/StaticData/Item.cs index 48ba515..34e19ff 100644 --- a/PkmnLibRSharp/StaticData/Item.cs +++ b/PkmnLibRSharp/StaticData/Item.cs @@ -82,10 +82,17 @@ namespace PkmnLibSharp.StaticData MiscBattleItem, } + /// + /// An item is an object which the player can pick up, keep in their Bag, and use in some manner + /// public class Item : HandleType { + /// protected Item(FFIHandle handle) : base(handle){} + /// + /// Instantiates an item. + /// public static Item Create(string name, ItemCategory category, BattleItemCategory battleItemCategory, int price, IEnumerable flags) { @@ -97,14 +104,29 @@ namespace PkmnLibSharp.StaticData } private string? _name; + /// + /// The name of the item. + /// public string Name => _name ??= Interface.item_name(Handle).Result().PtrString()!; private ItemCategory? _category; + /// + /// Which bag slot items are stored in. + /// public ItemCategory Category => _category ??= Interface.item_category(Handle); private BattleItemCategory? _battleCategory; + /// + /// How the item is categorized when in battle. + /// public BattleItemCategory BattleCategory => _battleCategory ??= Interface.item_battle_category(Handle); private int? _price; + /// + /// The buying value of the item. + /// public int Price => _price ??= Interface.item_price(Handle); + /// + /// Checks whether the item has a specific flag. + /// public bool HasFlag(string flag) => Interface.item_has_flag(Handle, flag.ToPtr()) == 1; } } \ No newline at end of file diff --git a/PkmnLibRSharp/StaticData/LearnableMoves.cs b/PkmnLibRSharp/StaticData/LearnableMoves.cs index 2db6efd..ab7e75b 100644 --- a/PkmnLibRSharp/StaticData/LearnableMoves.cs +++ b/PkmnLibRSharp/StaticData/LearnableMoves.cs @@ -3,23 +3,36 @@ using Interface = PkmnLibSharp.FFI.StaticData.LearnableMoves; namespace PkmnLibSharp.StaticData { + /// + /// The storage of the moves a Pokemon can learn. + /// public class LearnableMoves : HandleType { + /// protected LearnableMoves(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new object to store the moves a Pokemon can learn. + /// public static LearnableMoves Create() { var handle = Interface.learnable_moves_new(); return Resolver.Instance.ResolveLearnableMoves(handle.Resolve()); } + /// + /// Adds a new level move the Pokemon can learn. + /// public void AddLevelMove(LevelInt level, string moveName) { Interface.learnable_moves_add_level_move(Handle, level, moveName.ToPtr()); } + /// + /// Adds a new level move the Pokemon can learn. + /// public void AddLevelMove(LevelInt level, MoveData move) { Interface.learnable_moves_add_level_move(Handle, level, move.Name.ToPtr()); diff --git a/PkmnLibRSharp/StaticData/LevelInt.cs b/PkmnLibRSharp/StaticData/LevelInt.cs index 4641dda..265c072 100644 --- a/PkmnLibRSharp/StaticData/LevelInt.cs +++ b/PkmnLibRSharp/StaticData/LevelInt.cs @@ -1,29 +1,48 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using BackingLevelInt = System.Byte; // ReSharper disable BuiltInTypeReferenceStyle +// The type we store a level in. As our implementation is aimed at normal Pokemon behaviour, a u8 +// is probably enough, as we'd go up to 100. If you for some reason want to go higher, you can just +// change this type to hold a higher number. +using BackingLevelInt = System.Byte; + namespace PkmnLibSharp.StaticData { + /// + /// The data structure used to store a level. This is a struct to allow for easy modification of the data type. + /// + /// + /// If you want to change the type of the level, you can just change the type of . + /// Most of the implementation below is to allow for easy conversion between the two types, and to allow for + /// using the type as a normal integer. + /// [StructLayout(LayoutKind.Explicit)] public struct LevelInt : IComparable, IComparable, IComparable, IConvertible, IEquatable, IEquatable, IEquatable, IFormattable { [FieldOffset(0)] private BackingLevelInt _value; + /// + /// Converts a to a . + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator BackingLevelInt(LevelInt l) { return l._value; } + /// + /// Converts a to a . + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator LevelInt(BackingLevelInt b) { return new LevelInt { _value = b }; } + /// public int CompareTo(object obj) { if (obj is LevelInt l) @@ -31,89 +50,120 @@ namespace PkmnLibSharp.StaticData return _value.CompareTo(obj); } + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CompareTo(BackingLevelInt other) => _value.CompareTo(other); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CompareTo(LevelInt other) => _value.CompareTo(other._value); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public TypeCode GetTypeCode() => Type.GetTypeCode(typeof(BackingLevelInt)); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ToBoolean(IFormatProvider provider) => ((IConvertible)_value).ToBoolean(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public byte ToByte(IFormatProvider provider) => ((IConvertible)_value).ToByte(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public char ToChar(IFormatProvider provider) => ((IConvertible)_value).ToChar(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public DateTime ToDateTime(IFormatProvider provider) => ((IConvertible)_value).ToDateTime(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public decimal ToDecimal(IFormatProvider provider) => ((IConvertible)_value).ToDecimal(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public double ToDouble(IFormatProvider provider) => ((IConvertible)_value).ToDouble(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public short ToInt16(IFormatProvider provider) => ((IConvertible)_value).ToInt16(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public int ToInt32(IFormatProvider provider) => ((IConvertible)_value).ToInt32(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public long ToInt64(IFormatProvider provider) => ((IConvertible)_value).ToInt64(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public sbyte ToSByte(IFormatProvider provider) => ((IConvertible)_value).ToSByte(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public float ToSingle(IFormatProvider provider) => ((IConvertible)_value).ToSingle(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ToString(IFormatProvider provider) => _value.ToString(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public object ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)_value).ToType(conversionType, provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public ushort ToUInt16(IFormatProvider provider) => ((IConvertible)_value).ToUInt16(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public uint ToUInt32(IFormatProvider provider) => ((IConvertible)_value).ToUInt32(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public ulong ToUInt64(IFormatProvider provider) => ((IConvertible)_value).ToUInt64(provider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(BackingLevelInt other) => _value == other; + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public string ToString(string format, IFormatProvider formatProvider) => _value.ToString(format, formatProvider); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(LevelInt other) => _value == other._value; + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(int other) => _value == other; + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool Equals(object? obj) => obj is LevelInt other && Equals(other); + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() { return _value.GetHashCode(); } + /// + /// Equality operator for . + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(LevelInt left, LevelInt right) => left.Equals(right); + /// + /// Inequality operator for . + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(LevelInt left, LevelInt right) => !left.Equals(right); } diff --git a/PkmnLibRSharp/StaticData/Libraries/AbilityLibrary.cs b/PkmnLibRSharp/StaticData/Libraries/AbilityLibrary.cs index 2e22856..ecf5f6b 100644 --- a/PkmnLibRSharp/StaticData/Libraries/AbilityLibrary.cs +++ b/PkmnLibRSharp/StaticData/Libraries/AbilityLibrary.cs @@ -6,12 +6,19 @@ using Interface = PkmnLibSharp.FFI.StaticData.Libraries.AbilityLibrary; namespace PkmnLibSharp.StaticData.Libraries { + /// + /// A storage for all abilities that can be used in this data library. + /// public class AbilityLibrary : DataLibrary { + /// protected AbilityLibrary(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new ability library. + /// public static AbilityLibrary Create(ulong capacity) { var handle = Interface.ability_library_new(capacity).Resolve(); @@ -20,6 +27,7 @@ namespace PkmnLibSharp.StaticData.Libraries return self; } + /// protected override void AddNative(string key, Ability value) => Interface.ability_library_add(Handle, key.ToPtr(), value.Handle); } diff --git a/PkmnLibRSharp/StaticData/Libraries/DataLibrary.cs b/PkmnLibRSharp/StaticData/Libraries/DataLibrary.cs index 5becca3..2f548ae 100644 --- a/PkmnLibRSharp/StaticData/Libraries/DataLibrary.cs +++ b/PkmnLibRSharp/StaticData/Libraries/DataLibrary.cs @@ -5,19 +5,30 @@ using PkmnLibSharp.Utils; namespace PkmnLibSharp.StaticData.Libraries { + /// + /// The base backing class for all data libraries. + /// + /// + /// The type that this data library stores. + /// public abstract class DataLibrary : HandleType, IReadOnlyDictionary where T : HandleType { private Dictionary _backingDictionary = new(StringComparer.InvariantCultureIgnoreCase); + /// protected DataLibrary(FFIHandle handle) : base(handle) { } - protected void ReserveCapacity(ulong capacity) + /// + /// Reserves the cache capacity for this data library. + /// + private protected void ReserveCapacity(ulong capacity) { _backingDictionary = new Dictionary((int)capacity, StringComparer.InvariantCultureIgnoreCase); } + /// public IEnumerator> GetEnumerator() { return _backingDictionary.GetEnumerator(); @@ -28,22 +39,36 @@ namespace PkmnLibSharp.StaticData.Libraries return GetEnumerator(); } + /// + /// Calls the native add function for this data library. + /// protected abstract void AddNative(string key, T value); + /// + /// Adds a new value to the library. + /// public void Add(string key, T value) { AddNative(key, value); _backingDictionary.Add(key, value); } + /// public int Count => _backingDictionary.Count; + + /// public bool ContainsKey(string key) => _backingDictionary.ContainsKey(key); + /// public bool TryGetValue(string key, out T value) => _backingDictionary.TryGetValue(key, out value); + /// public T this[string key] => _backingDictionary[key]; + /// public IEnumerable Keys => _backingDictionary.Keys; + + /// public IEnumerable Values => _backingDictionary.Values; } } \ No newline at end of file diff --git a/PkmnLibRSharp/StaticData/Libraries/GrowthRateLibrary.cs b/PkmnLibRSharp/StaticData/Libraries/GrowthRateLibrary.cs index 7ec01cc..539e17c 100644 --- a/PkmnLibRSharp/StaticData/Libraries/GrowthRateLibrary.cs +++ b/PkmnLibRSharp/StaticData/Libraries/GrowthRateLibrary.cs @@ -6,15 +6,22 @@ using Interface = PkmnLibSharp.FFI.StaticData.Libraries.GrowthRateLibrary; namespace PkmnLibSharp.StaticData.Libraries { + /// + /// A library to store all growth rates. + /// public class GrowthRateLibrary : HandleType { // ReSharper disable once CollectionNeverQueried.Local private Dictionary _growthRates = new(); + /// protected GrowthRateLibrary(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new growth rate library with a capacity. + /// public static GrowthRateLibrary Create(ulong capacity) { var handle = Interface.growth_rate_library_new(capacity); @@ -24,16 +31,25 @@ namespace PkmnLibSharp.StaticData.Libraries return lib; } + /// + /// Calculates the level for a given growth key name and a certain experience. + /// [MustUseReturnValue] public LevelInt CalculateLevel(string name, uint experience) => Interface.growth_rate_library_calculate_level(Handle, name.ToPtr(), experience).Result(); + /// + /// Calculates the experience for a given growth key name and a certain level. + /// [MustUseReturnValue] public uint CalculateExperience(string name, LevelInt level) { return Interface.growth_rate_library_calculate_experience(Handle, name.ToPtr(), level).Result(); } + /// + /// Adds a new growth rate with a name and value. + /// public void AddGrowthRate(string name, GrowthRate growthRate) { Interface.growth_rate_library_add_growth_rate(Handle, name.ToPtr(), growthRate.Handle); diff --git a/PkmnLibRSharp/StaticData/Libraries/ItemLibrary.cs b/PkmnLibRSharp/StaticData/Libraries/ItemLibrary.cs index 1070ad5..ccb39d9 100644 --- a/PkmnLibRSharp/StaticData/Libraries/ItemLibrary.cs +++ b/PkmnLibRSharp/StaticData/Libraries/ItemLibrary.cs @@ -5,10 +5,17 @@ using Interface = PkmnLibSharp.FFI.StaticData.Libraries.ItemLibrary; namespace PkmnLibSharp.StaticData.Libraries { + /// + /// A library to store all items. + /// public class ItemLibrary : DataLibrary { + /// protected ItemLibrary(FFIHandle handle) : base(handle){} + /// + /// Instantiates a new Item Library. + /// public static ItemLibrary Create(ulong capacity) { var handle = Interface.item_library_new(capacity).Resolve(); @@ -17,6 +24,7 @@ namespace PkmnLibSharp.StaticData.Libraries return self; } + /// protected override void AddNative(string key, Item value) { Interface.item_library_add(Handle, key.ToPtr(), value.Handle); diff --git a/PkmnLibRSharp/StaticData/Libraries/LibrarySettings.cs b/PkmnLibRSharp/StaticData/Libraries/LibrarySettings.cs index 933e75b..ce5a89b 100644 --- a/PkmnLibRSharp/StaticData/Libraries/LibrarySettings.cs +++ b/PkmnLibRSharp/StaticData/Libraries/LibrarySettings.cs @@ -10,6 +10,7 @@ namespace PkmnLibSharp.StaticData.Libraries /// public class LibrarySettings : HandleType { + /// protected LibrarySettings(FFIHandle handle) : base(handle) {} /// diff --git a/PkmnLibRSharp/StaticData/Libraries/MoveLibrary.cs b/PkmnLibRSharp/StaticData/Libraries/MoveLibrary.cs index 45d7d74..23554b6 100644 --- a/PkmnLibRSharp/StaticData/Libraries/MoveLibrary.cs +++ b/PkmnLibRSharp/StaticData/Libraries/MoveLibrary.cs @@ -6,18 +6,26 @@ using Interface = PkmnLibSharp.FFI.StaticData.Libraries.MoveLibrary; namespace PkmnLibSharp.StaticData.Libraries { + /// + /// A library to store all data for moves. + /// public class MoveLibrary : DataLibrary { + /// protected MoveLibrary(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new Move Library. + /// public static MoveLibrary Create(ulong capacity) { var handle = Interface.move_library_new(capacity); return Resolver.Instance.ResolveMoveLibrary(handle.Resolve()); } + /// protected override void AddNative(string key, MoveData value) { Interface.move_library_add(Handle, key.ToPtr(), value.Handle); diff --git a/PkmnLibRSharp/StaticData/Libraries/NatureLibrary.cs b/PkmnLibRSharp/StaticData/Libraries/NatureLibrary.cs index 3b6b4c8..a6acc63 100644 --- a/PkmnLibRSharp/StaticData/Libraries/NatureLibrary.cs +++ b/PkmnLibRSharp/StaticData/Libraries/NatureLibrary.cs @@ -8,14 +8,21 @@ using Interface = PkmnLibSharp.FFI.StaticData.Libraries.NatureLibrary; namespace PkmnLibSharp.StaticData.Libraries { + /// + /// A library of all natures that can be used, stored by their names. + /// public class NatureLibrary : HandleType { private Dictionary _natures = new(); + /// protected NatureLibrary(FFIHandle handle) : base(handle) { } + /// + /// Creates a new nature library with a given capacity. + /// public static NatureLibrary Create(ulong capacity) { var handle = Interface.nature_library_new(capacity); @@ -25,6 +32,9 @@ namespace PkmnLibSharp.StaticData.Libraries return lib; } + /// + /// Try to get a nature from the library by its name. + /// public bool TryGetNature(string name, [NotNullWhen(true)] out Nature? nature) { if (_natures.TryGetValue(name, out nature)) @@ -37,17 +47,29 @@ namespace PkmnLibSharp.StaticData.Libraries return true; } + /// + /// Gets a random nature. + /// + /// + /// The seed to use for the random number generator. + /// public Nature GetRandomNature(ulong seed) { return Resolver.Instance.ResolveNature(Interface.nature_library_get_random_nature(Handle, seed).Result().Resolve()); } + /// + /// Gets the name of a nature from its object. + /// public string GetNatureName(Nature nature) { var fd = _natures.FirstOrDefault(x => x.Value == nature); return fd.Key ?? Interface.nature_library_get_nature_name(Handle, nature.Handle).PtrString()!; } + /// + /// Adds a new nature with name to the library. + /// public void LoadNature(string name, Nature nature) { Interface.nature_library_load_nature(Handle, name.ToPtr(), nature.Handle); diff --git a/PkmnLibRSharp/StaticData/Libraries/SpeciesLibrary.cs b/PkmnLibRSharp/StaticData/Libraries/SpeciesLibrary.cs index 150b3f0..15dba7d 100644 --- a/PkmnLibRSharp/StaticData/Libraries/SpeciesLibrary.cs +++ b/PkmnLibRSharp/StaticData/Libraries/SpeciesLibrary.cs @@ -3,12 +3,19 @@ using Interface = PkmnLibSharp.FFI.StaticData.Libraries.SpeciesLibrary; namespace PkmnLibSharp.StaticData.Libraries { + /// + /// A library to store all data for Pokemon species. + /// public class SpeciesLibrary : DataLibrary { + /// protected SpeciesLibrary(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new Species Library. + /// public static SpeciesLibrary Create(ulong capacity) { var handle = Interface.species_library_new(capacity); @@ -18,6 +25,7 @@ namespace PkmnLibSharp.StaticData.Libraries return lib; } + /// protected override void AddNative(string key, Species value) { Interface.species_library_add(Handle, key.ToPtr(), value.Handle); diff --git a/PkmnLibRSharp/StaticData/Libraries/StaticData.cs b/PkmnLibRSharp/StaticData/Libraries/StaticData.cs index 674d015..422c0b5 100644 --- a/PkmnLibRSharp/StaticData/Libraries/StaticData.cs +++ b/PkmnLibRSharp/StaticData/Libraries/StaticData.cs @@ -3,12 +3,19 @@ using Interface = PkmnLibSharp.FFI.StaticData.Libraries.StaticData; namespace PkmnLibSharp.StaticData.Libraries { + /// + /// The storage for all different libraries. + /// public class StaticData : HandleType { + /// protected StaticData(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new data collection. + /// public static StaticData Create(LibrarySettings settings, SpeciesLibrary speciesLibrary, MoveLibrary moveLibrary, ItemLibrary itemLibrary, GrowthRateLibrary growthRateLibrary, TypeLibrary typeLibrary, NatureLibrary natureLibrary, AbilityLibrary abilityLibrary) @@ -28,13 +35,44 @@ namespace PkmnLibSharp.StaticData.Libraries return data; } + /// + /// Several misc settings for the library. + /// public LibrarySettings LibrarySettings { get; private set; } = null!; + + /// + /// All data for Pokemon species. + /// public SpeciesLibrary SpeciesLibrary { get; private set; } = null!; + + /// + /// All data for the moves. + /// public MoveLibrary MoveLibrary { get; private set; } = null!; + + /// + /// All data for the items. + /// public ItemLibrary ItemLibrary { get; private set; } = null!; + + /// + /// All data for growth rates. + /// public GrowthRateLibrary GrowthRateLibrary { get; private set; } = null!; + + /// + /// All data related to types and type effectiveness. + /// public TypeLibrary TypeLibrary { get; private set; } = null!; + + /// + /// All data related to natures. + /// public NatureLibrary NatureLibrary { get; private set; } = null!; + + /// + /// All data related to abilities. + /// public AbilityLibrary AbilityLibrary { get; private set; } = null!; } } \ No newline at end of file diff --git a/PkmnLibRSharp/StaticData/Libraries/TypeLibrary.cs b/PkmnLibRSharp/StaticData/Libraries/TypeLibrary.cs index 4469bda..f573e06 100644 --- a/PkmnLibRSharp/StaticData/Libraries/TypeLibrary.cs +++ b/PkmnLibRSharp/StaticData/Libraries/TypeLibrary.cs @@ -7,53 +7,81 @@ using Interface = PkmnLibSharp.FFI.StaticData.Libraries.TypeLibrary; namespace PkmnLibSharp.StaticData.Libraries { + /// + /// All data related to types and effectiveness. + /// public class TypeLibrary : HandleType { - public Dictionary TypeCache { get; private set; } = - new(StringComparer.InvariantCultureIgnoreCase); - - protected TypeLibrary(FFIHandle handle) : base(handle){} - + private Dictionary _typeCache = new(StringComparer.InvariantCultureIgnoreCase); + + /// + protected TypeLibrary(FFIHandle handle) : base(handle) + { + } + + /// + /// Instantiates a new type library with a specific capacity. + /// public static TypeLibrary Create(ulong capacity) { var handle = Interface.type_library_new(capacity); var lib = Resolver.Instance.ResolveTypeLibrary(handle.Resolve()); - lib.TypeCache = new Dictionary((int)capacity, StringComparer.InvariantCultureIgnoreCase); + lib._typeCache = + new Dictionary((int)capacity, StringComparer.InvariantCultureIgnoreCase); return lib; } + /// + /// Gets the type identifier for a type with a name. + /// public TypeIdentifier GetTypeId(string name) { - if (TypeCache.TryGetValue(name, out var typeIdentifier)) + if (_typeCache.TryGetValue(name, out var typeIdentifier)) return typeIdentifier; throw new KeyNotFoundException($"No type found with name `{name}`"); } + /// + /// Gets the type name from the type identifier. + /// public string GetTypeName(TypeIdentifier typeIdentifier) { - var fd = TypeCache.FirstOrDefault(x => x.Value == typeIdentifier); + var fd = _typeCache.FirstOrDefault(x => x.Value == typeIdentifier); if (fd.Key != null) return fd.Key; throw new KeyNotFoundException($"No type found for given identifier"); } - + /// + /// Gets the effectiveness for a single attacking type against a single defending type. + /// public float GetSingleEffectiveness(TypeIdentifier attacking, TypeIdentifier defending) => Interface.type_library_get_single_effectiveness(Handle, attacking, defending); + /// + /// Gets the effectiveness for a single attacking type against an amount of defending types. + /// This is equivalent to running on each defending type, and + /// multiplying the results with each other. + /// public float GetEffectiveness(TypeIdentifier attacking, TypeIdentifier[] defending) { var arrayPtr = defending.ArrayPtr(); return Interface.type_library_get_effectiveness(Handle, attacking, arrayPtr, (ulong)defending.Length); } + /// + /// Registers a new type in the library. + /// public TypeIdentifier RegisterType(string name) { var typeId = Interface.type_library_register_type(Handle, name.ToPtr()); - TypeCache.Add(name, typeId); + _typeCache.Add(name, typeId); return typeId; } + /// + /// Sets the effectiveness for an attacking type against a defending type. + /// public void SetEffectiveness(TypeIdentifier attacking, TypeIdentifier defending, float effectiveness) => Interface.type_library_set_effectiveness(Handle, attacking, defending, effectiveness); } diff --git a/PkmnLibRSharp/StaticData/MoveData.cs b/PkmnLibRSharp/StaticData/MoveData.cs index 8bac05b..d3a51d3 100644 --- a/PkmnLibRSharp/StaticData/MoveData.cs +++ b/PkmnLibRSharp/StaticData/MoveData.cs @@ -5,6 +5,9 @@ using Interface = PkmnLibSharp.FFI.StaticData.MoveData; namespace PkmnLibSharp.StaticData { + /// + /// The move category defines what global kind of move this move is. + /// public enum MoveCategory : byte { /// A physical move uses the physical attack stats and physical defense stats to calculate damage. @@ -17,6 +20,9 @@ namespace PkmnLibSharp.StaticData Status = 2, } + /// + /// The move target defines what kind of targets the move can touch. + /// public enum MoveTarget : byte { /// Adjacent allows a move to target any Pokemon that is either directly to the left or right of @@ -60,40 +66,87 @@ namespace PkmnLibSharp.StaticData SelfUse, } + /// + /// A move is the skill Pokémon primarily use in battle. This is the data related to that. + /// public class MoveData : HandleType { - protected MoveData(FFIHandle handle) : base(handle) {} - - public static MoveData Create(string name, TypeIdentifier moveType, MoveCategory category, byte basePower, byte accuracy, - byte baseUsages, MoveTarget target, sbyte priority, SecondaryEffect? secondaryEffect, + /// + protected MoveData(FFIHandle handle) : base(handle) + { + } + + /// + /// Instantiates a new move. + /// + public static MoveData Create(string name, TypeIdentifier moveType, MoveCategory category, byte basePower, + byte accuracy, byte baseUsages, MoveTarget target, sbyte priority, SecondaryEffect? secondaryEffect, IEnumerable flags) { var ptrArray = flags.Select(x => x.ToPtr()).ToArray(); var ptrToPtrArray = ptrArray.ArrayPtr(); - var handle = Interface.move_data_new(name.ToPtr(), moveType, category, basePower, accuracy, baseUsages, target, - priority, secondaryEffect?.Handle ?? FFIHandle.Zero, ptrToPtrArray, - (ulong)ptrArray.Length); + var handle = Interface.move_data_new(name.ToPtr(), moveType, category, basePower, accuracy, baseUsages, + target, priority, secondaryEffect?.Handle ?? FFIHandle.Zero, ptrToPtrArray, (ulong)ptrArray.Length); return Resolver.Instance.ResolveMoveData(handle.Result().Resolve()); } private string? _name; + + /// + /// The name of the move. + /// public string Name => _name ??= Interface.move_data_name(Handle).Result().PtrString()!; + private TypeIdentifier? _type; + + /// + /// The attacking type of the move. + /// public TypeIdentifier Type => _type ??= Interface.move_data_move_type(Handle); - private byte? _basePower; - public byte BasePower => _basePower ??= Interface.move_data_base_power(Handle); + private MoveCategory? _category; + + /// + /// The category of the move. + /// public MoveCategory Category => _category ??= Interface.move_data_category(Handle); + + private byte? _basePower; + + /// + /// The base power, not considering any modifiers, the move has. + /// + public byte BasePower => _basePower ??= Interface.move_data_base_power(Handle); + private byte? _accuracy; + + /// + /// The accuracy of the move in percentage. Should be 255 for moves that always hit. + /// public byte Accuracy => _accuracy ??= Interface.move_data_accuracy(Handle); private byte? _baseUsages; + + /// + /// The number of times the move can be used. This can be modified on actually learned moves using + /// PP-Ups + /// public byte BaseUsages => _baseUsages ??= Interface.move_data_base_usages(Handle); private MoveTarget? _target; + /// + /// How the move handles targets. + /// public MoveTarget Target => _target ??= Interface.move_data_target(Handle); private sbyte? _priority; + /// + /// The priority of the move. A higher priority means the move should go before other moves. + /// public sbyte Priority => _priority ??= Interface.move_data_priority(Handle); private SecondaryEffect? _secondaryEffect; + + /// + /// The optional secondary effect the move has. + /// public SecondaryEffect? SecondaryEffect { get @@ -108,6 +161,9 @@ namespace PkmnLibSharp.StaticData } } + /// + /// Checks if the move has a specific flag. + /// public bool HasFlag(string flag) { return Interface.move_data_has_flag(Handle, flag.ToPtr()) == 1; diff --git a/PkmnLibRSharp/StaticData/Nature.cs b/PkmnLibRSharp/StaticData/Nature.cs index ceb750d..e03d189 100644 --- a/PkmnLibRSharp/StaticData/Nature.cs +++ b/PkmnLibRSharp/StaticData/Nature.cs @@ -3,36 +3,59 @@ using Interface = PkmnLibSharp.FFI.StaticData.Nature; namespace PkmnLibSharp.StaticData { + /// + /// A nature is an attribute on a Pokemon that modifies the effective base stats on a Pokemon. They + /// can have an increased statistic and a decreased statistic, or be neutral. + /// public class Nature : HandleType { + /// protected Nature(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new nature. + /// public static Nature Create(Statistic increasedStat, Statistic decreasedStat, float increaseModifier = 1.1f, float decreaseModifier = 0.9f) { var handle = Interface.nature_new(increasedStat, decreasedStat, increaseModifier, decreaseModifier); return Resolver.Instance.ResolveNature(handle.Resolve()); } - + + /// + /// Instantiates a new nature that does not modify any stats. + /// public static Nature NeutralNature() { return Create(Statistic.HP, Statistic.HP, 1f, 1f); } private Statistic? _increasedStat; + + /// + /// The stat that should receive the increased modifier. + /// public Statistic IncreasedStat { get { return _increasedStat ??= Interface.nature_increased_stat(Handle); } } private Statistic? _decreasedStat; + + /// + /// The stat that should receive the decreased modifier. + /// public Statistic DecreasedStat { get { return _decreasedStat ??= Interface.nature_decreased_stat(Handle); } } + /// + /// Calculates the modifier for a given stat. If it's the increased stat, returns the increased + /// modifier, if it's the decreased stat, returns the decreased modifier. Otherwise returns 1.0 + /// public float GetStatModifier(Statistic statistic) { return Interface.nature_get_stat_modifier(Handle, statistic); diff --git a/PkmnLibRSharp/StaticData/SecondaryEffect.cs b/PkmnLibRSharp/StaticData/SecondaryEffect.cs index a0e4855..ed66a52 100644 --- a/PkmnLibRSharp/StaticData/SecondaryEffect.cs +++ b/PkmnLibRSharp/StaticData/SecondaryEffect.cs @@ -5,12 +5,19 @@ using Interface = PkmnLibSharp.FFI.StaticData.MoveData; namespace PkmnLibSharp.StaticData { + /// + /// A secondary effect is an effect on a move that happens after it hits. + /// public class SecondaryEffect : HandleType { + /// protected SecondaryEffect(FFIHandle handle) : base(handle) { } + /// + /// Instantiates a new Secondary Effect. + /// public static SecondaryEffect Create(float chance, string effectName, IReadOnlyList parameters) { var parameterPtrs = parameters.Select(x => (FFIHandleValue)x.Handle).ToArray(); @@ -23,11 +30,20 @@ namespace PkmnLibSharp.StaticData } private float? _chance; + /// + /// The chance in percentages that the effect triggers. -1 to make it always trigger. + /// public float Chance => _chance ??= Interface.secondary_effect_chance(Handle); private string? _name; + /// + /// The name of the effect. + /// public string Name => _name ??= Interface.secondary_effect_effect_name(Handle).Result().PtrString()!; + /// + /// A list of parameters for the effect. + /// public IReadOnlyList Parameters { get; private set; } = null!; } } \ No newline at end of file diff --git a/PkmnLibRSharp/StaticData/Species.cs b/PkmnLibRSharp/StaticData/Species.cs index 069c1d3..1f62f1c 100644 --- a/PkmnLibRSharp/StaticData/Species.cs +++ b/PkmnLibRSharp/StaticData/Species.cs @@ -7,14 +7,21 @@ using Interface = PkmnLibSharp.FFI.StaticData.Species; namespace PkmnLibSharp.StaticData { + /// + /// The data belonging to a Pokemon with certain characteristics. + /// public class Species : HandleType { + /// protected Species(FFIHandle handle) : base(handle) { } - public static Species Create(ushort id, string name, float genderRate, string growthRate, byte captureRate, Form defaultForm, - IReadOnlyCollection flags) + /// + /// Creates a new species. + /// + public static Species Create(ushort id, string name, float genderRate, string growthRate, byte captureRate, + Form defaultForm, IReadOnlyCollection flags) { var flagsPtrArray = flags.Select(x => x.ToPtr()).ToArray(); var handle = Interface.species_new(id, name.ToPtr(), genderRate, growthRate.ToPtr(), captureRate, @@ -25,16 +32,44 @@ namespace PkmnLibSharp.StaticData } private ushort? _id; + + /// + /// The national dex identifier of the Pokemon. + /// public ushort Id => _id ??= Interface.species_id(Handle); + private string? _name; + + /// + /// The name of the Pokemon. + /// public string Name => _name ??= Interface.species_name(Handle).PtrString()!; + private float? _genderRate; + + /// + /// The chance between 0.0 and 1.0 that a Pokemon is female. + /// public float GenderRate => _genderRate ??= Interface.species_gender_rate(Handle); + private string? _growthRate; + + /// + /// How much experience is required for a level. + /// public string GrowthRate => _growthRate ??= Interface.species_growth_rate(Handle).PtrString()!; + private byte? _captureRate; - public byte CaptureRate => _captureRate ??= Interface.species_capture_rate(Handle); + /// + /// How hard it is to capture a Pokemon. 255 means this will be always caught, 0 means this is + /// uncatchable. + /// + public byte CaptureRate => _captureRate ??= Interface.species_capture_rate(Handle); + + /// + /// Gets the form the Pokemon will have by default, if no other form is specified. + /// public Form DefaultForm { get @@ -44,7 +79,11 @@ namespace PkmnLibSharp.StaticData } } - private Dictionary _forms = new(StringComparer.InvariantCultureIgnoreCase); + private readonly Dictionary _forms = new(StringComparer.InvariantCultureIgnoreCase); + + /// + /// Gets a form by name. + /// public bool TryGetForm(string formName, [NotNullWhen(true)] out Form? form) { if (_forms.TryGetValue(formName, out form)) @@ -61,12 +100,19 @@ namespace PkmnLibSharp.StaticData return true; } + /// + /// Adds a new form to the species. + /// + /// public void AddForm(Form form) { Interface.species_add_form(Handle, form.Name.ToPtr(), form.Handle).Result(); _forms.Add(form.Name, form); } + /// + /// Gets a random gender, returning a value based on the species gender ratio. + /// public Gender GetRandomGender(ulong seed) => Interface.species_get_random_gender(Handle, seed); } } \ No newline at end of file diff --git a/PkmnLibRSharp/StaticData/StaticStatisticSet.cs b/PkmnLibRSharp/StaticData/StaticStatisticSet.cs index b80e7e2..9ceb25c 100644 --- a/PkmnLibRSharp/StaticData/StaticStatisticSet.cs +++ b/PkmnLibRSharp/StaticData/StaticStatisticSet.cs @@ -5,13 +5,24 @@ using Interface = PkmnLibSharp.FFI.StaticData.StaticStatisticSet; namespace PkmnLibSharp.StaticData { + /// + /// A collection of statistics that can not be modified after creation. + /// + /// + /// The integer type that this statistic set will use. This type must be one of the following: ushort + /// public class StaticStatisticSet : HandleType where T : struct, IConvertible { + /// protected StaticStatisticSet(FFIHandle handle) : base(handle) { } - public static StaticStatisticSet Create(T hp, T attack, T defense, T specialAttack, T specialDefense, T speed) + /// + /// Create a new static statistic set. + /// + public static StaticStatisticSet Create(T hp, T attack, T defense, T specialAttack, T specialDefense, + T speed) { var handle = typeof(T) switch { @@ -23,6 +34,9 @@ namespace PkmnLibSharp.StaticData return Resolver.Instance.ResolveStaticStatisticSet(handle.Resolve()); } + /// + /// Get the value of a specific stat + /// [PublicAPI] public T GetStatistic(Statistic statistic) { @@ -73,22 +87,45 @@ namespace PkmnLibSharp.StaticData } private T? _hp; + + /// + /// The health point stat value. + /// public T HP => GetStatistic(Statistic.HP); private T? _attack; + + /// + /// The physical attack stat value. + /// public T Attack => GetStatistic(Statistic.Attack); private T? _defense; + + /// + /// The physical defense stat value. + /// public T Defense => GetStatistic(Statistic.Defense); private T? _specialAttack; + + /// + /// The special attack stat value. + /// public T SpecialAttack => GetStatistic(Statistic.SpecialAttack); private T? _specialDefense; + + /// + /// The special defense stat value. + /// public T SpecialDefense => GetStatistic(Statistic.SpecialDefense); private T? _speed; + + /// + /// The speed stat value. + /// public T Speed => GetStatistic(Statistic.Speed); - } } \ No newline at end of file diff --git a/PkmnLibRSharp/StaticData/Statistic.cs b/PkmnLibRSharp/StaticData/Statistic.cs index 2630d91..51252ca 100644 --- a/PkmnLibRSharp/StaticData/Statistic.cs +++ b/PkmnLibRSharp/StaticData/Statistic.cs @@ -1,12 +1,38 @@ namespace PkmnLibSharp.StaticData { + /// + /// Stats are numerical values on Pokemon that are used in battle. + /// public enum Statistic : byte { + /// + /// Health Points determine how much damage a Pokemon can receive before fainting. + /// HP = 0, + + /// + /// Attack determines how much damage a Pokemon deals when using a physical attack. + /// Attack = 1, + + /// + /// Defense determines how much damage a Pokemon receives when it is hit by a physical attack. + /// Defense = 2, + + /// + /// Special Attack determines how much damage a Pokemon deals when using a special attack. + /// SpecialAttack = 3, + + /// + /// Special Defense determines how much damage a Pokemon receives when it is hit by a special attack. + /// SpecialDefense = 4, + + /// + /// Speed determines the order that a Pokemon can act in battle. + /// Speed = 5, } } \ No newline at end of file diff --git a/PkmnLibRSharp/StaticData/StatisticSet.cs b/PkmnLibRSharp/StaticData/StatisticSet.cs index 556a34a..32a4a56 100644 --- a/PkmnLibRSharp/StaticData/StatisticSet.cs +++ b/PkmnLibRSharp/StaticData/StatisticSet.cs @@ -5,12 +5,23 @@ using Interface = PkmnLibSharp.FFI.StaticData.StatisticSet; namespace PkmnLibSharp.StaticData { + /// + /// A collection of every individual stat. This set can hold any value that is valid for its integer + /// type, and can be modified at will. + /// + /// + /// The integer type that this statistic set will use. This type must be one of the following: byte, sbyte, uint. + /// public class StatisticSet : HandleType where T : struct, IConvertible { + /// protected StatisticSet(FFIHandle handle) : base(handle) { } + /// + /// Creates a new statistic set with given stats. + /// public static StatisticSet Create(T hp, T attack, T defense, T specialAttack, T specialDefense, T speed) { var handle = typeof(T) switch @@ -29,6 +40,9 @@ namespace PkmnLibSharp.StaticData return Resolver.Instance.ResolveStatisticSet(handle.Resolve()); } + /// + /// Get the value of a specific stat + /// [PublicAPI] public T GetStatistic(Statistic statistic) { @@ -42,6 +56,9 @@ namespace PkmnLibSharp.StaticData return (T)p; } + /// + /// Modify the value of a specific stat. + /// [PublicAPI] public void SetStatistic(Statistic statistic, T value) { @@ -53,36 +70,54 @@ namespace PkmnLibSharp.StaticData else throw new ArgumentOutOfRangeException(); } + /// + /// The health point stat value. + /// public T HP { get => GetStatistic(Statistic.HP); set => SetStatistic(Statistic.HP, value); } + /// + /// The physical attack stat value. + /// public T Attack { get => GetStatistic(Statistic.Attack); set => SetStatistic(Statistic.Attack, value); } + /// + /// The physical defense stat value. + /// public T Defense { get => GetStatistic(Statistic.Defense); set => SetStatistic(Statistic.Defense, value); } + /// + /// The special attack stat value. + /// public T SpecialAttack { get => GetStatistic(Statistic.SpecialAttack); set => SetStatistic(Statistic.SpecialAttack, value); } + /// + /// The special defense stat value. + /// public T SpecialDefense { get => GetStatistic(Statistic.SpecialDefense); set => SetStatistic(Statistic.SpecialDefense, value); } + /// + /// The speed stat value. + /// public T Speed { get => GetStatistic(Statistic.Speed); diff --git a/PkmnLibRSharp/StaticData/TypeIdentifier.cs b/PkmnLibRSharp/StaticData/TypeIdentifier.cs index c61cb08..f9de6df 100644 --- a/PkmnLibRSharp/StaticData/TypeIdentifier.cs +++ b/PkmnLibRSharp/StaticData/TypeIdentifier.cs @@ -1,43 +1,61 @@ +using System; using System.Runtime.InteropServices; namespace PkmnLibSharp.StaticData { + /// + /// An identifier for a type. This is stored as a single byte internally, but is represented as a struct so that + /// we can use the type system to ensure that we don't accidentally mix up type identifiers with other bytes. + /// [StructLayout(LayoutKind.Explicit)] - public readonly struct TypeIdentifier + public readonly struct TypeIdentifier : IEquatable { // ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable [FieldOffset(0)] private readonly byte _identifier; + /// + /// Creates a new type identifier. + /// public TypeIdentifier(byte b) { _identifier = b; } + /// public bool Equals(TypeIdentifier other) { return _identifier == other._identifier; } + /// public override bool Equals(object? obj) { return obj is TypeIdentifier other && Equals(other); } + /// public override int GetHashCode() { return _identifier.GetHashCode(); } + /// + /// Equality operator for type identifiers. + /// public static bool operator ==(TypeIdentifier left, TypeIdentifier right) { return left.Equals(right); } + /// + /// Inequality operator for type identifiers. + /// public static bool operator !=(TypeIdentifier left, TypeIdentifier right) { return !left.Equals(right); } + /// public override string ToString() { return $"Type({_identifier})"; diff --git a/PkmnLibRSharp/Utils/CachedExternArray.cs b/PkmnLibRSharp/Utils/CachedExternArray.cs index d8dcae9..322fef0 100644 --- a/PkmnLibRSharp/Utils/CachedExternArray.cs +++ b/PkmnLibRSharp/Utils/CachedExternArray.cs @@ -5,7 +5,7 @@ using System.Runtime.CompilerServices; namespace PkmnLibSharp.Utils { - public sealed class CachedExternArray : IReadOnlyList + internal sealed class CachedExternArray : IReadOnlyList where T: class { private readonly T?[] _array; @@ -50,7 +50,7 @@ namespace PkmnLibSharp.Utils } - public class CachedExternValueArray : IReadOnlyList + internal class CachedExternValueArray : IReadOnlyList where T: struct { private readonly T?[] _array; diff --git a/PkmnLibRSharp/Utils/ExternValueArray.cs b/PkmnLibRSharp/Utils/ExternValueArray.cs index d64a0a8..bf1b5d4 100644 --- a/PkmnLibRSharp/Utils/ExternValueArray.cs +++ b/PkmnLibRSharp/Utils/ExternValueArray.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; namespace PkmnLibSharp.Utils { - public class ExternValueArray : IReadOnlyList where T : struct + internal class ExternValueArray : IReadOnlyList { private readonly Func _getLength; private readonly Func _getItem; diff --git a/PkmnLibRSharp/Utils/FFIHandle.cs b/PkmnLibRSharp/Utils/FFIHandle.cs index 2a43d6b..e29a222 100644 --- a/PkmnLibRSharp/Utils/FFIHandle.cs +++ b/PkmnLibRSharp/Utils/FFIHandle.cs @@ -60,6 +60,9 @@ namespace PkmnLibSharp.Utils } } + /// + /// A handle to a native object. + /// public struct FFIHandle { internal FFIHandle(ulong handle, FFIHandleReference handleReference) @@ -68,7 +71,11 @@ namespace PkmnLibSharp.Utils _handleReference = handleReference; } - public ulong Handle { get; } + internal ulong Handle { get; } + + /// + /// A handle with a value of 0, which is the null handle. + /// public static FFIHandle Zero => new(0, null!); /// diff --git a/PkmnLibRSharp/Utils/HandleType.cs b/PkmnLibRSharp/Utils/HandleType.cs index db93292..138e3de 100644 --- a/PkmnLibRSharp/Utils/HandleType.cs +++ b/PkmnLibRSharp/Utils/HandleType.cs @@ -1,12 +1,22 @@ +using JetBrains.Annotations; + namespace PkmnLibSharp.Utils { + /// + /// A basic type that holds a handle to a native object. + /// + [UsedImplicitly(ImplicitUseTargetFlags.Default | ImplicitUseTargetFlags.WithInheritors)] public abstract class HandleType { + /// protected internal HandleType(FFIHandle handle) { Handle = handle; } + /// + /// The internal handle to the native object. + /// protected internal FFIHandle Handle { get; } } } \ No newline at end of file diff --git a/PkmnLibRSharp/Utils/Resolver.cs b/PkmnLibRSharp/Utils/Resolver.cs index 1d948bc..7479401 100644 --- a/PkmnLibRSharp/Utils/Resolver.cs +++ b/PkmnLibRSharp/Utils/Resolver.cs @@ -3,17 +3,31 @@ using System.Collections.Generic; using System.Reflection; using PkmnLibSharp.DynamicData; using PkmnLibSharp.DynamicData.Libraries; -using PkmnLibSharp.FFI; using PkmnLibSharp.StaticData; using PkmnLibSharp.StaticData.Libraries; namespace PkmnLibSharp.Utils { + /// + /// This class is used to resolve FFIHandles to their respective classes. We use this so we can handle inheritance + /// in our objects. By overriding a method in this class, we can return a different object than the default throughout + /// the library. + /// + /// This class is a singleton, so you can replace the default resolver with your own by setting the Instance property. + /// public class Resolver { + /// + /// The global resolver instance. This is used throughout the library to resolve FFIHandles to their respective + /// classes. + /// public static Resolver Instance { get; set; } = new(); + private static readonly Dictionary Instances = new(); + /// + /// Either returns an existing instance of the given type, or creates a new one and returns it. + /// protected static T GetOrCreateInstance(FFIHandle handle) { if (!Instances.TryGetValue(handle, out var instance)) @@ -28,79 +42,177 @@ namespace PkmnLibSharp.Utils return (T)instance!; } + /// + /// Resolve an effect parameter from the given handle. + /// public virtual EffectParameter ResolveEffectParameter(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve a move effect from the given handle. + /// public virtual Ability ResolveAbility(FFIHandle handle) => GetOrCreateInstance(handle); + + /// + /// Resolve a form from the given handle. + /// public virtual Form ResolveForm(FFIHandle handle) => GetOrCreateInstance
(handle); + /// + /// Resolve a static statistic set from the given handle. + /// public virtual StaticStatisticSet ResolveStaticStatisticSet(FFIHandle handle) where T : struct, IConvertible => GetOrCreateInstance>(handle); + /// + /// Resolve a statistic set from the given handle. + /// public virtual StatisticSet ResolveStatisticSet(FFIHandle handle) where T : struct, IConvertible => GetOrCreateInstance>(handle); + /// + /// Resolve a learnable moves object from the given handle. + /// public virtual LearnableMoves ResolveLearnableMoves(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve an item object from the given handle. + /// public virtual Item ResolveItem(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve a secondary effect object from the given handle. + /// public virtual SecondaryEffect ResolveSecondaryEffect(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve a move data object from the given handle. + /// public virtual MoveData ResolveMoveData(FFIHandle handle) => GetOrCreateInstance(handle); + + /// + /// Resolve an nature from the given handle. + /// public virtual Nature ResolveNature(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve a species object from the given handle. + /// public virtual Species ResolveSpecies(FFIHandle handle) => GetOrCreateInstance(handle); - public virtual AbilityLibrary ResolveAbilityLibrary(FFIHandle handle) => - GetOrCreateInstance(handle); - - public virtual ItemLibrary ResolveItemLibrary(FFIHandle handle) => GetOrCreateInstance(handle); - + /// + /// Resolve a growthrate object from the given handle. + /// public virtual LookupGrowthRate ResolveLookupGrowthRate(FFIHandle ptr) => GetOrCreateInstance(ptr); + /// + /// Resolve an ability library object from the given handle. + /// + public virtual AbilityLibrary ResolveAbilityLibrary(FFIHandle handle) => + GetOrCreateInstance(handle); + + /// + /// Resolve an item library object from the given handle. + /// + public virtual ItemLibrary ResolveItemLibrary(FFIHandle handle) => GetOrCreateInstance(handle); + + /// + /// Resolve a growthrate library object from the given handle. + /// public virtual GrowthRateLibrary ResolveGrowthRateLibrary(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve a move library object from the given handle. + /// public virtual MoveLibrary ResolveMoveLibrary(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve a nature library object from the given handle. + /// public virtual NatureLibrary ResolveNatureLibrary(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve a species library object from the given handle. + /// public virtual SpeciesLibrary ResolveSpeciesLibrary(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve a library settings object from the given handle. + /// public virtual LibrarySettings ResolveLibrarySettings(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve a type library object from the given handle. + /// public virtual TypeLibrary ResolveTypeLibrary(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve a static data object from the given handle. + /// public virtual StaticData.Libraries.StaticData ResolveStaticData(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve a learned move object from the given handle. + /// public virtual LearnedMove ResolveLearnedMove(FFIHandle resolve) => GetOrCreateInstance(resolve); - public virtual Gen7BattleStatCalculator ResolveGen7BattleStatCalculator(FFIHandle handle) => + /// + /// Resolve a battle stat calculator object from the given handle. + /// + public virtual BattleStatCalculator ResolveBattleStatCalculator(FFIHandle handle) => GetOrCreateInstance(handle); - public virtual Gen7DamageLibrary ResolveGen7DamageLibrary(FFIHandle handle) => + /// + /// Resolve a damage library object from the given handle. + /// + public virtual DamageLibrary ResolveDamageLibrary(FFIHandle handle) => GetOrCreateInstance(handle); - public virtual Gen7MiscLibrary ResolveGen7MiscLibrary(FFIHandle handle) => - GetOrCreateInstance(handle); + /// + /// Resolve a misc library object from the given handle. + /// + public virtual MiscLibrary ResolveMiscLibrary(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve an empty script resolver object from the given handle. + /// public virtual EmptyScriptResolver ResolveEmptyScriptResolver(FFIHandle handle) => GetOrCreateInstance(handle); + /// + /// Resolve a script resolver object from the given handle. + /// #if WASM - public virtual WasmScriptResolver ResolveWasmScriptResolver(FFIHandle handle) => + public virtual ScriptResolver ResolveScriptResolver(FFIHandle handle) => GetOrCreateInstance(handle); +#else + public virtual ScriptResolver ResolveScriptResolver(FFIHandle handle) => ResolveEmptyScriptResolver(handle); #endif - public DynamicLibrary ResolveDynamicLibrary(FFIHandle resolve) => GetOrCreateInstance(resolve); + + /// + /// Resolve a dynamic library object from the given handle. + /// + public virtual DynamicLibrary ResolveDynamicLibrary(FFIHandle resolve) => + GetOrCreateInstance(resolve); - public Pokemon ResolvePokemon(FFIHandle resolve) => GetOrCreateInstance(resolve); + /// + /// Resolve a pokemon object from the given handle. + /// + public virtual Pokemon ResolvePokemon(FFIHandle resolve) => GetOrCreateInstance(resolve); + + /// + /// Resolve a pokemon party object from the given handle. + /// + public virtual PokemonParty ResolvePokemonParty(FFIHandle resolve) => + GetOrCreateInstance(resolve); } } \ No newline at end of file diff --git a/PkmnLibRSharp/libpkmn_lib.so b/PkmnLibRSharp/libpkmn_lib.so index 240b560..50de661 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:50bf8b12e15aa01f0de2a9a069d88a292210d5910582b6c486e3e2895376175d -size 131739760 +oid sha256:6749de907ce0a741000bd0bffcd7deaea024b558bc81f3eaf8870b6f9c124954 +size 131762488 diff --git a/PkmnLibRSharpTests/DynamicData/PokemonTests.cs b/PkmnLibRSharpTests/DynamicData/PokemonTests.cs index 6ec7821..aa3ba68 100644 --- a/PkmnLibRSharpTests/DynamicData/PokemonTests.cs +++ b/PkmnLibRSharpTests/DynamicData/PokemonTests.cs @@ -72,7 +72,7 @@ namespace PkmnLibRSharpTests.DynamicData { var library = GetLibrary(); var pokemon = new PokemonBuilder(library, "testSpecies", 100).WithIdentifier(1000).Build(); - Assert.AreEqual(1000, pokemon.UniqueIdentifier); + Assert.AreEqual(1000, pokemon.PersonalityValue); } [Test]