From d35534c0795caeda46e57fc515b74eba701110a2 Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Fri, 6 Dec 2019 18:00:04 +0100 Subject: initial commit --- src/bt.rs | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 src/bt.rs (limited to 'src/bt.rs') diff --git a/src/bt.rs b/src/bt.rs new file mode 100644 index 0000000..3485448 --- /dev/null +++ b/src/bt.rs @@ -0,0 +1,160 @@ +use super::api::{Skill, Specialization}; +use std::{fmt, str::FromStr}; + +/// The profession of the template. +/// +/// Can be cast to an `u8` to get the right ID for building chat links. +#[repr(u8)] +#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] +pub enum Profession { + Guardian = 1, + Warrior = 2, + Engineer = 3, + Ranger = 4, + Thief = 5, + Elementalist = 6, + Mesmer = 7, + Necromancer = 8, + Revenant = 9, +} + +impl fmt::Display for Profession { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fmt::Debug::fmt(&self, f) + } +} + +impl FromStr for Profession { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + "Guardian" => Ok(Profession::Guardian), + "Warrior" => Ok(Profession::Warrior), + "Engineer" => Ok(Profession::Engineer), + "Ranger" => Ok(Profession::Ranger), + "Thief" => Ok(Profession::Thief), + "Elementalist" => Ok(Profession::Elementalist), + "Mesmer" => Ok(Profession::Mesmer), + "Necromancer" => Ok(Profession::Necromancer), + "Revenant" => Ok(Profession::Revenant), + _ => Err(()), + } + } +} + +/// Represents the selected trait. +#[repr(u8)] +#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)] +pub enum TraitChoice { + None = 0, + Top = 1, + Middle = 2, + Bottom = 3, +} + +impl FromStr for TraitChoice { + type Err = (); + + fn from_str(s: &str) -> Result { + let lower = s.to_lowercase(); + match &lower as &str { + "" | "none" => Ok(TraitChoice::None), + "top" => Ok(TraitChoice::Top), + "mid" | "middle" => Ok(TraitChoice::Middle), + "bot" | "bottom" => Ok(TraitChoice::Bottom), + _ => Err(()), + } + } +} + +/// Represents a traitline. +/// +/// A traitline consists of the chosen specialization including 3 possible trait choices. +pub type Traitline = (Specialization, [TraitChoice; 3]); + +pub const SKILL_COUNT: usize = 5; +pub const TRAITLINE_COUNT: usize = 3; + +/// Represents a build template. +/// +/// This struct is made with the same limitations as the game imposes. That is, even though the +/// renderer can support more than three traitlines, this template will only allow you to take +/// three. +#[derive(Debug)] +pub struct BuildTemplate { + /// Profession of this build. + profession: Profession, + /// The skills of the build. + /// + /// Each slot can either contain a slot or be empty. A maximum of 5 skills are allowed (heal, 3 + /// utilities and elite). + skills: [Option; SKILL_COUNT], + /// The traitlines of the build. + traitlines: [Option; TRAITLINE_COUNT], +} + +impl BuildTemplate { + /// Returns a template without any skills or traitlines. + pub fn empty(profession: Profession) -> BuildTemplate { + BuildTemplate { + profession, + skills: [None, None, None, None, None], + traitlines: [None, None, None], + } + } + + /// Creates a template with the given skills and traitlines. + /// + /// If there are more than 5 skills or 3 traitlines given, the function will return `None`. + pub fn new( + profession: Profession, + skills: &[Skill], + traitlines: &[Traitline], + ) -> Option { + if skills.len() > SKILL_COUNT { + return None; + } + if traitlines.len() > TRAITLINE_COUNT { + return None; + } + let mut skill_array = [None, None, None, None, None]; + for (i, skill) in skills.iter().enumerate() { + skill_array[i] = Some(skill.clone()); + } + let mut trait_array = [None, None, None]; + for (i, traitline) in traitlines.iter().enumerate() { + trait_array[i] = Some(traitline.clone()); + } + Some(BuildTemplate { + profession, + skills: skill_array, + traitlines: trait_array, + }) + } + + /// Returns the profession of this build. + pub fn profession(&self) -> Profession { + self.profession + } + + /// Returns the skills of this build. + pub fn skills(&self) -> &[Option] { + &self.skills + } + + /// Returns the number of actually equipped skills. + pub fn skill_count(&self) -> u32 { + self.skills.iter().filter(|x| x.is_some()).count() as u32 + } + + /// Returns the traitlines of this build. + pub fn traitlines(&self) -> &[Option] { + &self.traitlines + } + + /// Returns the number of actually equipped specializations. + pub fn traitline_count(&self) -> u32 { + self.traitlines.iter().filter(|x| x.is_some()).count() as u32 + } +} -- cgit v1.2.3