From db8b9baf3f3887ba2a37cc4f6df867584f0755f0 Mon Sep 17 00:00:00 2001 From: David Gay Date: Mon, 22 Jan 2024 02:49:10 -0500 Subject: Simple magic item generation for 1st level NPCs --- src/data/rules/magic_items.yaml | 41 ++++++++++++++++++++++++++++++++++++ src/main.rs | 1 + src/rules/classes.rs | 2 +- src/rules/npcs.rs | 46 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/data/rules/magic_items.yaml b/src/data/rules/magic_items.yaml index c474cf0..3108e7c 100644 --- a/src/data/rules/magic_items.yaml +++ b/src/data/rules/magic_items.yaml @@ -1,3 +1,44 @@ +##### +# Dummy data, so we can at least generate kinds prior to having all magic items +# implemented. +##### + +potion: + name: "Potion" + kind: potion + +scroll: + name: "Scroll" + kind: scroll + +ring: + name: "Ring" + kind: ring + +rod_staff_wand: + name: "Rod/Staff/Wand" + kind: rod_staff_wand + +misc: + name: "Misc" + kind: misc + +armor_shield: + name: "Armor/Shield" + kind: armor_shield + +sword: + name: "Sword" + kind: sword + +protection: + name: "Protection" + kind: ring # Not actually, but this is fine for now. + +##### +# Remainder of file is actual data. +##### + sword_plus_one: name: "Sword +1" kind: sword diff --git a/src/main.rs b/src/main.rs index 4b2d91e..bc9e200 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,6 +40,7 @@ fn main() { Some(class_ref), None, None, + Vec::new(), ); npc.roll_henchman_ability_scores(); diff --git a/src/rules/classes.rs b/src/rules/classes.rs index d933bc1..1e4c24d 100644 --- a/src/rules/classes.rs +++ b/src/rules/classes.rs @@ -12,7 +12,7 @@ pub struct Class { pub prime_requisites: Vec, #[serde(default)] pub npc_ability_score_modifiers: HashMap, - pub chances_for_magic: Vec, + pub chances_for_magic: HashMap, } lazy_static! { diff --git a/src/rules/npcs.rs b/src/rules/npcs.rs index ccf9936..ab111de 100644 --- a/src/rules/npcs.rs +++ b/src/rules/npcs.rs @@ -1,9 +1,11 @@ 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::classes::{Class, CLASSES}; +use crate::rules::magic_items::{MagicItem, MAGIC_ITEMS}; use crate::rules::races::Race; use log::debug; +use rand::Rng; use std::collections::HashMap; // use std::fmt; @@ -13,6 +15,7 @@ pub struct Npc { pub class: Option<&'static Class>, pub ability_scores: Option, pub persona: Option, + pub magic_items: Vec<&'static MagicItem>, } impl Npc { @@ -22,6 +25,7 @@ impl Npc { class: Option<&'static Class>, ability_scores: Option, persona: Option, + magic_items: Vec<&'static MagicItem>, ) -> Self { Npc { alignment, @@ -29,6 +33,7 @@ impl Npc { class, ability_scores, persona, + magic_items, } } @@ -112,6 +117,44 @@ impl Npc { self.persona = Some(components.join(", ")); } + // This uses the Appendix C method provided in the city/town section. + // I prefer it to the Monster Manual method and the NPC party method + // because it provides more variance. + // TODO: Support other levels than 1st. + pub fn add_random_magic_items(&mut self) { + let mut rng = rand::thread_rng(); + let class_ref = self.class.unwrap(); + + // "Protection" isn't a real magic item kind, it's only used for this, + // which is why we don't just use MagicItemKind. Can improve this later. + let kind_strings_for_chances = [ + "sword", + "potion", + "scroll", + "ring", + "rod_staff_wand", + "misc", + "armor_shield", + "protection", + ]; + + for &kind_string in kind_strings_for_chances.iter() { + if class_ref + .chances_for_magic + .get(kind_string) + .copied() + .unwrap_or(0) + <= rng.gen_range(1..=100) + { + self.magic_items.push( + MAGIC_ITEMS + .get(kind_string) + .expect("Failed to load magic item"), + ); + } + } + } + // TODO: Probably break this out later like this. // fn increase_prime_requisites(&mut self, roll_result: &mut RollResult) { // let class_ref = self.class.unwrap(); @@ -159,6 +202,7 @@ mod tests { class: Some(class_ref), ability_scores: None, persona: None, + magic_items: Vec::new(), }; // Roll ability scores for the Npc. -- cgit v1.2.3