aboutsummaryrefslogtreecommitdiff
path: root/src/bt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bt.rs')
-rw-r--r--src/bt.rs160
1 files changed, 160 insertions, 0 deletions
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<Self, Self::Err> {
+ 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<Self, Self::Err> {
+ 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>; SKILL_COUNT],
+ /// The traitlines of the build.
+ traitlines: [Option<Traitline>; 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<BuildTemplate> {
+ 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<Skill>] {
+ &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<Traitline>] {
+ &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
+ }
+}