summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/data/random_tables/npc.yaml110
-rw-r--r--src/main.rs14
-rw-r--r--src/rules/npcs.rs16
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<AbilityScoreCollection>,
+ pub personality: Option<String>,
}
impl Npc {
@@ -19,12 +21,14 @@ impl Npc {
race: Option<&'static Race>,
class: Option<&'static Class>,
ability_scores: Option<AbilityScoreCollection>,
+ personality: Option<String>,
) -> 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();