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; fn modifier(&self) -> i8 { return (self.score() as i8 / 2) - 5; } fn skill_modifier(&self, proficiency_modifier: u8, proficiency: SkillProficiency) -> i8 { let modifier : i8 = self.modifier(); 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; } 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; } 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); } } impl Stat for u8 { fn score(&self) -> u8 { return *self; } }