using System; using System.Collections.Generic; using System.Linq; using PkmnLibSharp.Utils; using Interface = PkmnLibSharp.FFI.StaticData.MoveData; namespace PkmnLibSharp.StaticData { public enum MoveCategory : byte { /// A physical move uses the physical attack stats and physical defense stats to calculate damage. Physical = 0, /// A special move uses the special attack stats and special defense stats to calculate damage. Special = 1, /// A status move does not do damage, and only runs a secondary effect. Status = 2, } public enum MoveTarget : byte { /// Adjacent allows a move to target any Pokemon that is either directly to the left or right of /// the user, opposed to the user, or left or right of the slot that is opposing the user. Adjacent = 0, /// AdjacentAlly allows a move to target any Pokemon that is directly to the left or right of /// the user. AdjacentAlly, /// AdjacentAllySelf allows a move to target any Pokemon that is either directly to the left or /// right of the user, or the user itself. AdjacentAllySelf, /// AdjacentOpponent allows a move to target any Pokemon that is either the opponent, or directly /// to the left or right of it. AdjacentOpponent, /// All makes the move target everything on the field. All, /// AllAdjacent makes the move target everything adjacent on the field. AllAdjacent, /// AllAdjacentOpponent makes the move target everything adjacent to the opponent, and the opponent. AllAdjacentOpponent, /// AllAlly targets all Pokemon on the same side as the user. AllAlly, /// AllOpponent targets all Pokemon on an opposing side from the user. AllOpponent, /// Any allows a move to target a single Pokemon, in any position. Any, /// RandomOpponent allows a move to target a single Pokemon, in a random position. RandomOpponent, /// SelfUse makes the move target the user itself. SelfUse, } public class MoveData : ExternPointer { public class CacheData { public string? Name { get; internal set; } public TypeIdentifier? Type { get; internal set; } public MoveCategory? Category { get; internal set; } public byte? BasePower { get; internal set; } public byte? Accuracy { get; internal set; } public byte? BaseUsages { get; internal set; } public MoveTarget? Target { get; internal set; } public sbyte? Priority { get; internal set; } public SecondaryEffect? SecondaryEffect { get; internal set; } } public MoveData(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 ptr = Interface.move_data_new(name.ToPtr(), moveType, category, basePower, accuracy, baseUsages, target, priority, secondaryEffect?.TakeOwnershipAndInvalidate() ?? IntPtr.Zero, ptrToPtrArray, (ulong)ptrArray.Length); InitializePointer(ptr, true); } public string Name => Cache.Name ??= Interface.move_data_name(Ptr).PtrString()!; public TypeIdentifier Type => Cache.Type ??= Interface.move_data_move_type(Ptr); public byte BasePower => Cache.BasePower ??= Interface.move_data_base_power(Ptr); public MoveCategory Category => Cache.Category ??= Interface.move_data_category(Ptr); public byte Accuracy => Cache.Accuracy ??= Interface.move_data_accuracy(Ptr); public byte BaseUsages => Cache.BaseUsages ??= Interface.move_data_base_usages(Ptr); public MoveTarget Target => Cache.Target ??= Interface.move_data_target(Ptr); public sbyte Priority => Cache.Priority ??= Interface.move_data_priority(Ptr); public SecondaryEffect? SecondaryEffect { get { if (Cache.SecondaryEffect != null) return Cache.SecondaryEffect; var effect = Interface.move_data_secondary_effect(Ptr); if (effect == IntPtr.Zero) return null; Cache.SecondaryEffect = new SecondaryEffect(effect, false); return Cache.SecondaryEffect; } } public bool HasFlag(string flag) { return Interface.move_data_has_flag(Ptr, flag.ToPtr()) == 1; } protected override CacheData CreateCache() { return new CacheData(); } protected override void Destructor() { Interface.move_data_drop(Ptr); } } }