From f2c4ff69213c3e98bc0e679b4acce2a0d0019876 Mon Sep 17 00:00:00 2001 From: David Gay Date: Mon, 16 Oct 2023 16:30:23 -0400 Subject: NPC personalities --- src/data/random_tables/npc.yaml | 110 ++++++++++++++++++++++++++++++++++++++++ src/main.rs | 14 +++-- src/rules/npcs.rs | 16 ++++++ 3 files changed, 136 insertions(+), 4 deletions(-) diff --git a/src/data/random_tables/npc.yaml b/src/data/random_tables/npc.yaml index dbc6603..daf94e3 100644 --- a/src/data/random_tables/npc.yaml +++ b/src/data/random_tables/npc.yaml @@ -28,3 +28,113 @@ npc_alignment: - roll: 9-10 steps: - text: "Neutral" + +npc_general_appearance: + formula: d10 + rows: + - roll: 1 + steps: + - text: "dirty" + - roll: 2 + steps: + - text: "clean" + - roll: 3 + steps: + - text: "unkept" + - roll: 4 + steps: + - text: "immaculate" + - roll: 5 + steps: + - text: "rough" + - roll: 6 + steps: + - text: "ragged" + - roll: 7 + steps: + - text: "dandyish" + - roll: 8 + steps: + - text: "foppish" + - roll: 9 + steps: + - text: "non-descript" + - roll: 10 + steps: + - text: "imposing" + +npc_general_tendencies: + formula: d24 + rows: + - roll: 1 + steps: + - text: "optimist" + - roll: 2 + steps: + - text: "pessimist" + - roll: 3 + steps: + - text: "hedonist" + - roll: 4 + steps: + - text: "altruist" + - roll: 5 + steps: + - text: "helpful/kindly" + - roll: 6 + steps: + - text: "careless" + - roll: 7 + steps: + - text: "capricious/mischievous" + - roll: 8 + steps: + - text: "sober" + - roll: 9 + steps: + - text: "curious/inquisitive" + - roll: 10 + steps: + - text: "moody" + - roll: 11 + steps: + - text: "trusting" + - roll: 12 + steps: + - text: "suspicious/cautious" + - roll: 13 + steps: + - text: "precise/exacting" + - roll: 14 + steps: + - text: "perceptive" + - roll: 15 + steps: + - text: "opinionated/contrary" + - roll: 16 + steps: + - text: "violent/warlike" + - roll: 17 + steps: + - text: "studious" + - roll: 18 + steps: + - text: "foul/barbaric" + - roll: 19 + steps: + - text: "cruel/callous" + - roll: 20 + steps: + - text: "practical joker/prankster" + - roll: 21 + steps: + - text: "servile/obsequious" + - roll: 22 + steps: + - text: "fanatical/obsessive" + - roll: 23 + steps: + - text: "malevolent" + - roll: 24 + steps: + - text: "loquacious" diff --git a/src/main.rs b/src/main.rs index 20e4bcf..95f92b7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,8 +39,12 @@ fn main() { Some(race_ref), Some(class_ref), None, + None, ); + npc.roll_henchman_ability_scores(); + npc.randomize_personality(); + let ability_scores = npc.ability_scores.unwrap(); let output_csv = henchman_matches.get_flag("csv"); @@ -49,7 +53,7 @@ fn main() { // string literal at compile time. if output_csv { println!( - "{},{},{},{},{},{},{},{},{}", + "{},{},{},{},{},{},{},{},{},\"{}\"", npc.alignment .unwrap() .split_whitespace() @@ -66,11 +70,12 @@ fn main() { .get_score(AbilityScore::Constitution) .unwrap(), ability_scores.get_score(AbilityScore::Dexterity).unwrap(), - ability_scores.get_score(AbilityScore::Charisma).unwrap() + ability_scores.get_score(AbilityScore::Charisma).unwrap(), + npc.personality.unwrap(), ); } else { println!( - "{} {} {}. STR {}, INT {}, WIS {}, CON {}, DEX {}, CHA {}", + "{} {} {}. STR {}, INT {}, WIS {}, CON {}, DEX {}, CHA {}. {}", npc.alignment.unwrap(), npc.race.unwrap().name, npc.class.unwrap().name, @@ -83,7 +88,8 @@ fn main() { .get_score(AbilityScore::Constitution) .unwrap(), ability_scores.get_score(AbilityScore::Dexterity).unwrap(), - ability_scores.get_score(AbilityScore::Charisma).unwrap() + ability_scores.get_score(AbilityScore::Charisma).unwrap(), + npc.personality.unwrap(), ); }; } diff --git a/src/rules/npcs.rs b/src/rules/npcs.rs index dc65dbb..696ba0a 100644 --- a/src/rules/npcs.rs +++ b/src/rules/npcs.rs @@ -1,4 +1,5 @@ use crate::dice::roll_formula; +use crate::random_tables::RANDOM_TABLES; use crate::rules::ability_scores::{AbilityScore, AbilityScoreCollection}; use crate::rules::classes::Class; use crate::rules::races::Race; @@ -11,6 +12,7 @@ pub struct Npc { pub race: Option<&'static Race>, pub class: Option<&'static Class>, pub ability_scores: Option, + pub personality: Option, } impl Npc { @@ -19,12 +21,14 @@ impl Npc { race: Option<&'static Race>, class: Option<&'static Class>, ability_scores: Option, + personality: Option, ) -> Self { Npc { alignment, race, class, ability_scores, + personality, } } @@ -90,11 +94,23 @@ impl Npc { self.ability_scores = Some(score_collection); + // TODO: Limit human starting ability scores to 18. // 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. } + pub fn randomize_personality(&mut self) { + let appearance = RANDOM_TABLES + .roll_table("npc_general_appearance") + .to_string(); + let tendencies = RANDOM_TABLES + .roll_table("npc_general_tendencies") + .to_string(); + let components = vec![appearance, tendencies]; + self.personality = Some(components.join(", ")); + } + // TODO: Probably break this out later like this. // fn increase_prime_requisites(&mut self, roll_result: &mut RollResult) { // let class_ref = self.class.unwrap(); -- cgit v1.2.3