using System.Collections.Immutable;
using PkmnLib.Static.Utils;
namespace PkmnLib.Static.Moves;
///
/// The move category defines what global kind of move this move is.
///
public enum MoveCategory
{
///
/// 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,
}
///
/// The move target defines what kind of targets the move can touch.
///
public enum MoveTarget
{
///
/// Adjacent allows a move to target any Pokémon 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 Pokémon that is directly to the left or right of
/// the user.
///
AdjacentAlly,
///
/// AdjacentAllySelf allows a move to target any Pokémon that is either directly to the left or
/// right of the user, or the user itself.
///
AdjacentAllySelf,
///
/// AdjacentOpponent allows a move to target any Pokémon 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 Pokémon on the same side as the user.
///
AllAlly,
///
/// AllOpponent targets all Pokémon on an opposing side from the user.
///
AllOpponent,
///
/// Any allows a move to target a single Pokémon, in any position.
///
Any,
///
/// RandomOpponent allows a move to target a single Pokémon, in a random position.
///
RandomOpponent,
///
/// SelfUse makes the move target the user itself.
///
SelfUse,
}
///
/// A move is the skill Pokémon primarily use in battle. This is the data related to that.
///
public interface IMoveData : INamedValue
{
///
/// The attacking type of the move.
///
TypeIdentifier MoveType { get; }
///
/// The category of the move.
///
MoveCategory Category { get; }
///
/// The base power, not considering any modifiers, the move has.
///
byte BasePower { get; }
///
/// The accuracy of the move in percentage. Should be 255 for moves that always hit.
///
byte Accuracy { get; }
///
/// The number of times the move can be used. This can be modified on actually learned moves using PP-Ups
///
byte BaseUsages { get; }
///
/// How the move handles targets.
///
MoveTarget Target { get; }
///
/// The priority of the move. A higher priority means the move should go before other moves.
///
sbyte Priority { get; }
///
/// The optional secondary effect the move has.
///
ISecondaryEffect? SecondaryEffect { get; }
///
/// Arbitrary flags that can be applied to the move.
///
bool HasFlag(string key);
}
///
public class MoveDataImpl : IMoveData
{
///
public MoveDataImpl(StringKey name, TypeIdentifier moveType, MoveCategory category, byte basePower, byte accuracy,
byte baseUsages, MoveTarget target, sbyte priority, ISecondaryEffect? secondaryEffect,
IEnumerable flags)
{
Name = name;
MoveType = moveType;
Category = category;
BasePower = basePower;
Accuracy = accuracy;
BaseUsages = baseUsages;
Target = target;
Priority = priority;
SecondaryEffect = secondaryEffect;
_flags = [..flags];
}
///
public StringKey Name { get; }
///
public TypeIdentifier MoveType { get; }
///
public MoveCategory Category { get; }
///
public byte BasePower { get; }
///
public byte Accuracy { get; }
///
public byte BaseUsages { get; }
///
public MoveTarget Target { get; }
///
public sbyte Priority { get; }
///
public ISecondaryEffect? SecondaryEffect { get; }
private readonly ImmutableHashSet _flags;
///
public bool HasFlag(string key) => _flags.Contains(key);
}