From 3472d39bed3fe333897fe8b506836ad1939a27cd Mon Sep 17 00:00:00 2001 From: Deukhoofd Date: Fri, 30 Jun 2023 18:03:57 +0200 Subject: [PATCH] Fixes for assurance, implementation of avalanche --- gen_7_scripts/Cargo.toml | 1 + gen_7_scripts/src/common_usings.rs | 1 + ...double_power_if_target_damaged_in_turn.rs} | 17 ++-- ...le_power_user_damaged_by_target_in_turn.rs | 53 ++++++++++++ gen_7_scripts/src/moves/mod.rs | 3 +- gen_7_scripts/src/pokemon/assurance_data.rs | 61 -------------- ...le_power_user_damaged_by_target_in_turn.rs | 81 +++++++++++++++++++ gen_7_scripts/src/pokemon/mod.rs | 2 +- gen_7_scripts/src/registered_scripts.rs | 6 +- ...le_power_if_target_damaged_in_turn_data.rs | 68 ++++++++++++++++ gen_7_scripts/src/side/mod.rs | 1 + pkmn_lib_interface/Cargo.toml | 2 +- 12 files changed, 223 insertions(+), 73 deletions(-) rename gen_7_scripts/src/moves/{assurance.rs => double_power_if_target_damaged_in_turn.rs} (68%) create mode 100644 gen_7_scripts/src/moves/double_power_user_damaged_by_target_in_turn.rs delete mode 100644 gen_7_scripts/src/pokemon/assurance_data.rs create mode 100644 gen_7_scripts/src/pokemon/double_power_user_damaged_by_target_in_turn.rs create mode 100644 gen_7_scripts/src/side/double_power_if_target_damaged_in_turn_data.rs diff --git a/gen_7_scripts/Cargo.toml b/gen_7_scripts/Cargo.toml index a0d5e2f..5b75261 100755 --- a/gen_7_scripts/Cargo.toml +++ b/gen_7_scripts/Cargo.toml @@ -12,6 +12,7 @@ crate-type = ["cdylib"] pkmn_lib_interface = { path = "../pkmn_lib_interface" } paste = { version = "1.0.7" } atomic_float = "0.1.0" +spin = { version = "0.9.4", default-features = false, features = ["rwlock"] } [dev-dependencies] pkmn_lib_interface = { path = "../pkmn_lib_interface", features = ["mock_data"] } diff --git a/gen_7_scripts/src/common_usings.rs b/gen_7_scripts/src/common_usings.rs index 77d471d..e33273c 100644 --- a/gen_7_scripts/src/common_usings.rs +++ b/gen_7_scripts/src/common_usings.rs @@ -1,3 +1,4 @@ +pub use crate::alloc::string::ToString; pub use crate::script; pub use alloc::boxed::Box; pub use alloc::rc::Rc; diff --git a/gen_7_scripts/src/moves/assurance.rs b/gen_7_scripts/src/moves/double_power_if_target_damaged_in_turn.rs similarity index 68% rename from gen_7_scripts/src/moves/assurance.rs rename to gen_7_scripts/src/moves/double_power_if_target_damaged_in_turn.rs index dd48a23..c494fff 100755 --- a/gen_7_scripts/src/moves/assurance.rs +++ b/gen_7_scripts/src/moves/double_power_if_target_damaged_in_turn.rs @@ -1,10 +1,13 @@ use crate::common_usings::*; -use crate::pokemon::assurance_data::AssuranceData; +use crate::side::double_power_if_target_damaged_in_turn_data::DoublePowerIfTargetDamagedInTurnData; use pkmn_lib_interface::PkmnResult; -script!(Assurance, "assurance"); +script!( + DoublePowerIfTargetDamagedInTurn, + "double_power_if_target_damaged_in_turn" +); -impl Script for Assurance { +impl Script for DoublePowerIfTargetDamagedInTurn { fn new() -> Self { Self {} } @@ -30,7 +33,7 @@ impl Script for Assurance { .get(data.target_side() as usize) .unwrap() .clone(); - side.add_volatile(AssuranceData::create_for_assurance(data.target_index()))?; + side.add_volatile(DoublePowerIfTargetDamagedInTurnData::create_for_assurance())?; } Ok(()) } @@ -42,11 +45,11 @@ impl Script for Assurance { _hit: u8, base_power: &mut Saturating, ) -> PkmnResult<()> { - if let Some(s) = get_volatile_as::( + if let Some(s) = get_volatile_as::( target.battle_side()?.as_ref(), - AssuranceData::get_const_name(), + DoublePowerIfTargetDamagedInTurnData::get_const_name(), )? { - if s.has_hit() { + if s.has_hit_for_pokemon(&target) { *base_power *= 2; } } diff --git a/gen_7_scripts/src/moves/double_power_user_damaged_by_target_in_turn.rs b/gen_7_scripts/src/moves/double_power_user_damaged_by_target_in_turn.rs new file mode 100644 index 0000000..4a56cc6 --- /dev/null +++ b/gen_7_scripts/src/moves/double_power_user_damaged_by_target_in_turn.rs @@ -0,0 +1,53 @@ +use crate::common_usings::*; +use crate::pokemon::double_power_user_damaged_by_target_in_turn::DoublePowerUserDamagedByTargetInTurnData; +use pkmn_lib_interface::PkmnResult; + +script!( + DoublePowerUserDamagedByTargetInTurn, + "double_power_user_damaged_by_target_in_turn" +); + +impl Script for DoublePowerUserDamagedByTargetInTurn { + fn new() -> Self { + Self {} + } + + fn get_name(&self) -> &'static str { + Self::get_const_name() + } + + fn get_capabilities(&self) -> &[ScriptCapabilities] { + &[ + ScriptCapabilities::OnBeforeTurn, + ScriptCapabilities::ChangeBasePower, + ] + } + + fn on_before_turn(&self, choice: TurnChoice) -> PkmnResult<()> { + let user = choice.user(); + user.add_volatile(DoublePowerUserDamagedByTargetInTurnData::create())?; + Ok(()) + } + + fn change_base_power( + &self, + _move: ExecutingMove, + target: Pokemon, + _hit: u8, + base_power: &mut Saturating, + ) -> PkmnResult<()> { + if let Some(s) = get_volatile_as::( + target.battle_side()?.as_ref(), + DoublePowerUserDamagedByTargetInTurnData::get_const_name(), + )? { + if s.has_been_hit_by_pokemon(&target) { + *base_power *= 2; + } + } + Ok(()) + } + + fn as_any(&self) -> &dyn Any { + self + } +} diff --git a/gen_7_scripts/src/moves/mod.rs b/gen_7_scripts/src/moves/mod.rs index b633c3e..61d76f8 100755 --- a/gen_7_scripts/src/moves/mod.rs +++ b/gen_7_scripts/src/moves/mod.rs @@ -2,13 +2,14 @@ pub mod acrobatics; pub mod acupressure; pub mod after_you; 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 cure_party_status; +pub mod double_power_if_target_damaged_in_turn; +pub mod double_power_user_damaged_by_target_in_turn; pub mod drain; pub mod flinch; pub mod heal_each_end_of_turn; diff --git a/gen_7_scripts/src/pokemon/assurance_data.rs b/gen_7_scripts/src/pokemon/assurance_data.rs deleted file mode 100644 index 328cbf3..0000000 --- a/gen_7_scripts/src/pokemon/assurance_data.rs +++ /dev/null @@ -1,61 +0,0 @@ -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/double_power_user_damaged_by_target_in_turn.rs b/gen_7_scripts/src/pokemon/double_power_user_damaged_by_target_in_turn.rs new file mode 100644 index 0000000..b21c9a6 --- /dev/null +++ b/gen_7_scripts/src/pokemon/double_power_user_damaged_by_target_in_turn.rs @@ -0,0 +1,81 @@ +use crate::common_usings::*; +use pkmn_lib_interface::{pkmn_err, PkmnErr}; +use spin::RwLock; + +script!( + DoublePowerUserDamagedByTargetInTurnData, + "double_power_user_damaged_by_target_in_turn_data", + hits: RwLock> +); + +impl Script for DoublePowerUserDamagedByTargetInTurnData { + fn new() -> Self { + Self { + hits: Default::default(), + } + } + + fn get_name(&self) -> &'static str { + Self::get_const_name() + } + + fn get_capabilities(&self) -> &[ScriptCapabilities] { + &[ + ScriptCapabilities::OnEndTurn, + ScriptCapabilities::OnIncomingHit, + ] + } + + fn on_incoming_hit( + &self, + executing_move: ExecutingMove, + target: Pokemon, + hit: u8, + ) -> PkmnResult<()> { + // Only register hits that dealt damage + if executing_move + .get_hit_data(&target, hit) + .or(Err(pkmn_err!("Couldnt resolve hit")))? + .damage()? + == 0 + { + return Ok(()); + } + let user = executing_move.user(); + let mut write_lock = self.hits.write(); + // Check if the pokemon has already hit the pokemon. Bail out if it has. + for hit_pokemon in write_lock.iter() { + if hit_pokemon.reference() == user.reference() { + return Ok(()); + } + } + write_lock.push(user); + Ok(()) + } + + fn on_end_turn(&self) -> PkmnResult<()> { + let pokemon = self.get_owner().unwrap().as_pokemon(); + pokemon.remove_volatile(self)?; + Ok(()) + } + + fn as_any(&self) -> &dyn Any { + self + } +} + +impl DoublePowerUserDamagedByTargetInTurnData { + pub fn create() -> Box { + Box::new(Self::new()) + } + + pub fn has_been_hit_by_pokemon(&self, pokemon: &Pokemon) -> bool { + let read_lock = self.hits.read(); + for hit_pokemon in read_lock.iter() { + if hit_pokemon.reference() == pokemon.reference() { + return true; + } + } + false + } +} diff --git a/gen_7_scripts/src/pokemon/mod.rs b/gen_7_scripts/src/pokemon/mod.rs index f974525..37ccfb2 100644 --- a/gen_7_scripts/src/pokemon/mod.rs +++ b/gen_7_scripts/src/pokemon/mod.rs @@ -1,4 +1,4 @@ -pub mod assurance_data; +pub mod double_power_user_damaged_by_target_in_turn; pub mod flinch_effect; pub mod heal_each_end_of_turn; pub mod infatuated; diff --git a/gen_7_scripts/src/registered_scripts.rs b/gen_7_scripts/src/registered_scripts.rs index 34cd923..023970f 100755 --- a/gen_7_scripts/src/registered_scripts.rs +++ b/gen_7_scripts/src/registered_scripts.rs @@ -33,10 +33,11 @@ pub fn get_script(category: ScriptCategory, name: &StringKey) -> Option Option Option> +); + +impl Script for DoublePowerIfTargetDamagedInTurnData { + fn new() -> Self { + Self { + hits: Default::default(), + } + } + + 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<()> { + let mut write_lock = self.hits.write(); + for hit_pokemon in write_lock.iter() { + if hit_pokemon.reference() == pokemon.reference() { + return Ok(()); + } + } + write_lock.push(pokemon); + Ok(()) + } + + fn as_any(&self) -> &dyn Any { + self + } +} + +impl DoublePowerIfTargetDamagedInTurnData { + pub fn create_for_assurance() -> Box { + Box::new(Self { + hits: Default::default(), + }) + } + + pub fn has_hit_for_pokemon(&self, pokemon: &Pokemon) -> bool { + for hit_pokemon in self.hits.read().iter() { + if hit_pokemon.reference() == pokemon.reference() { + return true; + } + } + false + } +} diff --git a/gen_7_scripts/src/side/mod.rs b/gen_7_scripts/src/side/mod.rs index 2f5618b..e39dd3b 100644 --- a/gen_7_scripts/src/side/mod.rs +++ b/gen_7_scripts/src/side/mod.rs @@ -1,2 +1,3 @@ pub mod aurora_veil_effect; +pub mod double_power_if_target_damaged_in_turn_data; pub mod light_screen; diff --git a/pkmn_lib_interface/Cargo.toml b/pkmn_lib_interface/Cargo.toml index 6d9ed6a..1bb3c4f 100755 --- a/pkmn_lib_interface/Cargo.toml +++ b/pkmn_lib_interface/Cargo.toml @@ -12,7 +12,7 @@ cstr_core = { version = "0.2.6", features = ["nightly"] } enumflags2 = { version = "0.7.5", default-features = false } spin = { version = "0.9.4", default-features = false, features = ["rwlock"] } paste = { version = "1.0.7" } -hashbrown = { version = "0.13.2" } +hashbrown = { version = "0.14.0" } dlmalloc = { version = "0.2.4", features = ["global"] } mockall = { version = "0.11.2", optional = true, features = ["nightly"] } num-traits = { version = "0.2", default-features = false }