use alloc::{
string::String,
vec::Vec,
};
use hashbrown::HashSet;
use serde::{
Deserialize,
Serialize,
};
use serde_string_enum::{
DeserializeLabeledStringEnum,
SerializeLabeledStringEnum,
};
use crate::{
Accuracy,
BoostTable,
Fraction,
MonOverride,
MoveCategory,
MoveFlag,
MoveTarget,
MultihitType,
OhkoType,
SelfDestructType,
Stat,
SwitchType,
Type,
};
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct HitEffect {
pub boosts: Option<BoostTable>,
pub heal_percent: Option<Fraction<u16>>,
pub status: Option<String>,
pub volatile_status: Option<String>,
pub side_condition: Option<String>,
pub slot_condition: Option<String>,
pub weather: Option<String>,
pub pseudo_weather: Option<String>,
pub terrain: Option<String>,
#[serde(default)]
pub force_switch: bool,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct SecondaryEffectData {
pub chance: Option<Fraction<u16>>,
pub target: Option<HitEffect>,
pub user: Option<HitEffect>,
#[serde(default)]
pub effect: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ZPower {
#[serde(rename = "boosts")]
Boosts(BoostTable),
#[serde(rename = "effect")]
Effect(String),
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct ZMoveData {
#[serde(default)]
pub base_power: u32,
#[serde(flatten)]
pub z_power: Option<ZPower>,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct MaxMoveData {
pub base_power: u32,
}
#[derive(Debug, Default, Clone, SerializeLabeledStringEnum, DeserializeLabeledStringEnum)]
pub enum RecoilBase {
#[default]
#[string = "Damage"]
Damage,
#[string = "UserMaxHp"]
UserMaxHp,
#[string = "UserBaseMaxHp"]
UserBaseMaxHp,
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct RecoilData {
#[serde(default)]
pub base: RecoilBase,
pub percent: Fraction<u16>,
#[serde(default)]
pub struggle: bool,
}
fn default_crit_ratio() -> Option<u8> {
Some(1)
}
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct MoveData {
pub name: String,
pub category: MoveCategory,
pub primary_type: Type,
#[serde(default)]
pub base_power: u32,
pub accuracy: Accuracy,
#[serde(default)]
pub pp: u8,
#[serde(default)]
pub priority: i8,
pub target: MoveTarget,
pub flags: HashSet<MoveFlag>,
pub damage: Option<u16>,
#[serde(default)]
pub no_pp_boosts: bool,
pub ohko_type: Option<OhkoType>,
pub user_switch: Option<SwitchType>,
pub self_destruct: Option<SelfDestructType>,
pub recoil: Option<RecoilData>,
pub drain_percent: Option<Fraction<u16>>,
#[serde(default)]
pub typeless: bool,
#[serde(default)]
pub force_stab: bool,
pub hit_effect: Option<HitEffect>,
pub user_effect: Option<HitEffect>,
pub user_effect_chance: Option<Fraction<u16>>,
#[serde(default)]
pub secondary_effects: Vec<SecondaryEffectData>,
pub override_offensive_mon: Option<MonOverride>,
pub override_offensive_stat: Option<Stat>,
pub override_defensive_mon: Option<MonOverride>,
pub override_defensive_stat: Option<Stat>,
#[serde(default = "default_crit_ratio")]
pub crit_ratio: Option<u8>,
#[serde(default)]
pub ignore_accuracy: bool,
#[serde(default)]
pub ignore_defensive: bool,
#[serde(default)]
pub ignore_evasion: bool,
#[serde(default)]
pub ignore_offensive: bool,
#[serde(default)]
pub multiaccuracy: bool,
pub multihit: Option<MultihitType>,
#[serde(default)]
pub tracks_target: bool,
#[serde(default)]
pub will_crit: bool,
#[serde(default)]
pub no_random_target: bool,
pub z_move: Option<ZMoveData>,
pub max_move: Option<MaxMoveData>,
#[serde(default)]
pub effect: serde_json::Value,
#[serde(default)]
pub condition: serde_json::Value,
}