firecore_pokedex/
moves.rs1use alloc::string::String;
7use serde::{Deserialize, Serialize};
8use tinystr::TinyAsciiStr;
9
10use crate::{pokemon::stat::StatType, types::PokemonType, Identifiable, UNKNOWN_ID};
11
12pub mod owned;
13pub mod set;
14
15pub type Power = u8;
17pub type Accuracy = u8;
19pub type PP = u8;
21pub type Priority = i8;
24pub type CriticalRate = u8;
28
29#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord)]
31#[serde(transparent)]
32pub struct MoveId(pub TinyAsciiStr<16>);
33
34#[derive(Debug, Clone, Deserialize, Serialize)]
37#[serde(deny_unknown_fields)]
38pub struct Move {
39 pub id: MoveId,
40
41 pub name: String,
42
43 pub category: MoveCategory,
44
45 #[serde(rename = "type")]
47 pub pokemon_type: PokemonType,
48 pub accuracy: Option<Accuracy>,
50 pub power: Option<Power>,
51 pub pp: PP,
52 #[serde(default)]
53 pub priority: Priority,
54
55 #[serde(default)]
56 pub target: MoveTarget,
57
58 #[serde(default)]
60 pub contact: bool,
61
62 #[serde(default)]
64 pub crit_rate: CriticalRate,
65}
66
67impl Identifiable for Move {
74 type Id = MoveId;
75
76 const UNKNOWN: Self::Id = MoveId(UNKNOWN_ID);
77
78 fn id(&self) -> &Self::Id {
79 &self.id
80 }
81
82 fn name(&self) -> &str {
83 &self.name
84 }
85}
86
87#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Deserialize, Serialize)]
96pub enum MoveCategory {
97 Status,
98 Physical,
99 Special,
100}
101
102impl MoveCategory {
103 pub fn stats(&self) -> (StatType, StatType) {
105 (self.attack(), self.defense())
106 }
107 pub fn attack(&self) -> StatType {
109 match self {
110 MoveCategory::Physical => StatType::Attack,
111 MoveCategory::Special => StatType::SpAttack,
112 MoveCategory::Status => unreachable!("Cannot get attack stat for status move!"),
113 }
114 }
115 pub fn defense(&self) -> StatType {
117 match self {
118 MoveCategory::Physical => StatType::Defense,
119 MoveCategory::Special => StatType::SpDefense,
120 MoveCategory::Status => unreachable!("Cannot get defense stat for status move!"),
121 }
122 }
123}
124
125#[derive(Debug, Clone, Copy, Deserialize, Serialize)]
127pub enum MoveTarget {
128 Any,
129 Ally,
130 Allies,
131 UserOrAlly,
132 UserAndAllies,
133 User,
135 Opponent,
136 AllOpponents,
137 RandomOpponent,
138 AllOtherPokemon,
139 AllPokemon,
140 None,
141}
142
143impl Default for MoveTarget {
144 fn default() -> Self {
145 Self::None
146 }
147}
148
149impl MoveTarget {
150 pub fn needs_input(&self) -> bool {
151 match self {
152 MoveTarget::Ally | MoveTarget::Any | MoveTarget::Opponent | MoveTarget::UserOrAlly => {
153 true
154 }
155 _ => false,
156 }
157 }
158}
159
160impl Default for MoveId {
161 fn default() -> Self {
162 Self(UNKNOWN_ID)
163 }
164}
165
166impl From<TinyAsciiStr<16>> for MoveId {
167 fn from(str: TinyAsciiStr<16>) -> Self {
168 Self(str)
169 }
170}
171
172impl core::str::FromStr for MoveId {
173 type Err = tinystr::TinyStrError;
174
175 fn from_str(s: &str) -> Result<Self, Self::Err> {
176 s.parse().map(Self)
177 }
178}