summaryrefslogtreecommitdiff
path: root/src/rules/npcs.rs
blob: 9cc1650f5b158429aced5116fce155cdd259f27b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use crate::dice::{roll_formula, RollResult};
use crate::rules::ability_scores::{AbilityScore, AbilityScoreCollection};
use crate::rules::classes::Class;
use std::collections::HashMap;
// use std::fmt;

pub struct Npc {
    pub alignment: Option<String>,
    pub race: Option<String>,
    pub class: Option<&'static Class>,
    pub ability_scores: Option<AbilityScoreCollection>,
}

impl Npc {
    pub fn new(
        alignment: Option<String>,
        race: Option<String>,
        class: Option<&'static Class>,
        ability_scores: Option<AbilityScoreCollection>,
    ) -> Self {
        Npc {
            alignment,
            race,
            class,
            ability_scores,
        }
    }

    pub fn roll_henchman_ability_scores(&mut self) {
        rand::thread_rng();
        let mut ability_score_rolls: HashMap<AbilityScore, RollResult> = HashMap::new();

        for &ability in &[
            AbilityScore::Strength,
            AbilityScore::Intelligence,
            AbilityScore::Wisdom,
            AbilityScore::Dexterity,
            AbilityScore::Constitution,
            AbilityScore::Charisma,
        ] {
            // Roll 3d6 down the line.
            let mut roll_result = roll_formula("3d6").unwrap();
            let class_ref = self.class.unwrap();

            // For ability scores which are prime requisites of the class,
            // increase all dice by 1 which do not already show a 6.
            if class_ref.prime_requisites.contains(&ability) {
                roll_result.increase_sides_below_max(6, 1);
            }

            ability_score_rolls.insert(ability, roll_result);
        }

        // Create an AbilityScoreCollection for the Npc, using the above results.
        let mut score_collection = AbilityScoreCollection::new();
        for (ability, roll_result) in &ability_score_rolls {
            let total_score = roll_result.total();
            score_collection.add_score(*ability, total_score);
        }

        self.ability_scores = Some(score_collection);

        // TODO: Modify results for race.
        // TODO: Modify results for henchmen-specific class bonuses.
    }
}

// impl fmt::Display for Npc {
//     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
//         let values: Vec<&str> = vec![
//             self.alignment.as_deref().unwrap_or(""),
//             self.race.as_deref().unwrap_or(""),
//             self.class.as_ref().map_or("", |class| &class.name),
//         ]
//         .into_iter()
//         .filter(|&s| !s.is_empty())
//         .collect();
//
//         let formatted_string = values.join(" ");
//         write!(f, "{}", formatted_string)
//     }
// }