Skip to main content

battler_data/moves/
move_data.rs

1use alloc::{
2    string::String,
3    vec::Vec,
4};
5
6use hashbrown::HashSet;
7use serde::{
8    Deserialize,
9    Serialize,
10};
11use serde_string_enum::{
12    DeserializeLabeledStringEnum,
13    SerializeLabeledStringEnum,
14};
15
16use crate::{
17    Accuracy,
18    BoostTable,
19    Fraction,
20    MonOverride,
21    MoveCategory,
22    MoveFlag,
23    MoveTarget,
24    MultihitType,
25    OhkoType,
26    SelfDestructType,
27    Stat,
28    SwitchType,
29    Type,
30};
31
32/// The effect of being hit by a move.
33#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize)]
34pub struct HitEffect {
35    /// Stat boosts.
36    pub boosts: Option<BoostTable>,
37    /// Percentage of target's HP to heal.
38    pub heal_percent: Option<Fraction<u16>>,
39    /// Status applied.
40    pub status: Option<String>,
41    /// Volatile status applied.
42    pub volatile_status: Option<String>,
43    /// Side condition applied.
44    pub side_condition: Option<String>,
45    /// Slot condition applied.
46    pub slot_condition: Option<String>,
47    /// Weather applied.
48    pub weather: Option<String>,
49    /// Pseudo-weather applied.
50    pub pseudo_weather: Option<String>,
51    /// Terrain applied.
52    pub terrain: Option<String>,
53    /// Force the target to switch out?
54    #[serde(default)]
55    pub force_switch: bool,
56}
57
58/// Data about a secondary effect that occurs after a move is used.
59#[derive(Debug, Default, Clone, Serialize, Deserialize)]
60pub struct SecondaryEffectData {
61    /// Chance of the effect occurring.
62    pub chance: Option<Fraction<u16>>,
63    /// Secondary hit effect on the target.
64    pub target: Option<HitEffect>,
65    /// Secondary hit effect on the user of the move.
66    pub user: Option<HitEffect>,
67    /// Dynamic battle effects.
68    #[serde(default)]
69    pub effect: serde_json::Value,
70}
71
72/// Data for the Z-Power of a Z-Move.
73#[derive(Debug, Clone, Serialize, Deserialize)]
74pub enum ZPower {
75    #[serde(rename = "boosts")]
76    Boosts(BoostTable),
77    #[serde(rename = "effect")]
78    Effect(String),
79}
80
81/// Data about how a move affects Z-Moves.
82#[derive(Debug, Default, Clone, Serialize, Deserialize)]
83pub struct ZMoveData {
84    /// Base power.
85    #[serde(default)]
86    pub base_power: u32,
87    /// Z-Power.
88    #[serde(flatten)]
89    pub z_power: Option<ZPower>,
90}
91
92/// Data about how a move affects Max Moves.
93#[derive(Debug, Default, Clone, Serialize, Deserialize)]
94pub struct MaxMoveData {
95    /// Base power.
96    pub base_power: u32,
97}
98/// The base number to use for recoil damage calculation.
99#[derive(Debug, Default, Clone, SerializeLabeledStringEnum, DeserializeLabeledStringEnum)]
100pub enum RecoilBase {
101    /// Damage dealt.
102    #[default]
103    #[string = "Damage"]
104    Damage,
105    /// The move user's maximum HP.
106    #[string = "UserMaxHp"]
107    UserMaxHp,
108    /// The move user's base maximum HP.
109    #[string = "UserBaseMaxHp"]
110    UserBaseMaxHp,
111}
112
113/// Data for a move's recoil damage to the user.
114#[derive(Debug, Default, Clone, Serialize, Deserialize)]
115pub struct RecoilData {
116    /// The base number to use for recoil damage calculation.
117    #[serde(default)]
118    pub base: RecoilBase,
119    /// Percent of base.
120    pub percent: Fraction<u16>,
121    /// Apply Struggle recoil directly?
122    #[serde(default)]
123    pub struggle: bool,
124}
125
126fn default_crit_ratio() -> Option<u8> {
127    Some(1)
128}
129
130/// Data about a particular move.
131///
132/// Moves are the primary effect that drive battle forward. Every Mon enters a battle with their
133/// moveset. Each turn, a Mon uses one move to affect the battle. Moves can damage opposing Mons,
134/// affect ally Mons or the user itself, boost or drop stats, apply conditions to Mons or the
135/// battlefield itself, and more.
136#[derive(Debug, Default, Clone, Serialize, Deserialize)]
137pub struct MoveData {
138    /// Name of the move.
139    pub name: String,
140    /// Move category.
141    pub category: MoveCategory,
142    /// Move type.
143    pub primary_type: Type,
144    /// Base power.
145    #[serde(default)]
146    pub base_power: u32,
147    /// Base accuracy.
148    pub accuracy: Accuracy,
149    /// Total power points, which is the number of times this move can be used.
150    #[serde(default)]
151    pub pp: u8,
152    /// Move priority.
153    #[serde(default)]
154    pub priority: i8,
155    /// Move target(s).
156    pub target: MoveTarget,
157    /// Move flags.
158    pub flags: HashSet<MoveFlag>,
159
160    /// Static damage dealt.
161    pub damage: Option<u16>,
162    /// Disallow PP boosts?
163    #[serde(default)]
164    pub no_pp_boosts: bool,
165
166    /// Type of OHKO, if any.
167    ///
168    /// If a target has this type, it is immune.
169    pub ohko_type: Option<OhkoType>,
170    /// Type of switch that occurs on the user.
171    pub user_switch: Option<SwitchType>,
172    /// How the user self destructs.
173    pub self_destruct: Option<SelfDestructType>,
174    /// Recoil damage to apply.
175    pub recoil: Option<RecoilData>,
176    /// The percentage of the target's HP to drain.
177    pub drain_percent: Option<Fraction<u16>>,
178    /// Typeless?
179    #[serde(default)]
180    pub typeless: bool,
181    /// Force STAB?
182    #[serde(default)]
183    pub force_stab: bool,
184
185    /// Primary effect applied to the target.
186    ///
187    /// Applied when the move hits.
188    pub hit_effect: Option<HitEffect>,
189    /// Primary effect on the user.
190    ///
191    /// Applied when the move hits.
192    pub user_effect: Option<HitEffect>,
193    /// Chance of the user effect occurring.
194    pub user_effect_chance: Option<Fraction<u16>>,
195    /// Secondary effects applied to the target.
196    #[serde(default)]
197    pub secondary_effects: Vec<SecondaryEffectData>,
198
199    /// Mon override for offensive stat calculations.
200    ///
201    /// By default, the move user is used.
202    pub override_offensive_mon: Option<MonOverride>,
203    /// Stat override for offensive stat calculations.
204    ///
205    /// By default, Atk is used for physical moves and SpA is used for special moves.
206    pub override_offensive_stat: Option<Stat>,
207    /// Mon override for defensive stat calculations.
208    ///
209    /// By default, the move target is used.
210    pub override_defensive_mon: Option<MonOverride>,
211    /// Stat override for defensive stat calculations.
212    ///
213    /// By default, Def is used for physical moves and SpD is used for special moves.
214    pub override_defensive_stat: Option<Stat>,
215
216    /// Critical hit ratio.
217    #[serde(default = "default_crit_ratio")]
218    pub crit_ratio: Option<u8>,
219    /// Ignore accuracy modifiers?
220    #[serde(default)]
221    pub ignore_accuracy: bool,
222    /// Ignore defensive modifiers?
223    #[serde(default)]
224    pub ignore_defensive: bool,
225    /// Ignore evasion modifiers?
226    #[serde(default)]
227    pub ignore_evasion: bool,
228    /// Ignore offensive modifiers?
229    #[serde(default)]
230    pub ignore_offensive: bool,
231    /// Accuracy calculations should be run multiple times.
232    #[serde(default)]
233    pub multiaccuracy: bool,
234    /// The move hits multiple times.
235    pub multihit: Option<MultihitType>,
236    /// Does the move track the target, even if they have moved?
237    #[serde(default)]
238    pub tracks_target: bool,
239    /// The move will always critical hit.
240    #[serde(default)]
241    pub will_crit: bool,
242    /// Does the move avoid random targets?
243    #[serde(default)]
244    pub no_random_target: bool,
245
246    /// Data about how the move affects Z-Moves.
247    pub z_move: Option<ZMoveData>,
248    /// Data about how the move affects Max Moves.
249    pub max_move: Option<MaxMoveData>,
250
251    /// Dynamic battle effects.
252    #[serde(default)]
253    pub effect: serde_json::Value,
254    /// Dynamic battle effects of the condition created by this move.
255    #[serde(default)]
256    pub condition: serde_json::Value,
257}