From b71ea4d941805a4d5a7cbefa4a97b67c044a4eea Mon Sep 17 00:00:00 2001 From: David Gay Date: Sat, 14 Oct 2023 20:01:53 -0400 Subject: First parts of generating henchman ability scores --- src/dice.rs | 8 ++++++++ src/main.rs | 15 ++++++++++++--- src/random_tables.rs | 2 +- src/rules/npcs.rs | 42 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/dice.rs b/src/dice.rs index 2c778f4..cd6cf29 100644 --- a/src/dice.rs +++ b/src/dice.rs @@ -29,6 +29,14 @@ impl RollResult { pub fn total(&self) -> u32 { self.rolls.iter().map(|die_roll| die_roll.face).sum() } + + pub fn increase_sides_below_max(&mut self, max_value: u32, increase_by: u32) { + for roll in &mut self.rolls { + if roll.face < max_value { + roll.face += increase_by; + } + } + } } impl fmt::Display for RollResult { diff --git a/src/main.rs b/src/main.rs index 6070e06..1470811 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ use dmn::dice; use dmn::random_tables::RandomTables; +use dmn::rules::ability_scores::AbilityScore; use dmn::rules::classes::CLASSES; use dmn::rules::npcs::Npc; @@ -24,17 +25,25 @@ fn main() { eprintln!("Class '{}' not found.", &*class_name); std::process::exit(1); }); - let npc = Npc::new( + let mut npc = Npc::new( Some(random_tables.roll_table("npc_alignment")), Some(random_tables.roll_table("henchman_race")), Some(class_ref), None, ); + npc.roll_henchman_ability_scores(); + let ability_scores = npc.ability_scores.unwrap(); println!( - "{} {} {}", + "{} {} {}. STR: {}, INT: {}, WIS: {}, CON: {}, DEX: {}, CHA: {}", npc.alignment.unwrap(), npc.race.unwrap(), - npc.class.unwrap().name + npc.class.unwrap().name, + ability_scores.get_score(AbilityScore::Strength).unwrap(), + ability_scores.get_score(AbilityScore::Intelligence).unwrap(), + ability_scores.get_score(AbilityScore::Wisdom).unwrap(), + ability_scores.get_score(AbilityScore::Constitution).unwrap(), + ability_scores.get_score(AbilityScore::Dexterity).unwrap(), + ability_scores.get_score(AbilityScore::Charisma).unwrap() ); } ("magic", _) => { diff --git a/src/random_tables.rs b/src/random_tables.rs index 369f35b..831fd86 100644 --- a/src/random_tables.rs +++ b/src/random_tables.rs @@ -1,5 +1,5 @@ use crate::dice; -use crate::rules::classes::{CLASSES}; +use crate::rules::classes::CLASSES; use include_dir::{include_dir, Dir}; use serde::Deserialize; use serde_yaml; diff --git a/src/rules/npcs.rs b/src/rules/npcs.rs index c3fc86a..9cc1650 100644 --- a/src/rules/npcs.rs +++ b/src/rules/npcs.rs @@ -1,5 +1,7 @@ -use crate::rules::ability_scores::AbilityScoreCollection; +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 { @@ -23,6 +25,44 @@ impl Npc { 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. + } } // impl fmt::Display for Npc { -- cgit v1.2.3