From f585f5db852a34e2a6089bd460e7c68b8833ca4a Mon Sep 17 00:00:00 2001 From: David Gay Date: Sat, 14 Oct 2023 17:55:57 -0400 Subject: Partial implementation of Class struct --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/main.rs | 35 +++++++++++++++++++++++++++++------ src/random_tables.rs | 4 ++-- src/rules/ability_scores.rs | 5 ++++- src/rules/classes.rs | 11 +++++++++-- src/rules/npcs.rs | 39 +++++++++++++++++++++++++++++++++++++-- 7 files changed, 89 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0c85df6..d196a6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,6 +95,7 @@ version = "0.0.1" dependencies = [ "clap", "include_dir", + "lazy_static", "rand", "serde", "serde_yaml", @@ -158,6 +159,12 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + [[package]] name = "libc" version = "0.2.148" diff --git a/Cargo.toml b/Cargo.toml index f646014..24c9a81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ categories = ["command-line-utilities", "games"] [dependencies] clap = { version = "^4.4", features = ["cargo"] } include_dir = "0.7.3" +lazy_static = "1.4.0" rand = "^0.8" serde = { version = "^1.0", features = ["derive"] } serde_yaml = "^0.9" diff --git a/src/main.rs b/src/main.rs index 7887a90..e2c46ac 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,22 +1,45 @@ +use lazy_static::lazy_static; + use dmn::dice; use dmn::random_tables::RandomTables; +use dmn::rules::classes::Classes; +use dmn::rules::npcs::Npc; mod cli; +lazy_static! { + static ref CLASSES: Classes = Classes::new().expect("Failed to load classes."); +} + fn main() { let matches = cli::cli().get_matches(); - let random_tables = RandomTables::new().unwrap(); + let random_tables = RandomTables::new().expect("Failed to load random tables."); match matches.subcommand() { Some(("random", sub_matches)) => { - // TODO: Do something better than unwrap here. let random_command = sub_matches.subcommand().unwrap(); match random_command { ("henchman", _) => { - let race = random_tables.roll_table("henchman_race"); - let alignment = random_tables.roll_table("npc_alignment"); - let class = random_tables.roll_table("henchman_class"); - println!("{} {} {}", alignment, race, class); + let class_name = random_tables.roll_table("henchman_class").to_string(); + let class_ref = match CLASSES.class(&class_name) { + Ok(class_ref) => class_ref, + Err(err) => { + eprintln!("Error: {}", err); + std::process::exit(1); + } + }; + let npc = Npc::new( + Some(random_tables.roll_table("npc_alignment")), + Some(random_tables.roll_table("henchman_race")), + Some(class_ref), + None, + ); + println!( + "{} {} {}", + npc.alignment.unwrap(), + npc.race.unwrap(), + npc.class.unwrap().name + ); } ("magic", _) => { let magic = random_tables.roll_table("ua_magic"); diff --git a/src/random_tables.rs b/src/random_tables.rs index 600922c..07f0022 100644 --- a/src/random_tables.rs +++ b/src/random_tables.rs @@ -72,8 +72,8 @@ impl RandomTables { if let Some(class_string) = &step.class { let classes = Classes::new().unwrap(); - let class = classes.class(class_string) - .expect("Failed to load class."); + let class = + classes.class(class_string).expect("Failed to load class."); output_text.push_str(&*class.name); } diff --git a/src/rules/ability_scores.rs b/src/rules/ability_scores.rs index f255d4f..205c1a3 100644 --- a/src/rules/ability_scores.rs +++ b/src/rules/ability_scores.rs @@ -37,7 +37,10 @@ impl AbilityScoreCollection { } pub fn add_score(&mut self, ability_score: AbilityScore, bonus: u32) { - self.scores.entry(ability_score).or_insert_with(Vec::new).push(bonus); + self.scores + .entry(ability_score) + .or_insert_with(Vec::new) + .push(bonus); } pub fn get_score(&self, ability_score: AbilityScore) -> Option<&Vec> { diff --git a/src/rules/classes.rs b/src/rules/classes.rs index 5cd29d6..cc827f0 100644 --- a/src/rules/classes.rs +++ b/src/rules/classes.rs @@ -3,6 +3,7 @@ use serde::Deserialize; use serde_yaml; use std::collections::HashMap; use std::error::Error; +// use std::fmt; use std::string::String; #[derive(Deserialize)] @@ -31,7 +32,13 @@ impl Classes { Ok(Classes { classes }) } - pub fn class(&self, class_name: &str) -> Option<&Class> { - self.classes.get(class_name) + pub fn class(&self, class_name: &str) -> Result<&Class, &'static str> { + self.classes.get(class_name).ok_or("Class not found.") } } +// +// impl fmt::Display for Class { +// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +// write!(f, "{}", self.name) +// } +// } diff --git a/src/rules/npcs.rs b/src/rules/npcs.rs index 67eeb47..c3fc86a 100644 --- a/src/rules/npcs.rs +++ b/src/rules/npcs.rs @@ -1,7 +1,42 @@ use crate::rules::ability_scores::AbilityScoreCollection; use crate::rules::classes::Class; +// use std::fmt; pub struct Npc { - pub class: Class, - pub ability_score_collection: AbilityScoreCollection, + 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, + } + } +} + +// 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) +// } +// } -- cgit v1.2.3