Prevent overflows using saturating types for several script functions
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -4,6 +4,7 @@ pub use alloc::rc::Rc;
|
||||
pub use alloc::vec::Vec;
|
||||
pub use atomic_float::AtomicF32;
|
||||
pub use core::any::Any;
|
||||
pub use core::num::Saturating;
|
||||
pub use core::sync::atomic::{AtomicBool, AtomicI8, AtomicU32, Ordering};
|
||||
pub use pkmn_lib_interface::app_interface::{
|
||||
get_volatile_as, BattleSide, DamageSource, DynamicLibrary, EffectParameter, ExecutingMove,
|
||||
|
||||
@@ -21,14 +21,10 @@ impl Script for Acrobatics {
|
||||
mv: ExecutingMove,
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
base_power: &mut u8,
|
||||
base_power: &mut Saturating<u8>,
|
||||
) -> PkmnResult<()> {
|
||||
if mv.user().held_item()?.is_none() {
|
||||
if *base_power >= 128_u8 {
|
||||
*base_power = 255
|
||||
} else {
|
||||
*base_power *= 2;
|
||||
}
|
||||
*base_power *= 2;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -65,11 +61,11 @@ mod tests {
|
||||
let mv = mock_executing_move(false);
|
||||
|
||||
let script = Acrobatics::new();
|
||||
let mut base_power = 50u8;
|
||||
let mut base_power = Saturating(50u8);
|
||||
script
|
||||
.change_base_power(mv, Rc::new(MockPokemon::new()), 0, &mut base_power)
|
||||
.unwrap();
|
||||
assert_eq!(100, base_power);
|
||||
assert_eq!(100, base_power.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -77,11 +73,11 @@ mod tests {
|
||||
let mv = mock_executing_move(false);
|
||||
|
||||
let script = Acrobatics::new();
|
||||
let mut base_power = 200u8;
|
||||
let mut base_power = Saturating(200u8);
|
||||
script
|
||||
.change_base_power(mv, Rc::new(MockPokemon::new()), 0, &mut base_power)
|
||||
.unwrap();
|
||||
assert_eq!(255, base_power);
|
||||
assert_eq!(255, base_power.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -89,10 +85,10 @@ mod tests {
|
||||
let mv = mock_executing_move(true);
|
||||
|
||||
let script = Acrobatics::new();
|
||||
let mut base_power = 50u8;
|
||||
let mut base_power = Saturating(50u8);
|
||||
script
|
||||
.change_base_power(mv, Rc::new(MockPokemon::new()), 0, &mut base_power)
|
||||
.unwrap();
|
||||
assert_eq!(50, base_power);
|
||||
assert_eq!(50, base_power.0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ impl Script for Assurance {
|
||||
_move: ExecutingMove,
|
||||
target: Pokemon,
|
||||
_hit: u8,
|
||||
base_power: &mut u8,
|
||||
base_power: &mut Saturating<u8>,
|
||||
) -> PkmnResult<()> {
|
||||
if let Some(s) = get_volatile_as::<AssuranceData>(
|
||||
target.battle_side()?.as_ref(),
|
||||
|
||||
@@ -21,7 +21,7 @@ impl Script for IncreasedCriticalStage {
|
||||
_move: ExecutingMove,
|
||||
_target: Pokemon,
|
||||
_hit: u8,
|
||||
stage: &mut u8,
|
||||
stage: &mut Saturating<u8>,
|
||||
) -> PkmnResult<()> {
|
||||
*stage += 1;
|
||||
Ok(())
|
||||
|
||||
@@ -21,7 +21,11 @@ impl Script for MultiHitMove {
|
||||
&[ScriptCapabilities::ChangeNumberOfHits]
|
||||
}
|
||||
|
||||
fn change_number_of_hits(&self, choice: TurnChoice, number_of_hits: &mut u8) -> PkmnResult<()> {
|
||||
fn change_number_of_hits(
|
||||
&self,
|
||||
choice: TurnChoice,
|
||||
number_of_hits: &mut Saturating<u8>,
|
||||
) -> PkmnResult<()> {
|
||||
// 35% chance that it will hit 2 times, a 35% chance it will hit 3 times, a 15% chance it
|
||||
// will hit 4 times, and a 15% chance it will hit 5 times.
|
||||
let rand_value = choice
|
||||
@@ -30,12 +34,12 @@ impl Script for MultiHitMove {
|
||||
.unwrap()
|
||||
.random()
|
||||
.get_between(0, 100)?;
|
||||
*number_of_hits = match rand_value {
|
||||
number_of_hits.0 = match rand_value {
|
||||
0..=34 => 2,
|
||||
35..=69 => 3,
|
||||
70..=84 => 4,
|
||||
85..=100 => 5,
|
||||
_ => *number_of_hits,
|
||||
_ => number_of_hits.0,
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ impl Script for Struggle {
|
||||
fn change_number_of_hits(
|
||||
&self,
|
||||
_choice: TurnChoice,
|
||||
number_of_hits: &mut u8,
|
||||
number_of_hits: &mut Saturating<u8>,
|
||||
) -> PkmnResult<()> {
|
||||
*number_of_hits = 1;
|
||||
number_of_hits.0 = 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ impl Script for AuroraVeilEffect {
|
||||
mv: ExecutingMove,
|
||||
target: Pokemon,
|
||||
hit: u8,
|
||||
damage: &mut u32,
|
||||
damage: &mut Saturating<u32>,
|
||||
) -> PkmnResult<()> {
|
||||
if mv.get_hit_data(&target, hit)?.is_critical()? {
|
||||
return Ok(());
|
||||
@@ -48,7 +48,7 @@ impl Script for AuroraVeilEffect {
|
||||
if target.battle()?.unwrap().pokemon_per_side()? > 1 {
|
||||
modifier = 1.5
|
||||
}
|
||||
*damage = (*damage as f32 / modifier) as u32;
|
||||
damage.0 = (damage.0 as f32 / modifier) as u32;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user