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