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