use core::any::Any; use core::mem::transmute; use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon, Statistic}; use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; pub struct Acupressure {} impl Acupressure { pub const fn get_const_name() -> &'static str { "acupressure" } } impl Script for Acupressure { fn new() -> Self { Self {} } fn get_name(&self) -> &'static str { Self::get_const_name() } fn get_capabilities(&self) -> &[ScriptCapabilities] { &[ScriptCapabilities::OnSecondaryEffect] } fn on_secondary_effect(&self, mv: ExecutingMove, target: Pokemon, hit: u8) { if target.equals(&mv.user()) { mv.get_hit_data(&target, hit).fail(); return; } let rand_stat: Statistic = unsafe { transmute(target.battle().unwrap().random().get_between(1, 6) as u8) }; target.change_stat_boost(rand_stat, 2, false); } fn as_any(&self) -> &dyn Any { self } } #[cfg(test)] mod tests { use super::*; use alloc::rc::Rc; use pkmn_lib_interface::app_interface::{ MockBattle, MockBattleRandom, MockExecutingMove, MockHitData, MockPokemon, }; #[test] fn fails_if_target_is_user() { let mut user = MockPokemon::new(); user.expect_equals().return_const(true); let user = Rc::new(user); let u = user.clone(); let mut mv = MockExecutingMove::new(); mv.expect_user().returning_st(move || user.clone()); let mut hit_data = MockHitData::new(); hit_data.expect_fail().once(); let hit_data = Rc::new(hit_data); mv.expect_get_hit_data() .returning_st(move |_, _| hit_data.clone()); let script = Acupressure::new(); script.on_secondary_effect(Rc::new(mv), u, 0); } #[test] fn increases_stat_by_two() { let mut user = MockPokemon::new(); user.expect_equals().return_const(false); user.expect_battle().returning_st(move || { let mut battle = MockBattle::new(); battle.expect_random().returning_st(move || { let mut random = MockBattleRandom::new(); random.expect_get_between().returning_st(|low, high| { assert_eq!(1, low); assert_eq!(6, high); 1 }); Rc::new(random) }); Some(Rc::new(battle)) }); user.expect_change_stat_boost() .once() .returning(|stat, amount, self_inflicted| { assert_eq!(Statistic::Attack, stat); assert_eq!(2, amount); assert!(!self_inflicted); true }); let user = Rc::new(user); let u = user.clone(); let mut mv = MockExecutingMove::new(); mv.expect_user().returning_st(move || user.clone()); let script = Acupressure::new(); script.on_secondary_effect(Rc::new(mv), u, 0); } }