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, pub race: Option, pub class: Option<&'static Class>, pub ability_scores: Option, } impl Npc { pub fn new( alignment: Option, race: Option, class: Option<&'static Class>, ability_scores: Option, ) -> Self { Npc { alignment, race, class, ability_scores, } } pub fn roll_henchman_ability_scores(&mut self) { rand::thread_rng(); let mut ability_score_rolls: HashMap = 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. // TODO: Apply racial minimums and maximums. // TODO: Verify legality of class based on alignment. // TODO: Verify legality of class based on race. // TODO: Verify legality of class based on ability scores. } } // 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) // } // }