use crate::entity::Entity;
use std::rc::Rc;
pub struct Weapon {
pub name: String,
pub damage: i32,
pub effect: Rc<dyn Fn(&mut dyn Entity)>,
}
impl Clone for Weapon {
fn clone(&self) -> Self {
Weapon {
name: self.name.clone(),
damage: self.damage.clone(),
effect: self.effect.clone(),
}
}
}
impl Default for Weapon {
fn default() -> Self {
Weapon {
name: "Default Weapon".to_string(),
damage: 0,
effect: Rc::new(|_| println!("Default Effect Applied")),
}
}
}
impl Weapon {
pub fn new<F>(name: &str, damage: i32, effect: F) -> Self
where
F: Fn(&mut dyn Entity) + 'static,
{
Weapon {
name: name.to_string(),
damage,
effect: Rc::new(effect),
}
}
pub fn apply(&self, target: &mut dyn Entity) {
target.take_damage(self.damage);
(self.effect)(target)
}
}
#[cfg(test)]
mod tests {
use crate::entity::{Enemy, Entity};
use super::Weapon;
#[test]
fn apply_10_damage_and_10_effect_damage() {
let attack_weapon = Weapon::new("Attack Weapon", 10, |target| target.take_damage(10));
let mut training_dummy = Enemy::default();
let initial_health = training_dummy.get_current_health();
attack_weapon.apply(&mut training_dummy);
let final_health = training_dummy.get_current_health();
assert_eq!(initial_health - 20, final_health, "Hero did not take 20 damage!");
}
}