#[cfg(feature = "api")]
pub mod api;
pub mod abilities;
pub mod classes;
use std::fmt;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::abilities::{Abilities};
use crate::classes::Classes;
#[derive(Debug)]
pub struct UnexpectedAbility;
impl fmt::Display for UnexpectedAbility {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "The ability isn't present in the character's abilities")
}
}
impl std::error::Error for UnexpectedAbility {}
#[derive(Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))]
pub struct Character {
pub classes: Classes,
pub name: String,
pub age: u16,
pub race_index: String,
pub subrace_index: String,
pub alignment_index: String,
pub description: String,
pub background_index: String,
pub background_description: String,
experience_points: u32,
pub money: u32,
pub abilities_score: Abilities,
pub hp: u16,
pub max_hp: u16,
pub inventory: Vec<String>,
pub other: Vec<String>,
}
const LEVELS: [u32; 19] = [300, 900, 2_700, 6_500, 14_000, 23_000, 34_000, 48_000, 64_000, 85_000, 100_000, 120_000, 140_000, 165_000, 195_000, 225_000, 265_000, 305_000, 355_000];
impl Character {
pub fn new(main_class: String, name: String, age: u16, race_index: String, subrace_index: String, alignment_index: String, description: String, background_index: String, background_description: String) -> Self {
Self {
classes: Classes::new(main_class),
name,
age,
race_index,
subrace_index,
alignment_index,
description,
background_index,
background_description,
experience_points: 0,
money: 0,
inventory: Vec::new(),
abilities_score: Abilities::default(),
hp: 0,
max_hp: 0,
other: vec![],
}
}
pub fn class_armor(&self) -> i8 {
match self.classes.0.iter().next().unwrap().0.as_str() {
"monk" => {
10 + self.abilities_score.dexterity.modifier(0) + self.abilities_score.wisdom.modifier(0)
}
_ => {
10 + self.abilities_score.dexterity.modifier(0)
}
}
}
pub fn level(&self) -> u8 {
LEVELS.iter().filter(|&&x| x <= self.experience_points).count() as u8 + 1
}
pub fn experience_points(&self) -> u32 {
self.experience_points
}
pub fn add_experience(&mut self, experience: u32) -> u8 {
let previous_level = self.level();
let experience_to_add = LEVELS.get(self.level() as usize - 1)
.map_or(experience, |&next_level_points| {
(next_level_points - self.experience_points).min(experience)
});
self.experience_points += experience_to_add;
let current_level = self.level();
current_level - previous_level
}
}