172 lines
6.1 KiB
C#
172 lines
6.1 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using PkmnLibSharp.Utils;
|
|
using Interface = PkmnLibSharp.FFI.StaticData.MoveData;
|
|
|
|
namespace PkmnLibSharp.StaticData
|
|
{
|
|
/// <summary>
|
|
/// The move category defines what global kind of move this move is.
|
|
/// </summary>
|
|
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,
|
|
}
|
|
|
|
/// <summary>
|
|
/// The move target defines what kind of targets the move can touch.
|
|
/// </summary>
|
|
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,
|
|
}
|
|
|
|
/// <summary>
|
|
/// A move is the skill Pokémon primarily use in battle. This is the data related to that.
|
|
/// </summary>
|
|
public class MoveData : HandleType
|
|
{
|
|
/// <inheritdoc cref="MoveData"/>
|
|
protected MoveData(FFIHandle handle) : base(handle)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Instantiates a new move.
|
|
/// </summary>
|
|
public static MoveData Create(string name, TypeIdentifier moveType, MoveCategory category, byte basePower,
|
|
byte accuracy, byte baseUsages, MoveTarget target, sbyte priority, SecondaryEffect? secondaryEffect,
|
|
IEnumerable<string> 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);
|
|
return Resolver.Instance.ResolveMoveData(handle.Result().Resolve());
|
|
}
|
|
|
|
private string? _name;
|
|
|
|
/// <summary>
|
|
/// The name of the move.
|
|
/// </summary>
|
|
public string Name => _name ??= Interface.move_data_name(Handle).Result().PtrString()!;
|
|
|
|
private TypeIdentifier? _type;
|
|
|
|
/// <summary>
|
|
/// The attacking type of the move.
|
|
/// </summary>
|
|
public TypeIdentifier Type => _type ??= Interface.move_data_move_type(Handle);
|
|
|
|
private MoveCategory? _category;
|
|
|
|
/// <summary>
|
|
/// The category of the move.
|
|
/// </summary>
|
|
public MoveCategory Category => _category ??= Interface.move_data_category(Handle);
|
|
|
|
private byte? _basePower;
|
|
|
|
/// <summary>
|
|
/// The base power, not considering any modifiers, the move has.
|
|
/// </summary>
|
|
public byte BasePower => _basePower ??= Interface.move_data_base_power(Handle);
|
|
|
|
private byte? _accuracy;
|
|
|
|
/// <summary>
|
|
/// The accuracy of the move in percentage. Should be 255 for moves that always hit.
|
|
/// </summary>
|
|
public byte Accuracy => _accuracy ??= Interface.move_data_accuracy(Handle);
|
|
private byte? _baseUsages;
|
|
|
|
/// <summary>
|
|
/// The number of times the move can be used. This can be modified on actually learned moves using
|
|
/// PP-Ups
|
|
/// </summary>
|
|
public byte BaseUsages => _baseUsages ??= Interface.move_data_base_usages(Handle);
|
|
private MoveTarget? _target;
|
|
/// <summary>
|
|
/// How the move handles targets.
|
|
/// </summary>
|
|
public MoveTarget Target => _target ??= Interface.move_data_target(Handle);
|
|
private sbyte? _priority;
|
|
/// <summary>
|
|
/// The priority of the move. A higher priority means the move should go before other moves.
|
|
/// </summary>
|
|
public sbyte Priority => _priority ??= Interface.move_data_priority(Handle);
|
|
|
|
private SecondaryEffect? _secondaryEffect;
|
|
|
|
/// <summary>
|
|
/// The optional secondary effect the move has.
|
|
/// </summary>
|
|
public SecondaryEffect? SecondaryEffect
|
|
{
|
|
get
|
|
{
|
|
if (_secondaryEffect != null)
|
|
return _secondaryEffect;
|
|
var effect = Interface.move_data_secondary_effect(Handle);
|
|
if (effect.Handle == 0)
|
|
return null;
|
|
_secondaryEffect = Resolver.Instance.ResolveSecondaryEffect(effect.Resolve());
|
|
return _secondaryEffect;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if the move has a specific flag.
|
|
/// </summary>
|
|
public bool HasFlag(string flag)
|
|
{
|
|
return Interface.move_data_has_flag(Handle, flag.ToPtr()) == 1;
|
|
}
|
|
}
|
|
} |