From 037e7af16f65b0c720813f414dcb72c5bca522c5 Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Fri, 30 Jun 2023 13:44:50 +0200 Subject: [PATCH] Automatically generate script name resolver. --- gen_7_scripts/Cargo.toml | 6 +- gen_7_scripts/build.rs | 127 ++++++++++++++++++ gen_7_scripts/src/lib.rs | 1 + gen_7_scripts/src/moves/assurance.rs | 55 +------- gen_7_scripts/src/moves/aurora_veil.rs | 62 +-------- gen_7_scripts/src/moves/flinch.rs | 29 +--- .../src/moves/increased_critical_stage.rs | 33 +++++ gen_7_scripts/src/moves/light_screen.rs | 4 - gen_7_scripts/src/moves/mod.rs | 8 +- gen_7_scripts/src/moves/prevent_foes_exit.rs | 34 +++++ gen_7_scripts/src/pokemon/assurance_data.rs | 61 +++++++++ gen_7_scripts/src/pokemon/flinch_effect.rs | 27 ++++ gen_7_scripts/src/pokemon/mod.rs | 4 + .../src/pokemon/prevent_foes_exit.rs | 34 +++++ .../reflect.rs => pokemon/reflect_effect.rs} | 0 gen_7_scripts/src/registered_scripts.rs | 98 ++++++++------ gen_7_scripts/src/side/aurora_veil_effect.rs | 63 +++++++++ gen_7_scripts/src/side/light_screen.rs | 24 ++++ gen_7_scripts/src/side/mod.rs | 2 + 19 files changed, 485 insertions(+), 187 deletions(-) create mode 100644 gen_7_scripts/build.rs create mode 100644 gen_7_scripts/src/moves/increased_critical_stage.rs delete mode 100644 gen_7_scripts/src/moves/light_screen.rs create mode 100644 gen_7_scripts/src/moves/prevent_foes_exit.rs create mode 100644 gen_7_scripts/src/pokemon/assurance_data.rs create mode 100644 gen_7_scripts/src/pokemon/flinch_effect.rs create mode 100644 gen_7_scripts/src/pokemon/prevent_foes_exit.rs rename gen_7_scripts/src/{moves/reflect.rs => pokemon/reflect_effect.rs} (100%) create mode 100644 gen_7_scripts/src/side/aurora_veil_effect.rs create mode 100644 gen_7_scripts/src/side/light_screen.rs create mode 100644 gen_7_scripts/src/side/mod.rs diff --git a/gen_7_scripts/Cargo.toml b/gen_7_scripts/Cargo.toml index 0f48b47..a0d5e2f 100755 --- a/gen_7_scripts/Cargo.toml +++ b/gen_7_scripts/Cargo.toml @@ -3,6 +3,7 @@ name = "gen7_scripts" version = "0.1.0" authors = ["Deukhoofd "] edition = "2021" +build = "build.rs" [lib] crate-type = ["cdylib"] @@ -14,4 +15,7 @@ atomic_float = "0.1.0" [dev-dependencies] pkmn_lib_interface = { path = "../pkmn_lib_interface", features = ["mock_data"] } -mockall = "0.11.2" \ No newline at end of file +mockall = "0.11.2" + +[build-dependencies] +syn = { version = "2.0.22", features = ["full"] } \ No newline at end of file diff --git a/gen_7_scripts/build.rs b/gen_7_scripts/build.rs new file mode 100644 index 0000000..1d343c4 --- /dev/null +++ b/gen_7_scripts/build.rs @@ -0,0 +1,127 @@ +use std::io::Write; + +fn main() { + let mut output_file = std::fs::File::create("src/registered_scripts.rs").unwrap(); + + write!( + output_file, + r"// Autogenerated file. Do not edit. + +use alloc::boxed::Box; +use pkmn_lib_interface::app_interface::{{get_hash, StringKey}}; +use pkmn_lib_interface::handling::{{Script, ScriptCategory}}; + +macro_rules! resolve_match {{ + ( + $mid:expr, + $( + $script:ty, + )* + ) => ( + match $mid {{ + $( + const {{ get_hash(<$script>::get_const_name()) }} => {{ + return Some(Box::new(<$script>::new())) + }} + )* + _ => {{}} + }} + ) +}} + +pub fn get_script(category: ScriptCategory, name: &StringKey) -> Option> {{ + match category {{" + ) + .unwrap(); + + write_category("moves", "Move", &mut output_file); + write_category("abilities", "Ability", &mut output_file); + write_category("status", "Status", &mut output_file); + write_category("pokemon", "Pokemon", &mut output_file); + write_category("battle", "Battle", &mut output_file); + write_category("weather", "Weather", &mut output_file); + write_category("side", "Side", &mut output_file); + write_category( + "item_battle_triggers", + "ItemBattleTrigger", + &mut output_file, + ); + + write!( + output_file, + r#" + }} + None +}} + "# + ) + .unwrap(); +} + +fn write_category(path: &str, category: &str, output_file: &mut std::fs::File) { + write!( + output_file, + r" + ScriptCategory::{} => {{ + resolve_match! {{ + name.hash().unwrap(), +", + category + ) + .unwrap(); + write_scripts(path, output_file); + + write!( + output_file, + r" }} + }}," + ) + .unwrap(); +} + +fn write_scripts(path: &str, output_file: &mut std::fs::File) { + let move_files = std::fs::read_dir(format!("src/{}", path)) + .unwrap() + .map(|f| f.unwrap().path()) + .filter(|f| f.extension().unwrap() == "rs") + .map(|f| f.file_stem().unwrap().to_str().unwrap().to_string()) + .collect::>(); + for file in move_files { + println!("cargo:rerun-if-changed=src/{}/{}.rs", path, file); + let parsed = + syn::parse_file(&std::fs::read_to_string(format!("src/{}/{}.rs", path, file)).unwrap()) + .unwrap(); + // Now we need to find every impl Script for X { ... } block inside parsed + let script_impls = parsed + .items + .iter() + .filter_map(|item| match item { + syn::Item::Impl(impl_block) => match impl_block.trait_ { + Some((_, ref path, _)) => { + if path.segments[0].ident == "Script" { + Some(impl_block) + } else { + None + } + } + None => None, + }, + _ => None, + }) + .collect::>(); + for script_impl in script_impls { + match script_impl.self_ty.as_ref() { + syn::Type::Path(p) => { + let ident = p.path.segments[0].ident.to_string(); + writeln!( + output_file, + " crate::{}::{}::{},", + path, file, ident + ) + .unwrap(); + } + _ => {} + } + } + } +} diff --git a/gen_7_scripts/src/lib.rs b/gen_7_scripts/src/lib.rs index 1a4df95..8e6efee 100755 --- a/gen_7_scripts/src/lib.rs +++ b/gen_7_scripts/src/lib.rs @@ -18,6 +18,7 @@ pub mod registered_scripts; pub(crate) mod common_usings; pub mod moves; pub mod pokemon; +pub mod side; pub mod util_scripts; pub(crate) mod utils; pub mod weather; diff --git a/gen_7_scripts/src/moves/assurance.rs b/gen_7_scripts/src/moves/assurance.rs index 151785d..f2ed16b 100755 --- a/gen_7_scripts/src/moves/assurance.rs +++ b/gen_7_scripts/src/moves/assurance.rs @@ -1,4 +1,5 @@ use crate::common_usings::*; +use crate::pokemon::assurance_data::AssuranceData; use pkmn_lib_interface::PkmnResult; script!(Assurance, "assurance"); @@ -29,10 +30,7 @@ impl Script for Assurance { .get(data.target_side() as usize) .unwrap() .clone(); - side.add_volatile(Box::new(AssuranceData { - for_position: data.target_index(), - has_hit: AtomicBool::new(false), - }))?; + side.add_volatile(AssuranceData::create_for_assurance(data.target_index()))?; } Ok(()) } @@ -48,7 +46,7 @@ impl Script for Assurance { target.battle_side()?.as_ref(), AssuranceData::get_const_name(), )? { - if s.has_hit.load(Ordering::Relaxed) { + if s.has_hit() { *base_power *= 2; } } @@ -59,50 +57,3 @@ impl Script for Assurance { self } } - -script!( - AssuranceData, - "assurance_data", - for_position: u8, - has_hit: AtomicBool -); - -impl Script for AssuranceData { - fn new() -> Self { - Self { - for_position: 0, - has_hit: AtomicBool::new(false), - } - } - - fn get_name(&self) -> &'static str { - Self::get_const_name() - } - - fn get_capabilities(&self) -> &[ScriptCapabilities] { - &[ScriptCapabilities::OnEndTurn, ScriptCapabilities::OnDamage] - } - - fn on_end_turn(&self) -> PkmnResult<()> { - let side = self.get_owner().unwrap().as_side(); - side.remove_volatile(self)?; - Ok(()) - } - - fn on_damage( - &self, - pokemon: Pokemon, - _source: DamageSource, - _old_health: u32, - _new_health: u32, - ) -> PkmnResult<()> { - if pokemon.battle_index()? == self.for_position { - self.has_hit.store(true, Ordering::Relaxed); - } - Ok(()) - } - - fn as_any(&self) -> &dyn Any { - self - } -} diff --git a/gen_7_scripts/src/moves/aurora_veil.rs b/gen_7_scripts/src/moves/aurora_veil.rs index 01fea48..1715225 100644 --- a/gen_7_scripts/src/moves/aurora_veil.rs +++ b/gen_7_scripts/src/moves/aurora_veil.rs @@ -1,6 +1,5 @@ use crate::common_usings::*; -use crate::moves::light_screen::LightScreenEffect; -use crate::moves::reflect::ReflectEffect; +use crate::side::aurora_veil_effect::AuroraVeilEffect; use crate::weather::hail::Hail; use pkmn_lib_interface::PkmnResult; @@ -46,62 +45,3 @@ impl Script for AuroraVeil { 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, - ScriptCapabilities::OnEndTurn, - ] - } - - fn change_incoming_damage( - &self, - mv: ExecutingMove, - target: Pokemon, - hit: u8, - damage: &mut u32, - ) -> PkmnResult<()> { - if mv.get_hit_data(&target, hit)?.is_critical()? { - return Ok(()); - } - let side = self.get_owner().unwrap().as_side(); - if side.has_volatile(ReflectEffect::get_const_name())? - && mv.use_move().category() == MoveCategory::Physical - { - return Ok(()); - } - if side.has_volatile(LightScreenEffect::get_const_name())? - && mv.use_move().category() == MoveCategory::Special - { - return Ok(()); - } - let mut modifier = 2.0; - if target.battle()?.unwrap().pokemon_per_side()? > 1 { - modifier = 1.5 - } - *damage = (*damage as f32 / modifier) as u32; - Ok(()) - } - - fn on_end_turn(&self) -> PkmnResult<()> { - // TODO - Ok(()) - } - - fn as_any(&self) -> &dyn Any { - self - } -} diff --git a/gen_7_scripts/src/moves/flinch.rs b/gen_7_scripts/src/moves/flinch.rs index 1506542..2fa15e8 100644 --- a/gen_7_scripts/src/moves/flinch.rs +++ b/gen_7_scripts/src/moves/flinch.rs @@ -1,4 +1,5 @@ use crate::common_usings::*; +use crate::pokemon::flinch_effect::FlinchEffect; script!(Flinch, "flinch"); @@ -28,30 +29,4 @@ impl Script for Flinch { fn as_any(&self) -> &dyn Any { self } -} - -script!(FlinchEffect, "flinch_effect"); - -impl Script for FlinchEffect { - fn new() -> Self { - Self {} - } - - fn get_name(&self) -> &'static str { - Self::get_const_name() - } - - fn get_capabilities(&self) -> &[ScriptCapabilities] { - &[ScriptCapabilities::PreventMove] - } - - fn prevent_move(&self, mv: ExecutingMove, prevent: &mut bool) -> PkmnResult<()> { - *prevent = true; - mv.user().remove_volatile(self)?; - Ok(()) - } - - fn as_any(&self) -> &dyn Any { - self - } -} +} \ No newline at end of file diff --git a/gen_7_scripts/src/moves/increased_critical_stage.rs b/gen_7_scripts/src/moves/increased_critical_stage.rs new file mode 100644 index 0000000..68cd01f --- /dev/null +++ b/gen_7_scripts/src/moves/increased_critical_stage.rs @@ -0,0 +1,33 @@ +use crate::common_usings::*; +use pkmn_lib_interface::PkmnResult; + +script!(IncreasedCriticalStage, "increased_critical_stage"); + +impl Script for IncreasedCriticalStage { + fn new() -> Self { + Self {} + } + + fn get_name(&self) -> &'static str { + Self::get_const_name() + } + + fn get_capabilities(&self) -> &[ScriptCapabilities] { + &[ScriptCapabilities::ChangeCriticalStage] + } + + fn change_critical_stage( + &self, + _move: ExecutingMove, + _target: Pokemon, + _hit: u8, + stage: &mut u8, + ) -> PkmnResult<()> { + *stage += 1; + Ok(()) + } + + 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 deleted file mode 100644 index 7dac27f..0000000 --- a/gen_7_scripts/src/moves/light_screen.rs +++ /dev/null @@ -1,4 +0,0 @@ -// 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 b7ddaa9..b633c3e 100755 --- a/gen_7_scripts/src/moves/mod.rs +++ b/gen_7_scripts/src/moves/mod.rs @@ -11,8 +11,8 @@ pub mod change_target_stats; pub mod cure_party_status; pub mod drain; pub mod flinch; -pub mod light_screen; -pub mod multi_hit_move; -pub mod reflect; -pub mod struggle; pub mod heal_each_end_of_turn; +pub mod increased_critical_stage; +pub mod multi_hit_move; +pub mod prevent_foes_exit; +pub mod struggle; diff --git a/gen_7_scripts/src/moves/prevent_foes_exit.rs b/gen_7_scripts/src/moves/prevent_foes_exit.rs new file mode 100644 index 0000000..2821d97 --- /dev/null +++ b/gen_7_scripts/src/moves/prevent_foes_exit.rs @@ -0,0 +1,34 @@ +use crate::common_usings::*; +use crate::pokemon::prevent_foes_exit::PreventFoesExitEffect; + +script!(PreventFoesExist, "prevent_foes_exit"); + +impl Script for PreventFoesExist { + 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, + executing_move: ExecutingMove, + _target: Pokemon, + _hit: u8, + ) -> PkmnResult<()> { + executing_move + .user() + .add_volatile(Box::new(PreventFoesExitEffect::new()))?; + Ok(()) + } + + fn as_any(&self) -> &dyn Any { + self + } +} diff --git a/gen_7_scripts/src/pokemon/assurance_data.rs b/gen_7_scripts/src/pokemon/assurance_data.rs new file mode 100644 index 0000000..328cbf3 --- /dev/null +++ b/gen_7_scripts/src/pokemon/assurance_data.rs @@ -0,0 +1,61 @@ +use crate::common_usings::*; + +script!( + AssuranceData, + "assurance_data", + for_position: u8, + has_hit: AtomicBool +); + +impl Script for AssuranceData { + fn new() -> Self { + Self { + for_position: 0, + has_hit: AtomicBool::new(false), + } + } + + fn get_name(&self) -> &'static str { + Self::get_const_name() + } + + fn get_capabilities(&self) -> &[ScriptCapabilities] { + &[ScriptCapabilities::OnEndTurn, ScriptCapabilities::OnDamage] + } + + fn on_end_turn(&self) -> PkmnResult<()> { + let side = self.get_owner().unwrap().as_side(); + side.remove_volatile(self)?; + Ok(()) + } + + fn on_damage( + &self, + pokemon: Pokemon, + _source: DamageSource, + _old_health: u32, + _new_health: u32, + ) -> PkmnResult<()> { + if pokemon.battle_index()? == self.for_position { + self.has_hit.store(true, Ordering::Relaxed); + } + Ok(()) + } + + fn as_any(&self) -> &dyn Any { + self + } +} + +impl AssuranceData { + pub fn create_for_assurance(for_position: u8) -> Box { + Box::new(Self { + for_position, + has_hit: AtomicBool::new(false), + }) + } + + pub fn has_hit(&self) -> bool { + self.has_hit.load(Ordering::Relaxed) + } +} diff --git a/gen_7_scripts/src/pokemon/flinch_effect.rs b/gen_7_scripts/src/pokemon/flinch_effect.rs new file mode 100644 index 0000000..1f14f4b --- /dev/null +++ b/gen_7_scripts/src/pokemon/flinch_effect.rs @@ -0,0 +1,27 @@ +use crate::common_usings::*; + +script!(FlinchEffect, "flinch_effect"); + +impl Script for FlinchEffect { + fn new() -> Self { + Self {} + } + + fn get_name(&self) -> &'static str { + Self::get_const_name() + } + + fn get_capabilities(&self) -> &[ScriptCapabilities] { + &[ScriptCapabilities::PreventMove] + } + + fn prevent_move(&self, mv: ExecutingMove, prevent: &mut bool) -> PkmnResult<()> { + *prevent = true; + mv.user().remove_volatile(self)?; + Ok(()) + } + + fn as_any(&self) -> &dyn Any { + self + } +} diff --git a/gen_7_scripts/src/pokemon/mod.rs b/gen_7_scripts/src/pokemon/mod.rs index 4bbe169..f974525 100644 --- a/gen_7_scripts/src/pokemon/mod.rs +++ b/gen_7_scripts/src/pokemon/mod.rs @@ -1,2 +1,6 @@ +pub mod assurance_data; +pub mod flinch_effect; pub mod heal_each_end_of_turn; pub mod infatuated; +pub mod prevent_foes_exit; +pub mod reflect_effect; diff --git a/gen_7_scripts/src/pokemon/prevent_foes_exit.rs b/gen_7_scripts/src/pokemon/prevent_foes_exit.rs new file mode 100644 index 0000000..8457a7c --- /dev/null +++ b/gen_7_scripts/src/pokemon/prevent_foes_exit.rs @@ -0,0 +1,34 @@ +use crate::common_usings::*; + +script!(PreventFoesExitEffect, "prevent_foes_exit"); + +impl Script for PreventFoesExitEffect { + fn new() -> Self { + Self {} + } + + fn get_name(&self) -> &'static str { + Self::get_const_name() + } + + fn get_capabilities(&self) -> &[ScriptCapabilities] { + &[ + ScriptCapabilities::PreventOpponentSwitch, + ScriptCapabilities::PreventOpponentRunAway, + ] + } + + fn prevent_opponent_switch(&self, _choice: TurnChoice, prevent: &mut bool) -> PkmnResult<()> { + *prevent = true; + Ok(()) + } + + fn prevent_opponent_run_away(&self, _choice: TurnChoice, prevent: &mut bool) -> PkmnResult<()> { + *prevent = true; + Ok(()) + } + + fn as_any(&self) -> &dyn Any { + self + } +} diff --git a/gen_7_scripts/src/moves/reflect.rs b/gen_7_scripts/src/pokemon/reflect_effect.rs similarity index 100% rename from gen_7_scripts/src/moves/reflect.rs rename to gen_7_scripts/src/pokemon/reflect_effect.rs diff --git a/gen_7_scripts/src/registered_scripts.rs b/gen_7_scripts/src/registered_scripts.rs index 4f2cbd1..34cd923 100755 --- a/gen_7_scripts/src/registered_scripts.rs +++ b/gen_7_scripts/src/registered_scripts.rs @@ -1,10 +1,8 @@ -use crate::moves::*; -use crate::pokemon; -use crate::pokemon::*; +// Autogenerated file. Do not edit. + use alloc::boxed::Box; use pkmn_lib_interface::app_interface::{get_hash, StringKey}; use pkmn_lib_interface::handling::{Script, ScriptCategory}; -use pkmn_lib_interface::println; macro_rules! resolve_match { ( @@ -25,49 +23,73 @@ macro_rules! resolve_match { } pub fn get_script(category: ScriptCategory, name: &StringKey) -> Option> { - println!("Getting script {:?}", name); match category { ScriptCategory::Move => { resolve_match! { name.hash().unwrap(), - acrobatics::Acrobatics, - acupressure::Acupressure, - after_you::AfterYou, - assist::Assist, - assurance::Assurance, - attract::Attract, - aurora_veil::AuroraVeil, - automize::Automize, - change_all_target_stats::ChangeAllTargetStats, - change_target_stats::ChangeTargetAttack, - change_target_stats::ChangeTargetDefense, - change_target_stats::ChangeTargetSpecialAttack, - change_target_stats::ChangeTargetSpecialDefense, - change_target_stats::ChangeTargetSpeed, - cure_party_status::CurePartyStatus, - drain::Drain, - flinch::Flinch, + crate::moves::automize::Automize, + crate::moves::prevent_foes_exit::PreventFoesExist, + crate::moves::attract::Attract, + crate::moves::assist::Assist, + crate::moves::acupressure::Acupressure, + crate::moves::struggle::Struggle, + crate::moves::assurance::Assurance, + crate::moves::cure_party_status::CurePartyStatus, + crate::moves::multi_hit_move::MultiHitMove, crate::moves::heal_each_end_of_turn::HealEachEndOfTurn, - multi_hit_move::MultiHitMove, - struggle::Struggle, - }; - } - ScriptCategory::Ability => {} - ScriptCategory::Status => {} + crate::moves::aurora_veil::AuroraVeil, + crate::moves::change_all_target_stats::ChangeAllTargetStats, + crate::moves::after_you::AfterYou, + crate::moves::drain::Drain, + crate::moves::acrobatics::Acrobatics, + crate::moves::flinch::Flinch, + crate::moves::increased_critical_stage::IncreasedCriticalStage, + } + }, + ScriptCategory::Ability => { + resolve_match! { + name.hash().unwrap(), + } + }, + ScriptCategory::Status => { + resolve_match! { + name.hash().unwrap(), + } + }, ScriptCategory::Pokemon => { resolve_match! { name.hash().unwrap(), - infatuated::Infatuated, - pokemon::heal_each_end_of_turn::HealEachEndOfTurnEffect, + crate::pokemon::prevent_foes_exit::PreventFoesExitEffect, + crate::pokemon::assurance_data::AssuranceData, + crate::pokemon::flinch_effect::FlinchEffect, + crate::pokemon::heal_each_end_of_turn::HealEachEndOfTurnEffect, + crate::pokemon::infatuated::Infatuated, } - } + }, ScriptCategory::Battle => { - resolve_match! {name.hash().unwrap(), crate::util_scripts::ForceEffectTriggerScript,} - } - ScriptCategory::Side => {} - ScriptCategory::ItemBattleTrigger => {} - ScriptCategory::Weather => {} + resolve_match! { + name.hash().unwrap(), + } + }, + ScriptCategory::Weather => { + resolve_match! { + name.hash().unwrap(), + crate::weather::hail::Hail, + } + }, + ScriptCategory::Side => { + resolve_match! { + name.hash().unwrap(), + crate::side::light_screen::LightScreenEffect, + crate::side::aurora_veil_effect::AuroraVeilEffect, + } + }, + ScriptCategory::ItemBattleTrigger => { + resolve_match! { + name.hash().unwrap(), + } + }, } - None -} +} + \ No newline at end of file diff --git a/gen_7_scripts/src/side/aurora_veil_effect.rs b/gen_7_scripts/src/side/aurora_veil_effect.rs new file mode 100644 index 0000000..50e21ef --- /dev/null +++ b/gen_7_scripts/src/side/aurora_veil_effect.rs @@ -0,0 +1,63 @@ +use crate::common_usings::*; +use crate::pokemon::reflect_effect::ReflectEffect; +use crate::script; +use crate::side::light_screen::LightScreenEffect; + +script!(AuroraVeilEffect, "aurora_veil_effect", pub(crate) 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, + ScriptCapabilities::OnEndTurn, + ] + } + + fn change_incoming_damage( + &self, + mv: ExecutingMove, + target: Pokemon, + hit: u8, + damage: &mut u32, + ) -> PkmnResult<()> { + if mv.get_hit_data(&target, hit)?.is_critical()? { + return Ok(()); + } + let side = self.get_owner().unwrap().as_side(); + if side.has_volatile(ReflectEffect::get_const_name())? + && mv.use_move().category() == MoveCategory::Physical + { + return Ok(()); + } + if side.has_volatile(LightScreenEffect::get_const_name())? + && mv.use_move().category() == MoveCategory::Special + { + return Ok(()); + } + let mut modifier = 2.0; + if target.battle()?.unwrap().pokemon_per_side()? > 1 { + modifier = 1.5 + } + *damage = (*damage as f32 / modifier) as u32; + Ok(()) + } + + fn on_end_turn(&self) -> PkmnResult<()> { + // TODO + Ok(()) + } + + fn as_any(&self) -> &dyn Any { + self + } +} diff --git a/gen_7_scripts/src/side/light_screen.rs b/gen_7_scripts/src/side/light_screen.rs new file mode 100644 index 0000000..ced7345 --- /dev/null +++ b/gen_7_scripts/src/side/light_screen.rs @@ -0,0 +1,24 @@ +// TODO: Implementation + +use crate::script; +use core::any::Any; +use pkmn_lib_interface::handling::{Script, ScriptCapabilities}; +script!(LightScreenEffect, "light_screen_effect"); + +impl Script for LightScreenEffect { + fn new() -> Self { + Self {} + } + + fn get_name(&self) -> &'static str { + Self::get_const_name() + } + + fn get_capabilities(&self) -> &[ScriptCapabilities] { + &[] + } + + fn as_any(&self) -> &dyn Any { + self + } +} diff --git a/gen_7_scripts/src/side/mod.rs b/gen_7_scripts/src/side/mod.rs new file mode 100644 index 0000000..2f5618b --- /dev/null +++ b/gen_7_scripts/src/side/mod.rs @@ -0,0 +1,2 @@ +pub mod aurora_veil_effect; +pub mod light_screen;