From a00fd7e5267183eef729765d28c67b580682cafe Mon Sep 17 00:00:00 2001 From: Lauren Kaviak Date: Sat, 21 Mar 2026 23:57:44 -0500 Subject: [PATCH] add skill modifier calculations --- src/main.rs | 246 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 222 insertions(+), 24 deletions(-) diff --git a/src/main.rs b/src/main.rs index 32dcc56..d0eb075 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,41 @@ +pub enum StandardSkills { + Acrobatics, + AnimalHandling, + Arcana, + Athletics, + Deception, + History, + Insight, + Intimidation, + Investigation, + Medicine, + Nature, + Perception, + Performance, + Persuasion, + Religion, + SleightOfHand, + Stealth, + Survival, + StrengthSave, + DexteritySave, + ConstitutionSave, + IntelligenceSave, + WisdomSave, + CharismaSave +} + +#[derive(PartialEq, Clone, Copy)] +pub enum SkillProficiency { + None, + Proficient, + Expert, +} + +impl Default for SkillProficiency { + fn default() -> Self { SkillProficiency::None } +} + pub trait Stat { fn score(&self) -> u8; @@ -5,56 +43,212 @@ pub trait Stat { return (self.score() as i8 / 2) - 5; } - fn skill(&self, proficiency: u8, proficient : bool, expert : bool) -> i8 { + fn skill_modifier(&self, proficiency_modifier: u8, proficiency: SkillProficiency) -> i8 { let modifier : i8 = self.modifier(); - let proficiency_boost : u8 = proficiency * proficient as u8; - let expertise_boost : u8 = proficiency * expert as u8; + let expert = proficiency == SkillProficiency::Expert; // are they an expert? + let proficient = expert || proficiency == SkillProficiency::Proficient; // are they at least proficient? + let proficiency_boost : u8 = proficiency_modifier * proficient as u8; + let expertise_boost : u8 = proficiency_modifier * expert as u8; return modifier + (proficiency_boost as i8) + (expertise_boost as i8); } } pub trait StatSet { - fn strength(&self) -> impl Stat; - fn dexterity(&self) -> impl Stat; - fn constitution(&self) -> impl Stat; - fn intelligence(&self) -> impl Stat; - fn wisdom(&self) -> impl Stat; - fn charisma(&self) -> impl Stat; + fn strength(&self) -> &impl Stat; + fn dexterity(&self) -> &impl Stat; + fn constitution(&self) -> &impl Stat; + fn intelligence(&self) -> &impl Stat; + fn wisdom(&self) -> &impl Stat; + fn charisma(&self) -> &impl Stat; } +pub trait ProficiencySet { + fn get_proficiency(&self, skill: StandardSkills) -> SkillProficiency; + + fn get_proficiency_modifier(&self) -> u8; +} + +pub trait Skill { + fn select_stat<'a>(&self, set: &'a impl StatSet) -> &'a dyn Stat; + + fn get_modifier(&self, set: &impl StatSet, proficiency: SkillProficiency, proficiency_modifier: u8) -> i8 { + return self.select_stat(set).skill_modifier(proficiency_modifier, proficiency); + } + + fn is_save(&self) -> bool; +} + +// pub trait SkillSet { +// fn get_skill() { + +// } +// } + impl Stat for u8 { fn score(&self) -> u8 { return *self; } } -struct Player { +impl Skill for StandardSkills { + fn select_stat<'a>(&self, set: &'a impl StatSet) -> &'a dyn Stat { + match self { + StandardSkills::DexteritySave | StandardSkills::Acrobatics | StandardSkills::SleightOfHand | StandardSkills::Stealth => set.dexterity(), + StandardSkills::StrengthSave | StandardSkills::Athletics => set.strength(), + StandardSkills::ConstitutionSave => set.constitution(), + StandardSkills::IntelligenceSave | StandardSkills::Arcana | StandardSkills::History | StandardSkills::Investigation | StandardSkills::Nature | StandardSkills::Religion => set.intelligence(), + StandardSkills::WisdomSave | StandardSkills::AnimalHandling | StandardSkills::Insight | StandardSkills::Medicine | StandardSkills::Perception | StandardSkills::Survival => set.wisdom(), + StandardSkills::CharismaSave | StandardSkills::Deception | StandardSkills::Intimidation | StandardSkills::Performance | StandardSkills::Persuasion => set.charisma(), + } + } + + fn is_save(&self) -> bool { + return matches!(self, StandardSkills::StrengthSave | StandardSkills::DexteritySave | StandardSkills::ConstitutionSave | StandardSkills::IntelligenceSave | StandardSkills::WisdomSave | StandardSkills::CharismaSave); + } +} + +pub struct Player { strength_score: u8, dexterity_score: u8, constitution_score: u8, intelligence_score: u8, wisdom_score: u8, - charisma_score: u8 + charisma_score: u8, + level: u8, + + // saves + dexterity_save_proficiency: SkillProficiency, + strength_save_proficiency: SkillProficiency, + constitution_save_proficiency: SkillProficiency, + intelligence_save_proficiency: SkillProficiency, + wisdom_save_proficiency: SkillProficiency, + charisma_save_proficiency: SkillProficiency, + + // skills + // dexterity: Acrobatics, SleightOfHand, Stealth + acrobatics_proficiency: SkillProficiency, + sleight_of_hand_proficiency: SkillProficiency, + stealth_proficiency: SkillProficiency, + // strength: Athletics + athletics_proficiency: SkillProficiency, + // constitution: none + // intelligence: Arcana, History, Investigation, Nature, Religion + arcana_proficiency: SkillProficiency, + history_proficiency: SkillProficiency, + investigation_proficiency: SkillProficiency, + nature_proficiency: SkillProficiency, + religion_proficiency: SkillProficiency, + // wisdom: Animal Handling, Insight, Medicine, Perception, Survival + animal_handling_proficiency: SkillProficiency, + insight_proficiency: SkillProficiency, + medicine_proficiency: SkillProficiency, + perception_proficiency: SkillProficiency, + survival_proficiency: SkillProficiency, + // charisma: Deception, Intimidation, Performance, Persuasion + deception_proficiency: SkillProficiency, + intimidation_proficiency: SkillProficiency, + performance_proficiency: SkillProficiency, + persuasion_proficiency: SkillProficiency +} + +impl Default for Player { + fn default() -> Self { + return Player { + strength_score: 10, + dexterity_score: 10, + constitution_score: 10, + intelligence_score: 10, + wisdom_score: 10, + charisma_score: 10, + + level: 1, + + dexterity_save_proficiency: SkillProficiency::None, + strength_save_proficiency: SkillProficiency::None, + constitution_save_proficiency: SkillProficiency::None, + intelligence_save_proficiency: SkillProficiency::None, + wisdom_save_proficiency: SkillProficiency::None, + charisma_save_proficiency: SkillProficiency::None, + + acrobatics_proficiency: SkillProficiency::None, + sleight_of_hand_proficiency: SkillProficiency::None, + stealth_proficiency: SkillProficiency::None, + + athletics_proficiency: SkillProficiency::None, + + arcana_proficiency: SkillProficiency::None, + history_proficiency: SkillProficiency::None, + investigation_proficiency: SkillProficiency::None, + nature_proficiency: SkillProficiency::None, + religion_proficiency: SkillProficiency::None, + + animal_handling_proficiency: SkillProficiency::None, + insight_proficiency: SkillProficiency::None, + medicine_proficiency: SkillProficiency::None, + perception_proficiency: SkillProficiency::None, + survival_proficiency: SkillProficiency::None, + + deception_proficiency: SkillProficiency::None, + intimidation_proficiency: SkillProficiency::None, + performance_proficiency: SkillProficiency::None, + persuasion_proficiency: SkillProficiency::None + } + } } impl StatSet for Player { - fn strength(&self) -> impl Stat { - return self.strength_score; + fn strength(&self) -> &impl Stat { + return &self.strength_score; } - fn dexterity(&self) -> impl Stat { - return self.dexterity_score; + fn dexterity(&self) -> &impl Stat { + return &self.dexterity_score; } - fn constitution(&self) -> impl Stat { - return self.constitution_score; + fn constitution(&self) -> &impl Stat { + return &self.constitution_score; } - fn intelligence(&self) -> impl Stat { - return self.intelligence_score; + fn intelligence(&self) -> &impl Stat { + return &self.intelligence_score; } - fn wisdom(&self) -> impl Stat { - return self.wisdom_score; + fn wisdom(&self) -> &impl Stat { + return &self.wisdom_score; } - fn charisma(&self) -> impl Stat { - return self.charisma_score; + fn charisma(&self) -> &impl Stat { + return &self.charisma_score; + } +} + +impl ProficiencySet for Player { + fn get_proficiency(&self, skill: StandardSkills) -> SkillProficiency { + match skill { + StandardSkills::DexteritySave => self.dexterity_save_proficiency, + StandardSkills::StrengthSave => self.strength_save_proficiency, + StandardSkills::ConstitutionSave => self.constitution_save_proficiency, + StandardSkills::IntelligenceSave => self.intelligence_save_proficiency, + StandardSkills::WisdomSave => self.wisdom_save_proficiency, + StandardSkills::CharismaSave => self.charisma_save_proficiency, + StandardSkills::Acrobatics => self.acrobatics_proficiency, + StandardSkills::SleightOfHand => self.sleight_of_hand_proficiency, + StandardSkills::Stealth => self.stealth_proficiency, + StandardSkills::Athletics => self.athletics_proficiency, + StandardSkills::Arcana => self.arcana_proficiency, + StandardSkills::History => self.history_proficiency, + StandardSkills::Investigation => self.investigation_proficiency, + StandardSkills::Nature => self.nature_proficiency, + StandardSkills::Religion => self.religion_proficiency, + StandardSkills::AnimalHandling => self.animal_handling_proficiency, + StandardSkills::Insight => self.insight_proficiency, + StandardSkills::Medicine => self.medicine_proficiency, + StandardSkills::Perception => self.perception_proficiency, + StandardSkills::Survival => self.survival_proficiency, + StandardSkills::Deception => self.deception_proficiency, + StandardSkills::Intimidation => self.intimidation_proficiency, + StandardSkills::Performance => self.performance_proficiency, + StandardSkills::Persuasion => self.persuasion_proficiency + } + } + + fn get_proficiency_modifier(&self) -> u8 { + return ((self.level - 1) / 4) + 2; } } @@ -66,7 +260,9 @@ fn main() { constitution_score: 15, intelligence_score: 10, wisdom_score: 5, - charisma_score: 1 + charisma_score: 1, + stealth_proficiency: SkillProficiency::Expert, + ..Default::default() }; println!("STR Modifier: {}", demo.strength().modifier()); @@ -75,4 +271,6 @@ fn main() { println!("INT Modifier: {}", demo.intelligence().modifier()); println!("WIS Modifier: {}", demo.wisdom().modifier()); println!("CHA Modifier: {}", demo.charisma().modifier()); + + println!("Stealth Modifier: {}", StandardSkills::Stealth.get_modifier(&demo, demo.get_proficiency(StandardSkills::Stealth), demo.get_proficiency_modifier())); }