daggers/
daggers.rs

1use game_stat::prelude::*;
2// info: A more complex example for how you could integrate this library in a game
3// I don't think anyone would ever write it like this, but nontheless, some example code :)
4
5// in 'this specific game' we will never need more than 2 stat modifiers
6const MAX_STAT_MODIFIERS: usize = 2;
7
8pub struct DaggerItem {
9    name: String,
10    // our game data probably shouldn't deal with modifier directly
11    // a modifier will be later created using this value
12    attack_damage: f32,
13}
14
15pub struct Player {
16    inventory: Vec<DaggerItem>,
17    hand: Option<(DaggerItem, StatModifierHandle)>,
18    attack_damage_stat: Stat<MAX_STAT_MODIFIERS>,
19}
20
21impl Player {
22    pub fn new(base_attack_damage: f32) -> Self {
23        Self {
24            inventory: Vec::with_capacity(4),
25            hand: None,
26            attack_damage_stat: Stat::new(base_attack_damage),
27        }
28    }
29
30    pub fn add_item(&mut self, dagger: DaggerItem) {
31        self.inventory.push(dagger);
32    }
33
34    pub fn unequip_item(&mut self) {
35        // returns currently equiped item into inventory
36        // THE MODIFIER WILL BE DROPPED because self.hand holds the modifier key
37        if let Some(previous_equip) = self.hand.take() {
38            self.inventory.push(previous_equip.0);
39        }
40    }
41
42    pub fn equip_item_from_index(&mut self, i: usize) {
43        // return previous equipment to inventory
44        if let Some(previous_equip) = self.hand.take() {
45            self.inventory.push(previous_equip.0);
46        }
47        // move from inventory to hand
48        let new_dagger = self.inventory.remove(i);
49        // extract the modifier from the dagger stats
50        let modifier_key = self
51            .attack_damage_stat
52            .add_modifier(StatModifier::Flat(new_dagger.attack_damage));
53
54        // adding a modifier can fail if we exceed the max amount of modifiers
55        // T should be carefully selected for for Stat<T>
56        self.hand = Some((new_dagger, modifier_key));
57    }
58
59    pub fn hurt_monster(&mut self, monster: &mut Monster) {
60        monster.health -= self.attack_damage_stat.value();
61
62        // just some flavoring
63        let attack_method = match &self.hand {
64            Some(dagger) => &dagger.0.name,
65            None => "just his hands",
66        };
67        println!(
68            "using: {}, monster took: {} damage! now it has {} health",
69            attack_method,
70            self.attack_damage_stat.value(),
71            monster.health
72        );
73    }
74}
75
76pub struct Monster {
77    health: f32,
78}
79
80fn main() {
81    let mut player = Player::new(1f32);
82    player.add_item(DaggerItem {
83        name: "stabby stabby".to_string(),
84        attack_damage: 50f32,
85    });
86    let mut monster = Monster { health: 100f32 };
87
88    player.hurt_monster(&mut monster);
89
90    // our next attack will hurt!
91    player.equip_item_from_index(0);
92    player.hurt_monster(&mut monster);
93
94    // I'm weak again...
95    player.unequip_item();
96    player.hurt_monster(&mut monster);
97}