text_based_rpg 0.1.0

A text-based RPG game
Documentation
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 {
        //"Do Nothing" Weapon
        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!");
    }
}