diff --git a/gen_7_scripts/Cargo.toml b/gen_7_scripts/Cargo.toml index b6544d6..9ed48eb 100755 --- a/gen_7_scripts/Cargo.toml +++ b/gen_7_scripts/Cargo.toml @@ -9,6 +9,7 @@ crate-type = ["cdylib"] [dependencies] pkmn_lib_interface = { path = "../pkmn_lib_interface" } +paste = { version = "1.0.7" } [dev-dependencies] pkmn_lib_interface = { path = "../pkmn_lib_interface", features = ["mock_data"] } diff --git a/gen_7_scripts/src/moves/automize.rs b/gen_7_scripts/src/moves/automize.rs new file mode 100644 index 0000000..081cc99 --- /dev/null +++ b/gen_7_scripts/src/moves/automize.rs @@ -0,0 +1,38 @@ +use crate::script; +use core::any::Any; +use pkmn_lib_interface::app_interface::{ExecutingMove, Pokemon, Statistic}; +use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; + +script!(Automize, "automize"); + +impl Script for Automize { + 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) { + let user = mv.user(); + let stats = user.boosted_stats(); + let original_speed = stats.speed(); + let original_weight = user.weight(); + user.change_stat_boost(Statistic::Speed, 2, true); + if user.boosted_stats().speed() != original_speed { + user.set_weight(original_weight - 100.0); + if user.weight() != original_weight { + // TODO: Became nimble dialog. + } + } + } + + fn as_any(&self) -> &dyn Any { + self + } +} diff --git a/gen_7_scripts/src/moves/change_all_target_stats.rs b/gen_7_scripts/src/moves/change_all_target_stats.rs new file mode 100644 index 0000000..094d34a --- /dev/null +++ b/gen_7_scripts/src/moves/change_all_target_stats.rs @@ -0,0 +1,58 @@ +use crate::script; +use core::any::Any; +use core::sync::atomic::{AtomicI8, Ordering}; +use pkmn_lib_interface::app_interface::list::ImmutableList; +use pkmn_lib_interface::app_interface::{ + DynamicLibrary, EffectParameter, ExecutingMove, Pokemon, Statistic, +}; +use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; + +script!( + ChangeAllTargetStats, + "change_all_target_stats", + amount: AtomicI8 +); + +impl Script for ChangeAllTargetStats { + fn new() -> Self { + Self { + amount: Default::default(), + } + } + + fn get_name(&self) -> &'static str { + Self::get_const_name() + } + + fn get_capabilities(&self) -> &[ScriptCapabilities] { + &[ + ScriptCapabilities::Initialize, + ScriptCapabilities::OnSecondaryEffect, + ] + } + + fn on_initialize( + &self, + library: &DynamicLibrary, + parameters: Option>, + ) { + self.amount.store( + parameters.unwrap().get(0).unwrap().as_int() as i8, + Ordering::SeqCst, + ); + } + + fn on_secondary_effect(&self, mv: ExecutingMove, target: Pokemon, _hit: u8) { + let user = mv.user(); + let amount = self.amount.load(Ordering::SeqCst); + target.change_stat_boost(Statistic::Attack, amount, user == target); + target.change_stat_boost(Statistic::Defense, amount, user == target); + target.change_stat_boost(Statistic::SpecialAttack, amount, user == target); + target.change_stat_boost(Statistic::SpecialDefense, amount, user == target); + target.change_stat_boost(Statistic::Speed, amount, user == target); + } + + fn as_any(&self) -> &dyn Any { + self + } +} diff --git a/gen_7_scripts/src/moves/change_target_stats.rs b/gen_7_scripts/src/moves/change_target_stats.rs new file mode 100644 index 0000000..a811327 --- /dev/null +++ b/gen_7_scripts/src/moves/change_target_stats.rs @@ -0,0 +1,74 @@ +use crate::script; +use core::any::Any; +use core::sync::atomic::{AtomicI8, Ordering}; +use pkmn_lib_interface::app_interface::list::ImmutableList; +use pkmn_lib_interface::app_interface::{ + DynamicLibrary, EffectParameter, ExecutingMove, Pokemon, Statistic, +}; +use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; + +macro_rules! change_stat_effect { + ( + $stat:ident + ) => { + paste::paste! { + pub struct [] { + amount: AtomicI8, + } + + impl [] { + pub const fn get_const_name() -> &'static str { + stringify!([<"change_target_" $stat:snake>]) + } + } + + impl Script for [] { + fn new() -> Self { + Self { + amount: Default::default(), + } + } + + fn get_name(&self) -> &'static str { + Self::get_const_name() + } + + fn get_capabilities(&self) -> &[ScriptCapabilities] { + &[ + ScriptCapabilities::Initialize, + ScriptCapabilities::OnSecondaryEffect, + ] + } + + fn on_initialize( + &self, + _library: &DynamicLibrary, + parameters: Option>, + ) { + self.amount.store( + parameters.unwrap().get(0).unwrap().as_int() as i8, + Ordering::SeqCst, + ); + } + + fn on_secondary_effect(&self, mv: ExecutingMove, target: Pokemon, _hit: u8) { + target.change_stat_boost( + Statistic::$stat, + self.amount.load(Ordering::SeqCst), + mv.user() == target, + ); + } + + fn as_any(&self) -> &dyn Any { + self + } + } + } + }; +} + +change_stat_effect!(Attack); +change_stat_effect!(Defense); +change_stat_effect!(SpecialAttack); +change_stat_effect!(SpecialDefense); +change_stat_effect!(Speed); diff --git a/gen_7_scripts/src/moves/mod.rs b/gen_7_scripts/src/moves/mod.rs index 996f7e6..516dc0c 100755 --- a/gen_7_scripts/src/moves/mod.rs +++ b/gen_7_scripts/src/moves/mod.rs @@ -5,6 +5,9 @@ pub mod assist; pub mod assurance; pub mod attract; pub mod aurora_veil; +pub mod automize; +pub mod change_all_target_stats; +pub mod change_target_stats; pub mod light_screen; pub mod multi_hit_move; pub mod reflect; diff --git a/gen_7_scripts/src/registered_scripts.rs b/gen_7_scripts/src/registered_scripts.rs index f9105ed..4210d25 100755 --- a/gen_7_scripts/src/registered_scripts.rs +++ b/gen_7_scripts/src/registered_scripts.rs @@ -35,6 +35,13 @@ pub fn get_script(category: ScriptCategory, name: &StringKey) -> Option {} diff --git a/pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs b/pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs index 9161808..d37bc1f 100755 --- a/pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs +++ b/pkmn_lib_interface/src/app_interface/dynamic_data/pokemon.rs @@ -171,6 +171,13 @@ impl Pokemon { unsafe { pokemon_heal(self.inner.reference, amount, allow_revive) } } + #[cfg(not(feature = "mock_data"))] + pub fn set_weight(&self, weight: f32) { + unsafe { + pokemon_set_weight(self.reference(), weight); + } + } + #[cfg(not(feature = "mock_data"))] pub fn battle_side(&self) -> BattleSide { self.battle() @@ -319,6 +326,7 @@ extern "wasm" { fn pokemon_change_form(r: ExternRef, form: ExternRef
); fn pokemon_damage(r: ExternRef, damage: u32, source: DamageSource); fn pokemon_heal(r: ExternRef, amount: u32, allow_revive: bool) -> bool; + fn pokemon_set_weight(r: ExternRef, weight: f32); fn pokemon_add_volatile_by_name(r: ExternRef, name: *const c_char) -> ScriptPtr; fn pokemon_add_volatile(r: ExternRef, script: ScriptPtr) -> ScriptPtr; diff --git a/pkmn_lib_interface/src/app_interface/static_data/effect_parameter.rs b/pkmn_lib_interface/src/app_interface/static_data/effect_parameter.rs index 6e1b65d..7411375 100755 --- a/pkmn_lib_interface/src/app_interface/static_data/effect_parameter.rs +++ b/pkmn_lib_interface/src/app_interface/static_data/effect_parameter.rs @@ -35,6 +35,35 @@ impl EffectParameter { } } } + + pub fn as_bool(&self) -> bool { + if let EffectParameter::Bool(b) = self { + return *b; + } + panic!("Unexpected effect parameter type: {}", self); + } + + pub fn as_int(&self) -> i64 { + if let EffectParameter::Int(i) = self { + return *i; + } + panic!("Unexpected effect parameter type: {}", self); + } + + pub fn as_float(&self) -> f32 { + if let EffectParameter::Float(f) = self { + return *f; + } + panic!("Unexpected effect parameter type: {}", self); + } + + pub fn as_string(&self) -> StringKey { + if let EffectParameter::String(s) = self { + return s.clone(); + } + panic!("Unexpected effect parameter type: {}", self); + } + } #[cfg(not(feature = "mock_data"))]