using PkmnLibSharp.DynamicData.Libraries; using PkmnLibSharp.StaticData; using PkmnLibSharp.Utils; using Form = PkmnLibSharp.StaticData.Form; using Interface = PkmnLibSharp.FFI.DynamicData.Pokemon; using Item = PkmnLibSharp.StaticData.Item; using Species = PkmnLibSharp.StaticData.Species; namespace PkmnLibSharp.DynamicData { public class Pokemon : ExternPointer { public Pokemon(DynamicLibrary dynamicLibrary, Species species, Form form, bool hiddenAbility, byte abilityIndex, LevelInt level, uint uid, Gender gender, byte coloring, string nature) : base( Interface.pokemon_new(dynamicLibrary.Ptr, species.Ptr, form.Ptr, hiddenAbility.ForeignBool(), abilityIndex, level, uid, gender, coloring, nature.ToPtr()), true) { } /// /// The library data the Pokemon uses. /// public DynamicLibrary Library => Cache.DynamicLibrary ??= new DynamicLibrary(Interface.pokemon_library(Ptr)); /// /// The species of the Pokemon. /// public Species Species => new(Interface.pokemon_species(Ptr)); /// /// The form of the Pokemon. /// public Form Form => new(Interface.pokemon_form(Ptr)); /// /// The species that should be displayed to the user. This handles stuff like the Illusion ability. /// public Species DisplaySpecies => new(Interface.pokemon_display_species(Ptr)); /// /// The form that should be displayed to the user. This handles stuff like the Illusion ability. /// public Form DisplayForm => new(Interface.pokemon_display_form(Ptr)); public LevelInt Level => Interface.pokemon_level(Ptr); public uint Experience => Interface.pokemon_experience(Ptr); public uint UniqueIdentifier => Interface.pokemon_unique_identifier(Ptr); public Gender Gender => Interface.pokemon_gender(Ptr); public byte Coloring => Interface.pokemon_coloring(Ptr); public bool IsShiny => Coloring == 1; public Item? HeldItem { get { var ptr = Interface.pokemon_held_item(Ptr); return ptr.IsNull ? null : new Item(ptr); } } public bool HasHeldItem(string name) => Interface.pokemon_has_held_item(Ptr, name.ToPtr()) == 1; public void SetHeldItem(Item? item) { if (item == null) RemoveHeldItem(); else Interface.pokemon_set_held_item(Ptr, item.Ptr); } public void RemoveHeldItem() => Interface.pokemon_remove_held_item(Ptr); public bool ConsumeHeldItem() => Interface.pokemon_consume_held_item(Ptr) == 1; public uint CurrentHealth => Interface.pokemon_current_health(Ptr); public uint MaxHealth => Interface.pokemon_max_health(Ptr); public float Weight => Interface.pokemon_weight(Ptr); public float Height => Interface.pokemon_height(Ptr); public string? Nickname => Interface.pokemon_nickname(Ptr).PtrString(); public bool HasHiddenAbility => Interface.pokemon_real_ability_is_hidden(Ptr) == 1; public byte AbilityIndex => Interface.pokemon_real_ability_index(Ptr); public ExternValueArray Types => Cache.Types ??= new ExternValueArray(() => Interface.pokemon_types_length(Ptr), arg => Interface.pokemon_types_get(Ptr, arg)); public LearnedMove? LearnedMove(ulong index) { var ptr = Interface.pokemon_learned_move_get(Ptr, index); return ptr.IsNull ? null : new LearnedMove(ptr, false); } public StatisticSet FlatStats => Cache.FlatStats ??= new StatisticSet(Interface.pokemon_flat_stats(Ptr), false); public StatisticSet BoostedStats => Cache.BoostedStats ??= new StatisticSet(Interface.pokemon_boosted_stats(Ptr), false); public sbyte GetStatBoost(Statistic statistic) => Interface.pokemon_get_stat_boost(Ptr, statistic); public byte GetIndividualValue(Statistic statistic) => Interface.pokemon_get_individual_value(Ptr, statistic); public byte GetEffortValue(Statistic statistic) => Interface.pokemon_get_effort_value(Ptr, statistic); public void SetIndividualValue(Statistic statistic, byte value) => Interface.pokemon_set_individual_value(Ptr, statistic, value); public void SetEffortValue(Statistic statistic, byte value) => Interface.pokemon_set_effort_value(Ptr, statistic, value); // TODO: Battle getter public byte BattleSideIndex => Interface.pokemon_get_battle_side_index(Ptr); public byte BattleIndex => Interface.pokemon_get_battle_index(Ptr); public bool IsAbilityOverriden => Interface.pokemon_is_ability_overriden(Ptr) == 1; public Ability ActiveAbility => new(Interface.pokemon_active_ability(Ptr)); public bool AllowedExperienceGain => Interface.pokemon_allowed_experience_gain(Ptr) == 1; public Nature Nature => new(Interface.pokemon_nature(Ptr)); public void RecalculateFlatStats() => Interface.pokemon_recalculate_flat_stats(Ptr); public void RecalculateBoostedStats() => Interface.pokemon_recalculate_boosted_stats(Ptr); public void ChangeSpecies(Species species, Form form) => Interface.pokemon_change_species(Ptr, species.Ptr, form.Ptr); public void ChangeForm(Form form) => Interface.pokemon_change_form(Ptr, form.Ptr); public bool IsUsable => Interface.pokemon_is_usable(Ptr) == 1; public bool IsFainted => Interface.pokemon_is_fainted(Ptr) == 1; public bool IsOnBattleField => Interface.pokemon_is_on_battlefield(Ptr) == 1; public void Damage(uint amount, DamageSource source) => Interface.pokemon_damage(Ptr, amount, source); public bool Heal(uint amount, bool allowRevive) => Interface.pokemon_heal(Ptr, amount, allowRevive.ForeignBool()) == 1; public void LearnMove(string moveName, MoveLearnMethod learnMethod) => Interface.pokemon_learn_move(Ptr, moveName.ToPtr(), learnMethod); public void ClearStatus() => Interface.pokemon_clear_status(Ptr); public class CacheData { public DynamicLibrary? DynamicLibrary { get; set; } public ExternValueArray? Types { get; set; } public StatisticSet? FlatStats { get; set; } public StatisticSet? BoostedStats { get; set; } } protected override CacheData CreateCache() => new(); protected override void Destructor() => Interface.pokemon_drop(Ptr); } }