1use crate::abilities::Abilities;
2use crate::choices::{Choices, MoveCategory};
3use crate::items::Items;
4use crate::pokemon::PokemonName;
5use crate::state::SideReference;
6use crate::state::Terrain;
7use crate::state::Weather;
8use crate::state::{LastUsedMove, PokemonVolatileStatus};
9use crate::state::{PokemonBoostableStat, PokemonType};
10use crate::state::{PokemonIndex, PokemonSideCondition};
11use crate::state::{PokemonMoveIndex, PokemonStatus};
12use std::fmt;
13use std::fmt::Formatter;
14
15#[derive(PartialEq, Clone)]
16pub struct StateInstructions {
17 pub percentage: f32,
18 pub instruction_list: Vec<Instruction>,
19}
20
21impl Default for StateInstructions {
22 fn default() -> StateInstructions {
23 StateInstructions {
24 percentage: 100.0,
25 instruction_list: Vec::with_capacity(16),
26 }
27 }
28}
29
30impl fmt::Debug for StateInstructions {
31 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
32 let mut final_string = format!("\n\tPercentage: {}\n\tInstructions:", self.percentage);
33 for i in self.instruction_list.iter() {
34 final_string.push_str(format!("\n\t\t{:?}", i).as_str());
35 }
36 write!(f, "{}\n", final_string)
37 }
38}
39
40impl StateInstructions {
41 pub fn update_percentage(&mut self, modifier: f32) {
42 self.percentage *= modifier;
43 }
44}
45
46#[derive(PartialEq, Clone)]
48pub enum Instruction {
49 Switch(SwitchInstruction),
50 ApplyVolatileStatus(ApplyVolatileStatusInstruction),
51 RemoveVolatileStatus(RemoveVolatileStatusInstruction),
52 ChangeStatus(ChangeStatusInstruction),
53 Heal(HealInstruction),
54 Damage(DamageInstruction),
55 Boost(BoostInstruction),
56 ChangeSideCondition(ChangeSideConditionInstruction),
57 ChangeWeather(ChangeWeather),
58 DecrementWeatherTurnsRemaining,
59 ChangeTerrain(ChangeTerrain),
60 DecrementTerrainTurnsRemaining,
61 ChangeType(ChangeType),
62 ChangeAbility(ChangeAbilityInstruction),
63 ChangeItem(ChangeItemInstruction),
64 ChangeAttack(ChangeStatInstruction),
65 ChangeDefense(ChangeStatInstruction),
66 ChangeSpecialAttack(ChangeStatInstruction),
67 ChangeSpecialDefense(ChangeStatInstruction),
68 ChangeSpeed(ChangeStatInstruction),
69 DisableMove(DisableMoveInstruction),
70 EnableMove(EnableMoveInstruction),
71 ChangeWish(ChangeWishInstruction),
72 DecrementWish(DecrementWishInstruction),
73 SetFutureSight(SetFutureSightInstruction),
74 DecrementFutureSight(DecrementFutureSightInstruction),
75 DamageSubstitute(DamageInstruction),
76 DecrementRestTurns(DecrementRestTurnsInstruction),
77 SetRestTurns(SetSleepTurnsInstruction),
78 SetSleepTurns(SetSleepTurnsInstruction),
79 ChangeSubstituteHealth(ChangeSubsituteHealthInstruction),
80 FormeChange(FormeChangeInstruction),
81 SetSideOneMoveSecondSwitchOutMove(SetSecondMoveSwitchOutMoveInstruction),
82 SetSideTwoMoveSecondSwitchOutMove(SetSecondMoveSwitchOutMoveInstruction),
83 ToggleBatonPassing(ToggleBatonPassingInstruction),
84 SetLastUsedMove(SetLastUsedMoveInstruction),
85 SetDamageDealtSideOne(SetDamageDealtSideOneInstruction),
86 SetDamageDealtSideTwo(SetDamageDealtSideTwoInstruction),
87 DecrementPP(DecrementPPInstruction),
88 ToggleTrickRoom(ToggleTrickRoomInstruction),
89 DecrementTrickRoomTurnsRemaining,
90 ToggleSideOneForceSwitch,
91 ToggleSideTwoForceSwitch,
92 ToggleTerastallized(ToggleTerastallizedInstruction),
93}
94
95impl fmt::Debug for Instruction {
96 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
97 match self {
98 Instruction::Switch(s) => {
99 write!(
100 f,
101 "Switch {:?}: {:?} -> {:?}",
102 s.side_ref, s.previous_index, s.next_index
103 )
104 }
105 Instruction::ApplyVolatileStatus(a) => {
106 write!(
107 f,
108 "ApplyVolatileStatus {:?}: {:?}",
109 a.side_ref, a.volatile_status
110 )
111 }
112 Instruction::RemoveVolatileStatus(r) => {
113 write!(
114 f,
115 "RemoveVolatileStatus {:?}: {:?}",
116 r.side_ref, r.volatile_status
117 )
118 }
119 Instruction::ChangeStatus(c) => {
120 write!(
121 f,
122 "ChangeStatus {:?}-{:?}: {:?} -> {:?}",
123 c.side_ref, c.pokemon_index, c.old_status, c.new_status
124 )
125 }
126 Instruction::Heal(h) => {
127 write!(f, "Heal {:?}: {:?}", h.side_ref, h.heal_amount)
128 }
129 Instruction::Damage(d) => {
130 write!(f, "Damage {:?}: {}", d.side_ref, d.damage_amount)
131 }
132 Instruction::Boost(b) => {
133 write!(f, "Boost {:?} {:?}: {:?}", b.side_ref, b.stat, b.amount)
134 }
135 Instruction::ChangeSideCondition(c) => {
136 write!(
137 f,
138 "ChangeSideCondition {:?} {:?}: {:?}",
139 c.side_ref, c.side_condition, c.amount
140 )
141 }
142 Instruction::ChangeWeather(c) => {
143 write!(
144 f,
145 "ChangeWeather: {:?},{:?} -> {:?},{:?}",
146 c.previous_weather,
147 c.previous_weather_turns_remaining,
148 c.new_weather,
149 c.new_weather_turns_remaining
150 )
151 }
152 Instruction::DecrementWeatherTurnsRemaining => {
153 write!(f, "DecrementWeatherTurnsRemaining",)
154 }
155 Instruction::ChangeTerrain(c) => {
156 write!(
157 f,
158 "ChangeTerrain: {:?},{:?} -> {:?},{:?}",
159 c.previous_terrain,
160 c.previous_terrain_turns_remaining,
161 c.new_terrain,
162 c.new_terrain_turns_remaining
163 )
164 }
165 Instruction::DecrementTerrainTurnsRemaining => {
166 write!(f, "DecrementTerrainTurnsRemaining",)
167 }
168 Instruction::ChangeType(c) => {
169 write!(
170 f,
171 "ChangeType {:?}: {:?} -> {:?}",
172 c.side_ref, c.old_types, c.new_types
173 )
174 }
175 Instruction::ChangeAbility(c) => {
176 write!(
177 f,
178 "ChangeAbility {:?}: {:?} -> {:?}",
179 c.side_ref, c.old_ability, c.new_ability
180 )
181 }
182 Instruction::ChangeItem(c) => {
183 write!(
184 f,
185 "ChangeItem {:?}: {:?} -> {:?}",
186 c.side_ref, c.current_item, c.new_item
187 )
188 }
189 Instruction::ChangeAttack(c) => {
190 write!(f, "ChangeAttack {:?}: {}", c.side_ref, c.amount)
191 }
192 Instruction::ChangeDefense(c) => {
193 write!(f, "ChangeDefense {:?}: {}", c.side_ref, c.amount)
194 }
195 Instruction::ChangeSpecialAttack(c) => {
196 write!(f, "ChangeSpecialAttack {:?}: {}", c.side_ref, c.amount)
197 }
198 Instruction::ChangeSpecialDefense(c) => {
199 write!(f, "ChangeSpecialDefense {:?}: {}", c.side_ref, c.amount)
200 }
201 Instruction::ChangeSpeed(c) => {
202 write!(f, "ChangeSpeed {:?}: {}", c.side_ref, c.amount)
203 }
204 Instruction::DisableMove(d) => {
205 write!(f, "DisableMove {:?}: {:?}", d.side_ref, d.move_index)
206 }
207 Instruction::EnableMove(e) => {
208 write!(f, "EnableMove {:?}: {:?}", e.side_ref, e.move_index)
209 }
210 Instruction::ChangeWish(s) => {
211 write!(f, "SetWish {:?}: {:?}", s.side_ref, s.wish_amount_change)
212 }
213 Instruction::DecrementWish(d) => {
214 write!(f, "DecrementWish {:?}", d.side_ref)
215 }
216 Instruction::SetFutureSight(s) => {
217 write!(
218 f,
219 "SetFutureSight {:?}: {:?} -> {:?}",
220 s.side_ref, s.previous_pokemon_index, s.pokemon_index
221 )
222 }
223 Instruction::DecrementFutureSight(d) => {
224 write!(f, "DecrementFutureSight {:?}", d.side_ref)
225 }
226 Instruction::DamageSubstitute(d) => {
227 write!(
228 f,
229 "DamageSubstitute {:?}: {:?}",
230 d.side_ref, d.damage_amount
231 )
232 }
233 Instruction::DecrementRestTurns(d) => {
234 write!(f, "DecrementRestTurns {:?}", d.side_ref)
235 }
236 Instruction::SetRestTurns(s) => {
237 write!(
238 f,
239 "SetRestTurns {:?}-{:?}: {:?} -> {:?}",
240 s.side_ref, s.pokemon_index, s.previous_turns, s.new_turns
241 )
242 }
243 Instruction::SetSleepTurns(s) => {
244 write!(
245 f,
246 "SetSleepTurns {:?}-{:?}: {:?} -> {:?}",
247 s.side_ref, s.pokemon_index, s.previous_turns, s.new_turns
248 )
249 }
250 Instruction::ChangeSubstituteHealth(s) => {
251 write!(
252 f,
253 "SetSubstituteHealth {:?}: {:?}",
254 s.side_ref, s.health_change,
255 )
256 }
257 Instruction::FormeChange(s) => {
258 write!(
259 f,
260 "FormeChange {:?}: {:?} -> {:?}",
261 s.side_ref, s.previous_forme, s.new_forme
262 )
263 }
264 Instruction::SetSideOneMoveSecondSwitchOutMove(s) => {
265 write!(
266 f,
267 "SideOneMoveSecondSwitchOutMove: {:?} -> {:?}",
268 s.previous_choice, s.new_choice
269 )
270 }
271 Instruction::SetSideTwoMoveSecondSwitchOutMove(s) => {
272 write!(
273 f,
274 "SideTwoMoveSecondSwitchOutMove: {:?} -> {:?}",
275 s.previous_choice, s.new_choice
276 )
277 }
278 Instruction::ToggleBatonPassing(s) => {
279 write!(f, "ToggleBatonPassing {:?}", s.side_ref)
280 }
281 Instruction::ToggleTerastallized(s) => {
282 write!(f, "ToggleTerastallized {:?}", s.side_ref)
283 }
284 Instruction::SetLastUsedMove(s) => {
285 write!(
286 f,
287 "SetLastUsedMove {:?}: {:?} -> {:?}",
288 s.side_ref, s.previous_last_used_move, s.last_used_move
289 )
290 }
291 Instruction::SetDamageDealtSideOne(s) => {
292 write!(
293 f,
294 "SetDamageDealt SideOne: ({:?} -> {:?}) Damage Change: {:?} HitSub Change: {:?}",
295 s.previous_move_category,
296 s.move_category,
297 s.damage_change,
298 s.toggle_hit_substitute
299 )
300 }
301 Instruction::SetDamageDealtSideTwo(s) => {
302 write!(
303 f,
304 "SetDamageDealt SideTwo: ({:?} -> {:?}) Damage Change: {:?} HitSub Change: {:?}",
305 s.previous_move_category,
306 s.move_category,
307 s.damage_change,
308 s.toggle_hit_substitute
309 )
310 }
311 Instruction::DecrementPP(s) => {
312 write!(
313 f,
314 "DecrementPP {:?}: {:?} {}",
315 s.side_ref, s.move_index, s.amount
316 )
317 }
318 Instruction::ToggleTrickRoom(i) => {
319 write!(
320 f,
321 "ToggleTrickRoom: {:?},{:?} -> {:?},{:?}",
322 i.currently_active,
323 i.previous_trickroom_turns_remaining,
324 !i.currently_active,
325 i.new_trickroom_turns_remaining,
326 )
327 }
328 Instruction::DecrementTrickRoomTurnsRemaining => {
329 write!(f, "DecrementTrickRoomTurnsRemaining")
330 }
331 Instruction::ToggleSideOneForceSwitch => {
332 write!(f, "ToggleSideOneForceSwitch")
333 }
334 Instruction::ToggleSideTwoForceSwitch => {
335 write!(f, "ToggleSideTwoForceSwitch")
336 }
337 }
338 }
339}
340
341#[derive(Debug, PartialEq, Clone)]
342pub struct SetDamageDealtSideOneInstruction {
343 pub damage_change: i16,
344 pub move_category: MoveCategory,
345 pub previous_move_category: MoveCategory,
346 pub toggle_hit_substitute: bool,
347}
348
349#[derive(Debug, PartialEq, Clone)]
350pub struct SetDamageDealtSideTwoInstruction {
351 pub damage_change: i16,
352 pub move_category: MoveCategory,
353 pub previous_move_category: MoveCategory,
354 pub toggle_hit_substitute: bool,
355}
356
357#[derive(Debug, PartialEq, Clone)]
358pub struct DecrementPPInstruction {
359 pub side_ref: SideReference,
360 pub move_index: PokemonMoveIndex,
361 pub amount: i8,
362}
363
364#[derive(Debug, PartialEq, Clone)]
365pub struct SetLastUsedMoveInstruction {
366 pub side_ref: SideReference,
367 pub last_used_move: LastUsedMove,
368 pub previous_last_used_move: LastUsedMove,
369}
370
371#[derive(Debug, PartialEq, Clone)]
372pub struct ToggleBatonPassingInstruction {
373 pub side_ref: SideReference,
374}
375
376#[derive(Debug, PartialEq, Clone)]
377pub struct DecrementRestTurnsInstruction {
378 pub side_ref: SideReference,
379}
380
381#[derive(Debug, PartialEq, Clone)]
382pub struct SetSleepTurnsInstruction {
383 pub side_ref: SideReference,
384 pub pokemon_index: PokemonIndex,
385 pub new_turns: i8,
386 pub previous_turns: i8,
387}
388
389#[derive(Debug, PartialEq, Clone)]
390pub struct SetSecondMoveSwitchOutMoveInstruction {
391 pub new_choice: Choices,
392 pub previous_choice: Choices,
393}
394
395#[derive(Debug, PartialEq, Clone)]
396pub struct ChangeWishInstruction {
397 pub side_ref: SideReference,
398 pub wish_amount_change: i16,
399}
400
401#[derive(Debug, PartialEq, Clone)]
402pub struct DecrementWishInstruction {
403 pub side_ref: SideReference,
404}
405
406#[derive(Debug, PartialEq, Clone)]
407pub struct SetFutureSightInstruction {
408 pub side_ref: SideReference,
409 pub pokemon_index: PokemonIndex,
410 pub previous_pokemon_index: PokemonIndex,
411}
412
413#[derive(Debug, PartialEq, Clone)]
414pub struct DecrementFutureSightInstruction {
415 pub side_ref: SideReference,
416}
417
418#[derive(Debug, PartialEq, Clone)]
419pub struct EnableMoveInstruction {
420 pub side_ref: SideReference,
421 pub move_index: PokemonMoveIndex,
422}
423
424#[derive(Debug, PartialEq, Clone)]
425pub struct DisableMoveInstruction {
426 pub side_ref: SideReference,
427 pub move_index: PokemonMoveIndex,
428}
429
430#[derive(Debug, PartialEq, Clone)]
431pub struct ChangeItemInstruction {
432 pub side_ref: SideReference,
433 pub current_item: Items,
434 pub new_item: Items,
435}
436
437#[derive(Debug, PartialEq, Clone)]
438pub struct ChangeStatInstruction {
439 pub side_ref: SideReference,
440 pub amount: i16,
441}
442
443#[derive(Debug, PartialEq, Clone)]
444pub struct HealInstruction {
445 pub side_ref: SideReference,
446 pub heal_amount: i16,
447}
448
449#[derive(Debug, PartialEq, Clone)]
450pub struct DamageInstruction {
451 pub side_ref: SideReference,
452 pub damage_amount: i16,
453}
454
455#[derive(Debug, PartialEq, Clone)]
456pub struct ChangeSubsituteHealthInstruction {
457 pub side_ref: SideReference,
458 pub health_change: i16,
459}
460
461#[derive(Debug, PartialEq, Clone)]
462pub struct FormeChangeInstruction {
463 pub side_ref: SideReference,
464 pub new_forme: PokemonName,
465 pub previous_forme: PokemonName,
466}
467
468#[derive(Debug, PartialEq, Clone)]
469pub struct SwitchInstruction {
470 pub side_ref: SideReference,
471 pub previous_index: PokemonIndex,
472 pub next_index: PokemonIndex,
473}
474
475#[derive(Debug, PartialEq, Clone)]
478pub struct ChangeStatusInstruction {
479 pub side_ref: SideReference,
480 pub pokemon_index: PokemonIndex,
481 pub old_status: PokemonStatus,
482 pub new_status: PokemonStatus,
483}
484
485#[derive(Debug, PartialEq, Clone)]
486pub struct ApplyVolatileStatusInstruction {
487 pub side_ref: SideReference,
488 pub volatile_status: PokemonVolatileStatus,
489}
490
491#[derive(Debug, PartialEq, Clone)]
492pub struct RemoveVolatileStatusInstruction {
493 pub side_ref: SideReference,
494 pub volatile_status: PokemonVolatileStatus,
495}
496
497#[derive(Debug, PartialEq, Clone)]
498pub struct BoostInstruction {
499 pub side_ref: SideReference,
500 pub stat: PokemonBoostableStat,
501 pub amount: i8,
502}
503
504#[derive(Debug, PartialEq, Clone)]
505pub struct ChangeSideConditionInstruction {
506 pub side_ref: SideReference,
507 pub side_condition: PokemonSideCondition,
508 pub amount: i8,
509}
510
511#[derive(Debug, PartialEq, Clone)]
512pub struct ChangeWeather {
513 pub new_weather: Weather,
514 pub new_weather_turns_remaining: i8,
515 pub previous_weather: Weather,
516 pub previous_weather_turns_remaining: i8,
517}
518
519#[derive(Debug, PartialEq, Clone)]
520pub struct ChangeTerrain {
521 pub new_terrain: Terrain,
522 pub new_terrain_turns_remaining: i8,
523 pub previous_terrain: Terrain,
524 pub previous_terrain_turns_remaining: i8,
525}
526
527#[derive(Debug, PartialEq, Clone)]
528pub struct ToggleTrickRoomInstruction {
529 pub currently_active: bool,
530 pub new_trickroom_turns_remaining: i8,
531 pub previous_trickroom_turns_remaining: i8,
532}
533
534#[derive(Debug, PartialEq, Clone)]
535pub struct ToggleTerastallizedInstruction {
536 pub side_ref: SideReference,
537}
538
539#[derive(Debug, PartialEq, Clone)]
540pub struct ChangeType {
541 pub side_ref: SideReference,
542 pub new_types: (PokemonType, PokemonType),
543 pub old_types: (PokemonType, PokemonType),
544}
545
546#[derive(Debug, PartialEq, Clone)]
547pub struct ChangeAbilityInstruction {
548 pub side_ref: SideReference,
549 pub new_ability: Abilities,
550 pub old_ability: Abilities,
551}
552
553#[cfg(test)]
554mod test {
555 use super::Instruction;
556
557 #[test]
559 fn test_instruction_size() {
560 assert_eq!(size_of::<Instruction>(), 8);
561 assert_eq!(align_of::<Instruction>(), 2);
562 }
563}