refactor into multiple files
All checks were successful
Continuous Releases / build (windows) (push) Successful in 6s
All checks were successful
Continuous Releases / build (windows) (push) Successful in 6s
This commit is contained in:
89
src/classes.rs
Normal file
89
src/classes.rs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
use crate::dice::{DieRoll, RollResult, RollCalculation, Rollable};
|
||||||
|
|
||||||
|
pub trait ShortRestRecovery {
|
||||||
|
fn on_short_rest(&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LongRestRecovery {
|
||||||
|
fn on_long_rest(&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait LevelAndHitDieManagement {
|
||||||
|
fn get_hit_die() -> u8;
|
||||||
|
|
||||||
|
fn max_hit_die(&self) -> DieRoll {
|
||||||
|
return DieRoll {
|
||||||
|
sides: Self::get_hit_die(),
|
||||||
|
count: self.get_total_levels()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expended_hit_die(&self) -> u8;
|
||||||
|
fn get_total_levels(&self) -> u8;
|
||||||
|
fn single_hit_die(&self) -> DieRoll {
|
||||||
|
return DieRoll {
|
||||||
|
sides: Self::get_hit_die(),
|
||||||
|
count: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn available_hit_die(&self) -> DieRoll {
|
||||||
|
let max = self.max_hit_die();
|
||||||
|
let expended = self.expended_hit_die();
|
||||||
|
return DieRoll {
|
||||||
|
sides: max.sides,
|
||||||
|
count: max.count - expended
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn get_historical_hit_die(&self) -> &Vec<RollResult>;
|
||||||
|
fn get_total_hp(&self) -> i32 {
|
||||||
|
let mut max_hp = 0;
|
||||||
|
let historical_hp_rolls = self.get_historical_hit_die();
|
||||||
|
for roll in historical_hp_rolls {
|
||||||
|
max_hp += roll.total;
|
||||||
|
}
|
||||||
|
return max_hp;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn level_up(&mut self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct UniversalClass {
|
||||||
|
pub levels: u8,
|
||||||
|
// reset to 0 on long rest
|
||||||
|
pub expended_hit_die: u8,
|
||||||
|
// historical, each should be immutable.
|
||||||
|
pub hit_die_history: Vec<RollResult>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LongRestRecovery for UniversalClass {
|
||||||
|
fn on_long_rest(&mut self) {
|
||||||
|
self.expended_hit_die = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LevelAndHitDieManagement for UniversalClass {
|
||||||
|
fn get_hit_die() -> u8 {
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_total_levels(&self) -> u8 {
|
||||||
|
return self.levels;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expended_hit_die(&self) -> u8 {
|
||||||
|
return self.expended_hit_die;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_historical_hit_die(&self) -> &Vec<RollResult> {
|
||||||
|
return &self.hit_die_history;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn level_up(&mut self) {
|
||||||
|
self.levels += 1;
|
||||||
|
let new_hit_die = self.single_hit_die();
|
||||||
|
self.hit_die_history.push(RollResult {
|
||||||
|
total: new_hit_die.roll(),
|
||||||
|
calculation: new_hit_die.calculation()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/dice.rs
Normal file
41
src/dice.rs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
use rand::prelude::*;
|
||||||
|
|
||||||
|
pub struct DieRoll {
|
||||||
|
pub sides: u8,
|
||||||
|
pub count: u8
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RollCalculation {
|
||||||
|
pub rolls: Vec<DieRoll>,
|
||||||
|
pub modifier: i8
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RollResult {
|
||||||
|
pub total: i32,
|
||||||
|
pub calculation: RollCalculation
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Rollable {
|
||||||
|
fn calculation(&self) -> RollCalculation;
|
||||||
|
|
||||||
|
fn roll(&self) -> i32 {
|
||||||
|
let calculation = self.calculation();
|
||||||
|
let mut total : i32 = calculation.modifier as i32;
|
||||||
|
let mut _rng = rand::rng();
|
||||||
|
for die in calculation.rolls {
|
||||||
|
for _ in 0..die.count {
|
||||||
|
total += (rand::random::<u8>() % die.sides + 1) as i32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rollable for DieRoll {
|
||||||
|
fn calculation(&self) -> RollCalculation {
|
||||||
|
return RollCalculation {
|
||||||
|
rolls: vec![DieRoll { sides: self.sides, count: self.count }],
|
||||||
|
modifier: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
383
src/main.rs
383
src/main.rs
@@ -1,381 +1,10 @@
|
|||||||
use rand::prelude::*;
|
mod dice;
|
||||||
|
mod stats_skills;
|
||||||
pub enum StandardSkills {
|
mod player;
|
||||||
Acrobatics,
|
mod classes;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DieRoll {
|
|
||||||
sides: u8,
|
|
||||||
count: u8
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RollCalculation {
|
|
||||||
rolls: Vec<DieRoll>,
|
|
||||||
modifier: i8
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RollResult {
|
|
||||||
total: i32,
|
|
||||||
calculation: RollCalculation
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Rollable {
|
|
||||||
fn calculation(&self) -> RollCalculation;
|
|
||||||
|
|
||||||
fn roll(&self) -> i32 {
|
|
||||||
let calculation = self.calculation();
|
|
||||||
let mut total : i32 = calculation.modifier as i32;
|
|
||||||
let mut _rng = rand::rng();
|
|
||||||
for die in calculation.rolls {
|
|
||||||
for _ in 0..die.count {
|
|
||||||
total += (rand::random::<u8>() % die.sides + 1) as i32;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return total;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Rollable for DieRoll {
|
|
||||||
fn calculation(&self) -> RollCalculation {
|
|
||||||
return RollCalculation {
|
|
||||||
rolls: vec![DieRoll { sides: self.sides, count: self.count }],
|
|
||||||
modifier: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ShortRestRecovery {
|
|
||||||
fn on_short_rest(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait LongRestRecovery {
|
|
||||||
fn on_long_rest(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait LevelAndHitDieManagement {
|
|
||||||
fn get_hit_die() -> u8;
|
|
||||||
|
|
||||||
fn max_hit_die(&self) -> DieRoll {
|
|
||||||
return DieRoll {
|
|
||||||
sides: Self::get_hit_die(),
|
|
||||||
count: self.get_total_levels()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expended_hit_die(&self) -> u8;
|
|
||||||
fn get_total_levels(&self) -> u8;
|
|
||||||
fn single_hit_die(&self) -> DieRoll {
|
|
||||||
return DieRoll {
|
|
||||||
sides: Self::get_hit_die(),
|
|
||||||
count: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn available_hit_die(&self) -> DieRoll {
|
|
||||||
let max = self.max_hit_die();
|
|
||||||
let expended = self.expended_hit_die();
|
|
||||||
return DieRoll {
|
|
||||||
sides: max.sides,
|
|
||||||
count: max.count - expended
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn get_historical_hit_die(&self) -> &Vec<RollResult>;
|
|
||||||
fn get_total_hp(&self) -> i32 {
|
|
||||||
let mut max_hp = 0;
|
|
||||||
let historical_hp_rolls = self.get_historical_hit_die();
|
|
||||||
for roll in historical_hp_rolls {
|
|
||||||
max_hp += roll.total;
|
|
||||||
}
|
|
||||||
return max_hp;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn level_up(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct UniversalClass {
|
|
||||||
levels: u8,
|
|
||||||
// reset to 0 on long rest
|
|
||||||
expended_hit_die: u8,
|
|
||||||
// historical, each should be immutable.
|
|
||||||
hit_die_history: Vec<RollResult>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LongRestRecovery for UniversalClass {
|
|
||||||
fn on_long_rest(&mut self) {
|
|
||||||
self.expended_hit_die = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LevelAndHitDieManagement for UniversalClass {
|
|
||||||
fn get_hit_die() -> u8 {
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_total_levels(&self) -> u8 {
|
|
||||||
return self.levels;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expended_hit_die(&self) -> u8 {
|
|
||||||
return self.expended_hit_die;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_historical_hit_die(&self) -> &Vec<RollResult> {
|
|
||||||
return &self.hit_die_history;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn level_up(&mut self) {
|
|
||||||
self.levels += 1;
|
|
||||||
let new_hit_die = self.single_hit_die();
|
|
||||||
self.hit_die_history.push(RollResult {
|
|
||||||
total: new_hit_die.roll(),
|
|
||||||
calculation: new_hit_die.calculation()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Stat for u8 {
|
|
||||||
fn score(&self) -> u8 {
|
|
||||||
return *self;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
|
||||||
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 dexterity(&self) -> &impl Stat {
|
|
||||||
return &self.dexterity_score;
|
|
||||||
}
|
|
||||||
fn constitution(&self) -> &impl Stat {
|
|
||||||
return &self.constitution_score;
|
|
||||||
}
|
|
||||||
fn intelligence(&self) -> &impl Stat {
|
|
||||||
return &self.intelligence_score;
|
|
||||||
}
|
|
||||||
fn wisdom(&self) -> &impl Stat {
|
|
||||||
return &self.wisdom_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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
use stats_skills::{StandardSkills, SkillProficiency, Skill, ProficiencySet, StatSet, Stat};
|
||||||
|
use player::Player;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let demo : Player = Player {
|
let demo : Player = Player {
|
||||||
|
|||||||
146
src/player.rs
Normal file
146
src/player.rs
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
use crate::stats_skills::{Stat, StatSet, ProficiencySet, SkillProficiency, StandardSkills};
|
||||||
|
|
||||||
|
pub struct Player {
|
||||||
|
pub strength_score: u8,
|
||||||
|
pub dexterity_score: u8,
|
||||||
|
pub constitution_score: u8,
|
||||||
|
pub intelligence_score: u8,
|
||||||
|
pub wisdom_score: u8,
|
||||||
|
pub charisma_score: u8,
|
||||||
|
pub level: u8,
|
||||||
|
|
||||||
|
// saves
|
||||||
|
pub dexterity_save_proficiency: SkillProficiency,
|
||||||
|
pub strength_save_proficiency: SkillProficiency,
|
||||||
|
pub constitution_save_proficiency: SkillProficiency,
|
||||||
|
pub intelligence_save_proficiency: SkillProficiency,
|
||||||
|
pub wisdom_save_proficiency: SkillProficiency,
|
||||||
|
pub charisma_save_proficiency: SkillProficiency,
|
||||||
|
|
||||||
|
// skills
|
||||||
|
// dexterity: Acrobatics, SleightOfHand, Stealth
|
||||||
|
pub acrobatics_proficiency: SkillProficiency,
|
||||||
|
pub sleight_of_hand_proficiency: SkillProficiency,
|
||||||
|
pub stealth_proficiency: SkillProficiency,
|
||||||
|
// strength: Athletics
|
||||||
|
pub athletics_proficiency: SkillProficiency,
|
||||||
|
// constitution: none
|
||||||
|
// intelligence: Arcana, History, Investigation, Nature, Religion
|
||||||
|
pub arcana_proficiency: SkillProficiency,
|
||||||
|
pub history_proficiency: SkillProficiency,
|
||||||
|
pub investigation_proficiency: SkillProficiency,
|
||||||
|
pub nature_proficiency: SkillProficiency,
|
||||||
|
pub religion_proficiency: SkillProficiency,
|
||||||
|
// wisdom: Animal Handling, Insight, Medicine, Perception, Survival
|
||||||
|
pub animal_handling_proficiency: SkillProficiency,
|
||||||
|
pub insight_proficiency: SkillProficiency,
|
||||||
|
pub medicine_proficiency: SkillProficiency,
|
||||||
|
pub perception_proficiency: SkillProficiency,
|
||||||
|
pub survival_proficiency: SkillProficiency,
|
||||||
|
// charisma: Deception, Intimidation, Performance, Persuasion
|
||||||
|
pub deception_proficiency: SkillProficiency,
|
||||||
|
pub intimidation_proficiency: SkillProficiency,
|
||||||
|
pub performance_proficiency: SkillProficiency,
|
||||||
|
pub 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 dexterity(&self) -> &impl Stat {
|
||||||
|
return &self.dexterity_score;
|
||||||
|
}
|
||||||
|
fn constitution(&self) -> &impl Stat {
|
||||||
|
return &self.constitution_score;
|
||||||
|
}
|
||||||
|
fn intelligence(&self) -> &impl Stat {
|
||||||
|
return &self.intelligence_score;
|
||||||
|
}
|
||||||
|
fn wisdom(&self) -> &impl Stat {
|
||||||
|
return &self.wisdom_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;
|
||||||
|
}
|
||||||
|
}
|
||||||
102
src/stats_skills.rs
Normal file
102
src/stats_skills.rs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user