1use std::fmt;
2
3use atools::Chunked;
4
5use crate::content::{Content, Type};
6
7#[derive(Clone, Copy, Debug, Eq, Ord, PartialOrd, Default, PartialEq)]
8pub struct Team(u8);
9
10impl Team {
11 #[must_use]
12 pub const fn of(id: u8) -> Self {
13 Self(id)
14 }
15
16 #[must_use]
17 pub const fn is_base(self) -> bool {
18 self.0 < 7
19 }
20}
21
22impl From<u8> for Team {
23 fn from(value: u8) -> Self {
24 Team::of(value)
25 }
26}
27
28impl TryFrom<u16> for Team {
29 type Error = TryFromU16Error;
30
31 fn try_from(value: u16) -> Result<Self, Self::Error> {
32 if u8::try_from(value).is_ok() {
33 Ok(Team(value as u8))
34 } else {
35 Err(TryFromU16Error(value))
36 }
37 }
38}
39
40#[derive(Copy, Clone, Debug, Eq, PartialEq, thiserror::Error)]
41#[error("no content of type Team for value {0}")]
42pub struct TryFromU16Error(pub u16);
43
44impl From<Team> for u8 {
45 fn from(value: Team) -> Self {
46 value.0
47 }
48}
49
50impl From<Team> for u16 {
51 fn from(value: Team) -> Self {
52 u16::from(value.0)
53 }
54}
55
56impl fmt::Display for Team {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 match self.0 {
59 0 => f.write_str("Derelict"),
60 1 => f.write_str("Sharded"),
61 2 => f.write_str("Crux"),
62 3 => f.write_str("Malis"),
63 4 => f.write_str("Green"),
64 5 => f.write_str("Blue"),
65 6 => f.write_str("Neoplastic"),
66 id => write!(f, "Team #{id}"),
67 }
68 }
69}
70
71const TEAM_NAMES: &str = include_str!("../res/team_names.txt");
72
73impl Content for Team {
74 fn get_type(&self) -> Type {
75 Type::Team
76 }
77
78 fn get_id(&self) -> u16 {
79 u16::from(self.0)
80 }
81
82 fn get_name(&self) -> &'static str {
83 match self.0 {
84 0 => "derelict",
85 1 => "sharded",
86 2 => "crux",
87 3 => "malis",
88 4 => "green",
89 5 => "blue",
90 6 => "neoplastic",
91 i @ 7..=9 => {
93 let s = ((i - 6) as usize) * 7;
95 &TEAM_NAMES[s..s + 6] }
97 i @ 10..=99 => {
98 let s = 28 + ((i - 10) as usize) * 8;
100 &TEAM_NAMES[s..s + 7] }
102 i @ 100..=255 => {
103 let s = 748 + ((i - 100) as usize) * 9;
105 &TEAM_NAMES[s..s + 8] }
107 }
108 }
109}
110
111impl Team {
112 pub const fn color(self) -> [u8; 3] {
113 static COLORS: [[u8; 3]; 256] = include_bytes!("colors").chunked::<3>();
114 COLORS[self.0 as usize]
115 }
116
117 pub const DERELICT: Team = Team(0);
118 pub const SHARDED: Team = Team(1);
119 pub const CRUX: Team = Team(2);
120 pub const MALIS: Team = Team(3);
121 pub const GREEN: Team = Team(4);
122 pub const BLUE: Team = Team(5);
123 pub const NEOPLASTIC: Team = Team(6);
124}