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); }