PkmnLib_rs/src/static_data/moves/move_data.rs

166 lines
5.7 KiB
Rust
Executable File

use hashbrown::HashSet;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::static_data::{SecondaryEffect, TypeIdentifier};
use crate::StringKey;
/// The move category defines what global kind of move this move is.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
#[repr(u8)]
pub 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.
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[repr(u8)]
pub enum MoveTarget {
/// 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.
#[default]
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.
#[cfg_attr(feature = "serde", serde(rename = "Self"))]
SelfUse,
}
/// A move is the skill Pokémon primarily use in battle. This is the data related to that.
#[derive(PartialEq, Debug)]
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
pub struct MoveData {
/// The name of the move.
name: StringKey,
/// The attacking type of the move.
move_type: TypeIdentifier,
/// The category of the move.
category: MoveCategory,
/// The base power, not considering any modifiers, the move has.
base_power: u8,
/// The accuracy of the move in percentage. Should be 255 for moves that always hit.
accuracy: u8,
/// The number of times the move can be used. This can be modified on actually learned moves using
/// PP-Ups
base_usages: u8,
/// How the move handles targets.
target: MoveTarget,
/// The priority of the move. A higher priority means the move should go before other moves.
priority: i8,
/// The optional secondary effect the move has.
secondary_effect: Option<SecondaryEffect>,
/// Arbitrary flags that can be applied to the move.
flags: HashSet<StringKey>,
}
impl MoveData {
/// Instantiates a new move.
pub fn new(
name: &StringKey,
move_type: TypeIdentifier,
category: MoveCategory,
base_power: u8,
accuracy: u8,
base_usages: u8,
target: MoveTarget,
priority: i8,
secondary_effect: Option<SecondaryEffect>,
flags: HashSet<StringKey>,
) -> MoveData {
MoveData {
name: name.clone(),
move_type,
category,
base_power,
accuracy,
base_usages,
target,
priority,
secondary_effect,
flags,
}
}
/// The name of the move.
pub fn name(&self) -> &StringKey {
&self.name
}
/// The attacking type of the move.
pub fn move_type(&self) -> TypeIdentifier {
self.move_type
}
/// The category of the move.
pub fn category(&self) -> MoveCategory {
self.category
}
/// The base power, not considering any modifiers, the move has.
pub fn base_power(&self) -> u8 {
self.base_power
}
/// The accuracy of the move in percentage. Should be 255 for moves that always hit.
pub fn accuracy(&self) -> u8 {
self.accuracy
}
/// The number of times the move can be used. This can be modified on actually learned moves using
/// PP-Ups
pub fn base_usages(&self) -> u8 {
self.base_usages
}
/// How the move handles targets.
pub fn target(&self) -> MoveTarget {
self.target
}
/// The priority of the move. A higher priority means the move should go before other moves.
pub fn priority(&self) -> i8 {
self.priority
}
/// The optional secondary effect the move has.
pub fn secondary_effect(&self) -> &Option<SecondaryEffect> {
&self.secondary_effect
}
/// Arbitrary flags that can be applied to the move.
pub fn has_flag(&self, key: &StringKey) -> bool {
self.flags.contains::<StringKey>(key)
}
/// Arbitrary flags that can be applied to the move.
pub fn has_flag_by_hash(&self, key_hash: u32) -> bool {
self.flags.contains::<u32>(&key_hash)
}
}