Fixes for assurance, implementation of avalanche
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
ddaa2dab31
commit
3472d39bed
|
@ -12,6 +12,7 @@ crate-type = ["cdylib"]
|
||||||
pkmn_lib_interface = { path = "../pkmn_lib_interface" }
|
pkmn_lib_interface = { path = "../pkmn_lib_interface" }
|
||||||
paste = { version = "1.0.7" }
|
paste = { version = "1.0.7" }
|
||||||
atomic_float = "0.1.0"
|
atomic_float = "0.1.0"
|
||||||
|
spin = { version = "0.9.4", default-features = false, features = ["rwlock"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pkmn_lib_interface = { path = "../pkmn_lib_interface", features = ["mock_data"] }
|
pkmn_lib_interface = { path = "../pkmn_lib_interface", features = ["mock_data"] }
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
pub use crate::alloc::string::ToString;
|
||||||
pub use crate::script;
|
pub use crate::script;
|
||||||
pub use alloc::boxed::Box;
|
pub use alloc::boxed::Box;
|
||||||
pub use alloc::rc::Rc;
|
pub use alloc::rc::Rc;
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
use crate::common_usings::*;
|
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;
|
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 {
|
fn new() -> Self {
|
||||||
Self {}
|
Self {}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +33,7 @@ impl Script for Assurance {
|
||||||
.get(data.target_side() as usize)
|
.get(data.target_side() as usize)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
side.add_volatile(AssuranceData::create_for_assurance(data.target_index()))?;
|
side.add_volatile(DoublePowerIfTargetDamagedInTurnData::create_for_assurance())?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -42,11 +45,11 @@ impl Script for Assurance {
|
||||||
_hit: u8,
|
_hit: u8,
|
||||||
base_power: &mut Saturating<u8>,
|
base_power: &mut Saturating<u8>,
|
||||||
) -> PkmnResult<()> {
|
) -> PkmnResult<()> {
|
||||||
if let Some(s) = get_volatile_as::<AssuranceData>(
|
if let Some(s) = get_volatile_as::<DoublePowerIfTargetDamagedInTurnData>(
|
||||||
target.battle_side()?.as_ref(),
|
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;
|
*base_power *= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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<u8>,
|
||||||
|
) -> PkmnResult<()> {
|
||||||
|
if let Some(s) = get_volatile_as::<DoublePowerUserDamagedByTargetInTurnData>(
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,13 +2,14 @@ pub mod acrobatics;
|
||||||
pub mod acupressure;
|
pub mod acupressure;
|
||||||
pub mod after_you;
|
pub mod after_you;
|
||||||
pub mod assist;
|
pub mod assist;
|
||||||
pub mod assurance;
|
|
||||||
pub mod attract;
|
pub mod attract;
|
||||||
pub mod aurora_veil;
|
pub mod aurora_veil;
|
||||||
pub mod automize;
|
pub mod automize;
|
||||||
pub mod change_all_target_stats;
|
pub mod change_all_target_stats;
|
||||||
pub mod change_target_stats;
|
pub mod change_target_stats;
|
||||||
pub mod cure_party_status;
|
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 drain;
|
||||||
pub mod flinch;
|
pub mod flinch;
|
||||||
pub mod heal_each_end_of_turn;
|
pub mod heal_each_end_of_turn;
|
||||||
|
|
|
@ -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<dyn Script> {
|
|
||||||
Box::new(Self {
|
|
||||||
for_position,
|
|
||||||
has_hit: AtomicBool::new(false),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_hit(&self) -> bool {
|
|
||||||
self.has_hit.load(Ordering::Relaxed)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<Vec<Pokemon>>
|
||||||
|
);
|
||||||
|
|
||||||
|
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<dyn Script> {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
pub mod assurance_data;
|
pub mod double_power_user_damaged_by_target_in_turn;
|
||||||
pub mod flinch_effect;
|
pub mod flinch_effect;
|
||||||
pub mod heal_each_end_of_turn;
|
pub mod heal_each_end_of_turn;
|
||||||
pub mod infatuated;
|
pub mod infatuated;
|
||||||
|
|
|
@ -33,10 +33,11 @@ pub fn get_script(category: ScriptCategory, name: &StringKey) -> Option<Box<dyn
|
||||||
crate::moves::assist::Assist,
|
crate::moves::assist::Assist,
|
||||||
crate::moves::acupressure::Acupressure,
|
crate::moves::acupressure::Acupressure,
|
||||||
crate::moves::struggle::Struggle,
|
crate::moves::struggle::Struggle,
|
||||||
crate::moves::assurance::Assurance,
|
|
||||||
crate::moves::cure_party_status::CurePartyStatus,
|
crate::moves::cure_party_status::CurePartyStatus,
|
||||||
crate::moves::multi_hit_move::MultiHitMove,
|
crate::moves::multi_hit_move::MultiHitMove,
|
||||||
|
crate::moves::double_power_if_target_damaged_in_turn::DoublePowerIfTargetDamagedInTurn,
|
||||||
crate::moves::heal_each_end_of_turn::HealEachEndOfTurn,
|
crate::moves::heal_each_end_of_turn::HealEachEndOfTurn,
|
||||||
|
crate::moves::double_power_user_damaged_by_target_in_turn::DoublePowerUserDamagedByTargetInTurn,
|
||||||
crate::moves::aurora_veil::AuroraVeil,
|
crate::moves::aurora_veil::AuroraVeil,
|
||||||
crate::moves::change_all_target_stats::ChangeAllTargetStats,
|
crate::moves::change_all_target_stats::ChangeAllTargetStats,
|
||||||
crate::moves::after_you::AfterYou,
|
crate::moves::after_you::AfterYou,
|
||||||
|
@ -60,9 +61,9 @@ pub fn get_script(category: ScriptCategory, name: &StringKey) -> Option<Box<dyn
|
||||||
resolve_match! {
|
resolve_match! {
|
||||||
name.hash().unwrap(),
|
name.hash().unwrap(),
|
||||||
crate::pokemon::prevent_foes_exit::PreventFoesExitEffect,
|
crate::pokemon::prevent_foes_exit::PreventFoesExitEffect,
|
||||||
crate::pokemon::assurance_data::AssuranceData,
|
|
||||||
crate::pokemon::flinch_effect::FlinchEffect,
|
crate::pokemon::flinch_effect::FlinchEffect,
|
||||||
crate::pokemon::heal_each_end_of_turn::HealEachEndOfTurnEffect,
|
crate::pokemon::heal_each_end_of_turn::HealEachEndOfTurnEffect,
|
||||||
|
crate::pokemon::double_power_user_damaged_by_target_in_turn::DoublePowerUserDamagedByTargetInTurnData,
|
||||||
crate::pokemon::infatuated::Infatuated,
|
crate::pokemon::infatuated::Infatuated,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -81,6 +82,7 @@ pub fn get_script(category: ScriptCategory, name: &StringKey) -> Option<Box<dyn
|
||||||
resolve_match! {
|
resolve_match! {
|
||||||
name.hash().unwrap(),
|
name.hash().unwrap(),
|
||||||
crate::side::light_screen::LightScreenEffect,
|
crate::side::light_screen::LightScreenEffect,
|
||||||
|
crate::side::double_power_if_target_damaged_in_turn_data::DoublePowerIfTargetDamagedInTurnData,
|
||||||
crate::side::aurora_veil_effect::AuroraVeilEffect,
|
crate::side::aurora_veil_effect::AuroraVeilEffect,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
use crate::common_usings::*;
|
||||||
|
use spin::RwLock;
|
||||||
|
|
||||||
|
script!(
|
||||||
|
DoublePowerIfTargetDamagedInTurnData,
|
||||||
|
"double_power_if_target_damaged_in_turn_data",
|
||||||
|
hits: RwLock<Vec<Pokemon>>
|
||||||
|
);
|
||||||
|
|
||||||
|
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<dyn Script> {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,2 +1,3 @@
|
||||||
pub mod aurora_veil_effect;
|
pub mod aurora_veil_effect;
|
||||||
|
pub mod double_power_if_target_damaged_in_turn_data;
|
||||||
pub mod light_screen;
|
pub mod light_screen;
|
||||||
|
|
|
@ -12,7 +12,7 @@ cstr_core = { version = "0.2.6", features = ["nightly"] }
|
||||||
enumflags2 = { version = "0.7.5", default-features = false }
|
enumflags2 = { version = "0.7.5", default-features = false }
|
||||||
spin = { version = "0.9.4", default-features = false, features = ["rwlock"] }
|
spin = { version = "0.9.4", default-features = false, features = ["rwlock"] }
|
||||||
paste = { version = "1.0.7" }
|
paste = { version = "1.0.7" }
|
||||||
hashbrown = { version = "0.13.2" }
|
hashbrown = { version = "0.14.0" }
|
||||||
dlmalloc = { version = "0.2.4", features = ["global"] }
|
dlmalloc = { version = "0.2.4", features = ["global"] }
|
||||||
mockall = { version = "0.11.2", optional = true, features = ["nightly"] }
|
mockall = { version = "0.11.2", optional = true, features = ["nightly"] }
|
||||||
num-traits = { version = "0.2", default-features = false }
|
num-traits = { version = "0.2", default-features = false }
|
||||||
|
|
Loading…
Reference in New Issue