mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/team.rs')
-rw-r--r--src/team.rs136
1 files changed, 136 insertions, 0 deletions
diff --git a/src/team.rs b/src/team.rs
new file mode 100644
index 0000000..35a651f
--- /dev/null
+++ b/src/team.rs
@@ -0,0 +1,136 @@
+use std::fmt;
+
+use crate::content::{Content, Type};
+
+#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
+pub struct Team(u8);
+
+impl Team {
+ #[must_use]
+ pub const fn of(id: u8) -> Self {
+ Self(id)
+ }
+
+ #[must_use]
+ pub const fn is_base(self) -> bool {
+ self.0 < 7
+ }
+}
+
+impl From<u8> for Team {
+ fn from(value: u8) -> Self {
+ Team::of(value)
+ }
+}
+
+impl TryFrom<u16> for Team {
+ type Error = TryFromU16Error;
+
+ fn try_from(value: u16) -> Result<Self, Self::Error> {
+ if u8::try_from(value).is_ok() {
+ Ok(Team(value as u8))
+ } else {
+ Err(TryFromU16Error(value))
+ }
+ }
+}
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq, thiserror::Error)]
+#[error("no content of type Team for value {0}")]
+pub struct TryFromU16Error(pub u16);
+
+impl From<Team> for u8 {
+ fn from(value: Team) -> Self {
+ value.0
+ }
+}
+
+impl From<Team> for u16 {
+ fn from(value: Team) -> Self {
+ u16::from(value.0)
+ }
+}
+
+impl fmt::Display for Team {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match self.0 {
+ 0 => f.write_str("Derelict"),
+ 1 => f.write_str("Sharded"),
+ 2 => f.write_str("Crux"),
+ 3 => f.write_str("Malis"),
+ 4 => f.write_str("Green"),
+ 5 => f.write_str("Blue"),
+ 6 => f.write_str("Neoplastic"),
+ id => write!(f, "Team #{id}"),
+ }
+ }
+}
+
+const TEAM_NAMES: &str = include_str!("../res/team_names.txt");
+
+impl Content for Team {
+ fn get_type(&self) -> Type {
+ Type::Team
+ }
+
+ fn get_id(&self) -> u16 {
+ u16::from(self.0)
+ }
+
+ fn get_name(&self) -> &'static str {
+ match self.0 {
+ 0 => "derelict",
+ 1 => "sharded",
+ 2 => "crux",
+ 3 => "malis",
+ 4 => "green",
+ 5 => "blue",
+ 6 => "neoplastic",
+ // dark magic: offsets manually computed, then rely on the format "...|team#{i}|..."
+ i @ 7..=9 => {
+ // length: 7 ("team#" (5) + 1 digit + "|" (1))
+ let s = ((i - 6) as usize) * 7;
+ &TEAM_NAMES[s..s + 6] // exclude the trailing "|"
+ }
+ i @ 10..=99 => {
+ // length: 8 ("team#" (5) + 2 digits + "|" (1))
+ let s = 28 + ((i - 10) as usize) * 8;
+ &TEAM_NAMES[s..s + 7] // exclude the trailing "|"
+ }
+ i @ 100..=255 => {
+ // length: 9 ("team#" (5) + 3 digits + "|" (1))
+ let s = 748 + ((i - 100) as usize) * 9;
+ &TEAM_NAMES[s..s + 8] // exclude the trailing "|"
+ }
+ }
+ }
+}
+
+impl Team {
+ pub const fn color(self) -> (u8, u8, u8) {
+ macro_rules! h {
+ ($x:literal) => {{
+ let v = color_hex::color_from_hex!($x);
+ (v[0], v[1], v[2])
+ }};
+ }
+ match self {
+ SHARDED => h!("ffd37f"),
+ DERELICT => h!("4d4e58"),
+ CRUX => h!("f25555"),
+ MALIS => h!("a27ce5"),
+ GREEN => h!("54d67d"),
+ BLUE => h!("6c87fd"),
+ NEOPLASTIC => h!("e05438"),
+ _ => h!("a9a9a9"),
+ }
+ }
+}
+
+pub const DERELICT: Team = Team(0);
+pub const SHARDED: Team = Team(1);
+pub const CRUX: Team = Team(2);
+pub const MALIS: Team = Team(3);
+pub const GREEN: Team = Team(4);
+pub const BLUE: Team = Team(5);
+pub const NEOPLASTIC: Team = Team(6);