From c29201b36fbf59b9f2f6297b899367d48c2f4fc6 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Sat, 10 Sep 2022 11:12:27 +0200 Subject: [PATCH] Implements Aurora Veil --- gen_7_scripts/src/lib.rs | 1 + gen_7_scripts/src/moves/aurora_veil.rs | 101 ++++++++++++++++++ gen_7_scripts/src/moves/light_screen.rs | 4 + gen_7_scripts/src/moves/mod.rs | 3 + gen_7_scripts/src/moves/reflect.rs | 5 + gen_7_scripts/src/weather/hail.rs | 25 +++++ gen_7_scripts/src/weather/mod.rs | 1 + .../src/app_interface/dynamic_data/battle.rs | 23 +++- .../app_interface/dynamic_data/battle_side.rs | 10 +- .../app_interface/static_data/move_data.rs | 4 +- .../src/app_interface/string_key.rs | 4 + 11 files changed, 177 insertions(+), 4 deletions(-) create mode 100644 gen_7_scripts/src/moves/aurora_veil.rs create mode 100644 gen_7_scripts/src/moves/light_screen.rs create mode 100644 gen_7_scripts/src/moves/reflect.rs create mode 100644 gen_7_scripts/src/weather/hail.rs create mode 100644 gen_7_scripts/src/weather/mod.rs diff --git a/gen_7_scripts/src/lib.rs b/gen_7_scripts/src/lib.rs index c7622e6..a1d52d6 100755 --- a/gen_7_scripts/src/lib.rs +++ b/gen_7_scripts/src/lib.rs @@ -16,6 +16,7 @@ pub mod moves; pub mod pokemon; pub mod util_scripts; pub(crate) mod utils; +pub mod weather; #[no_mangle] #[cfg(not(test))] diff --git a/gen_7_scripts/src/moves/aurora_veil.rs b/gen_7_scripts/src/moves/aurora_veil.rs new file mode 100644 index 0000000..a36b943 --- /dev/null +++ b/gen_7_scripts/src/moves/aurora_veil.rs @@ -0,0 +1,101 @@ +use crate::moves::light_screen::LightScreenEffect; +use crate::moves::reflect::ReflectEffect; +use crate::script; +use crate::weather::hail::Hail; +use alloc::boxed::Box; +use core::any::Any; +use core::sync::atomic::{AtomicU32, Ordering}; +use pkmn_lib_interface::app_interface::{BattleSide, ExecutingMove, MoveCategory, Pokemon}; +use pkmn_lib_interface::handling::ScriptCapabilities::OnEndTurn; +use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; + +script!(AuroraVeil, "aurora_veil"); + +impl Script for AuroraVeil { + 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.battle().unwrap().has_weather(Hail::get_const_name()) { + return mv.get_hit_data(&target, hit).fail(); + } + let script = target + .battle_side() + .add_volatile(Box::new(AuroraVeilEffect::new())) + .as_any() + .downcast_ref::() + .unwrap(); + if mv.user().has_held_item("light_clay") { + script.turns.store(8, Ordering::SeqCst); + } else { + script.turns.store(5, Ordering::SeqCst); + } + } + + fn as_any(&self) -> &dyn Any { + self + } +} + +script!(AuroraVeilEffect, "aurora_veil_effect", turns: AtomicU32); + +impl Script for AuroraVeilEffect { + fn new() -> Self { + Self { + turns: Default::default(), + } + } + + fn get_name(&self) -> &'static str { + Self::get_const_name() + } + + fn get_capabilities(&self) -> &[ScriptCapabilities] { + &[ScriptCapabilities::ChangeIncomingDamage, OnEndTurn] + } + + fn change_incoming_damage( + &self, + mv: ExecutingMove, + target: Pokemon, + hit: u8, + damage: &mut u32, + ) { + if mv.get_hit_data(&target, hit).is_critical() { + return; + } + let side: BattleSide = self.get_owner().unwrap(); + if side.has_volatile(ReflectEffect::get_const_name()) + && mv.use_move().category() == MoveCategory::Physical + { + return; + } + if side.has_volatile(LightScreenEffect::get_const_name()) + && mv.use_move().category() == MoveCategory::Special + { + return; + } + let mut modifier = 2.0; + if target.battle().unwrap().pokemon_per_side() > 1 { + modifier = 1.5 + } + *damage = (*damage as f32 / modifier) as u32; + } + + fn on_end_turn(&self) { + todo!() + } + + fn as_any(&self) -> &dyn Any { + self + } +} diff --git a/gen_7_scripts/src/moves/light_screen.rs b/gen_7_scripts/src/moves/light_screen.rs new file mode 100644 index 0000000..7dac27f --- /dev/null +++ b/gen_7_scripts/src/moves/light_screen.rs @@ -0,0 +1,4 @@ +// TODO: Implementation + +use crate::script; +script!(LightScreenEffect, "light_screen_effect"); diff --git a/gen_7_scripts/src/moves/mod.rs b/gen_7_scripts/src/moves/mod.rs index 0eb2828..996f7e6 100755 --- a/gen_7_scripts/src/moves/mod.rs +++ b/gen_7_scripts/src/moves/mod.rs @@ -4,4 +4,7 @@ pub mod after_you; pub mod assist; pub mod assurance; pub mod attract; +pub mod aurora_veil; +pub mod light_screen; pub mod multi_hit_move; +pub mod reflect; diff --git a/gen_7_scripts/src/moves/reflect.rs b/gen_7_scripts/src/moves/reflect.rs new file mode 100644 index 0000000..9572d7a --- /dev/null +++ b/gen_7_scripts/src/moves/reflect.rs @@ -0,0 +1,5 @@ +use crate::script; + +// TODO: Implementation + +script!(ReflectEffect, "reflect_effect"); \ No newline at end of file diff --git a/gen_7_scripts/src/weather/hail.rs b/gen_7_scripts/src/weather/hail.rs new file mode 100644 index 0000000..adae079 --- /dev/null +++ b/gen_7_scripts/src/weather/hail.rs @@ -0,0 +1,25 @@ +use crate::script; +use core::any::Any; +use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; +script!(Hail, "hail"); + +impl Script for Hail { + fn new() -> Self + where + Self: Sized, + { + Self {} + } + + fn get_name(&self) -> &'static str { + Self::get_const_name() + } + + fn get_capabilities(&self) -> &[ScriptCapabilities] { + todo!() + } + + fn as_any(&self) -> &dyn Any { + self + } +} diff --git a/gen_7_scripts/src/weather/mod.rs b/gen_7_scripts/src/weather/mod.rs new file mode 100644 index 0000000..cf47a2c --- /dev/null +++ b/gen_7_scripts/src/weather/mod.rs @@ -0,0 +1 @@ +pub mod hail; diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs index 08ffcc8..aa19e84 100755 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/battle.rs @@ -3,7 +3,7 @@ use crate::handling::cached_value::CachedValue; use crate::handling::Cacheable; use crate::{ cached_value, cached_value_getters, wasm_value_getters, DynamicLibrary, ExternRef, - ExternalReferenceType, ImmutableList, VecExternRef, + ExternalReferenceType, ImmutableList, StringKey, VecExternRef, }; use alloc::rc::Rc; @@ -56,6 +56,25 @@ impl Battle { battle_find_party_for_pokemon(self.inner.reference, pokemon.reference()).get_value() } } + + #[cfg(feature = "mock_data")] + pub fn weather_name(&self) -> Option { + None + } + + #[cfg(not(feature = "mock_data"))] + pub fn weather_name(&self) -> Option { + unsafe { battle_get_weather_name(self.inner.reference).get_value() } + } + + pub fn has_weather(&self, name: &str) -> bool { + if let Some(weather) = self.weather_name() { + if weather.eq(name) { + return true; + } + } + false + } } wasm_value_getters! { @@ -90,4 +109,6 @@ extern "wasm" { r: ExternRef, mon: ExternRef, ) -> ExternRef; + + fn battle_get_weather_name(r: ExternRef) -> ExternRef; } diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/battle_side.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/battle_side.rs index c3bcd41..de841df 100755 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/battle_side.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/battle_side.rs @@ -46,7 +46,15 @@ impl BattleSide { } #[cfg(not(feature = "mock_data"))] - pub fn add_volatile(&self, script: Box) -> &dyn Script { + pub fn has_volatile(&self, script_name: &str) -> bool { + unsafe { + let script_name = CString::new(script_name).unwrap(); + battleside_has_volatile(self.inner.reference, script_name.into_raw()) + } + } + + #[cfg(not(feature = "mock_data"))] + pub fn add_volatile<'a, 'b>(&'a self, script: Box) -> &'b dyn Script { unsafe { battleside_add_volatile(self.inner.reference, ScriptPtr::new(script)) .val() diff --git a/pkmn_lib_interface/src/app_interface/static_data/move_data.rs b/pkmn_lib_interface/src/app_interface/static_data/move_data.rs index 67ce385..84a567d 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/move_data.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/move_data.rs @@ -5,7 +5,7 @@ use crate::{cached_value, cached_value_getters, ExternRef, ExternalReferenceType use alloc::rc::Rc; #[repr(u8)] -#[derive(Clone)] +#[derive(Clone, Eq, PartialEq)] pub enum MoveCategory { Physical = 0, Special = 1, @@ -13,7 +13,7 @@ pub enum MoveCategory { } #[repr(u8)] -#[derive(Clone)] +#[derive(Clone, Eq, PartialEq)] pub enum MoveTarget { Adjacent, AdjacentAlly, diff --git a/pkmn_lib_interface/src/app_interface/string_key.rs b/pkmn_lib_interface/src/app_interface/string_key.rs index 971729b..82ee0c5 100755 --- a/pkmn_lib_interface/src/app_interface/string_key.rs +++ b/pkmn_lib_interface/src/app_interface/string_key.rs @@ -68,6 +68,10 @@ impl StringKey { pub fn hash(&self) -> u32 { self.data.hash.borrow().unwrap() } + + pub fn eq(&self, other: &str) -> bool { + self.hash() == get_hash(other) + } } impl PartialEq for StringKey {