#[cfg(test)]
mod tests {
use enshwick::abi::{DamageCheck, Header, Status};
use enshwick::damage::{DamageCause, DamageTypeNew};
use enshwick::{Load, Mod, Off};
struct Soft;
impl Mod for Soft {
fn manifest() -> &'static enshwick::abi::Manifest {
enshwick::manifest!(id: "you.soft", side: SERVER)
}
fn init(load: &mut Load<'_>) -> Result<Self, Off> {
load.on_damage(|damage| match damage.cause() {
DamageCause::FallDamage => damage.scale(0.5),
DamageCause::DeadlyFog => damage.cancel(),
DamageCause::Impact if damage.source() == Some(damage.target()) => damage.cancel(),
DamageCause::Impact => {
damage.scale_type(DamageTypeNew::MagicalFire, 2.0);
let cut = damage.amount(DamageTypeNew::PhysicalCut);
damage.set(DamageTypeNew::PhysicalCut, cut.min(10.0));
}
_ => {}
})?;
Ok(Self)
}
}
enshwick::declare_mod!(Soft);
fn check(cause: u32, target: u32, source: u32) -> DamageCheck {
DamageCheck {
header: Header::of::<DamageCheck>(),
cause,
target: enshwick::Entity(target),
source: enshwick::Entity(source),
attacker: enshwick::Entity(0),
amounts: [0.0; enshwick::abi::DAMAGE_TYPES],
total: 0.0,
}
}
#[test]
fn filters_scale_set_and_cancel_by_cause_and_type() {
let loader = enshwick::test::FakeHost::new().install();
let status = unsafe { loader.start(enshwick_mod_init, enshwick_mod_ready) };
assert_eq!(status, Status::OK);
let mut hit = check(DamageCheck::IMPACT, 2, 9);
hit.amounts[DamageTypeNew::PhysicalCut.index()] = 30.0;
hit.amounts[DamageTypeNew::MagicalFire.index()] = 5.0;
hit.amounts[DamageTypeNew::Healing.index()] = 4.0;
let after = loader.damage(hit);
assert!(
(after.amounts[DamageTypeNew::PhysicalCut.index()] - 10.0).abs() < f32::EPSILON,
"cut capped"
);
assert!(
(after.amounts[DamageTypeNew::MagicalFire.index()] - 10.0).abs() < f32::EPSILON,
"fire doubled"
);
assert!(
(after.amounts[DamageTypeNew::Healing.index()] - 4.0).abs() < f32::EPSILON,
"healing kept"
);
let mut own = check(DamageCheck::IMPACT, 2, 2);
own.amounts[DamageTypeNew::PhysicalBlunt.index()] = 12.0;
own.amounts[DamageTypeNew::Healing.index()] = 3.0;
let after = loader.damage(own);
assert!(
after.amounts[DamageTypeNew::PhysicalBlunt.index()].abs() < f32::EPSILON,
"cancelled"
);
assert!(
(after.amounts[DamageTypeNew::Healing.index()] - 3.0).abs() < f32::EPSILON,
"a cancel keeps healing"
);
let mut fall = check(DamageCheck::FALL_DAMAGE, 2, 0);
fall.total = 40.0;
assert!((loader.damage(fall).total - 20.0).abs() < f32::EPSILON);
let mut death = check(DamageCheck::DEADLY_FOG, 2, 0);
death.total = 300.0;
assert!(loader.damage(death).total.abs() < f32::EPSILON);
}
}