halbu/character/mercenary/
mod.rs

1use crate::utils::u16_from;
2use crate::utils::u32_from;
3use serde::{Deserialize, Serialize};
4use std::fmt;
5use std::ops::Range;
6
7mod tests;
8
9enum Section {
10    IsDead,
11    Id,
12    NameId,
13    VariantId,
14    Experience,
15}
16
17impl Section {
18    const fn range(self) -> Range<usize> {
19        match self {
20            Section::IsDead => 0..2,
21            Section::Id => 2..6,
22            Section::NameId => 6..8,
23            Section::VariantId => 8..10,
24            Section::Experience => 10..14,
25        }
26    }
27}
28
29#[derive(Default, PartialEq, Eq, Debug, Copy, Clone, Serialize, Deserialize)]
30pub struct Mercenary {
31    pub is_dead: bool,
32    pub id: u32,
33    pub name_id: u16,
34    pub variant_id: u16,
35    pub experience: u32,
36}
37
38impl fmt::Display for Mercenary {
39    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40        write!(
41            f,
42            "Dead: {0}, ID: {1}, Name_ID: {2}, Variant: {3}, XP: {4}",
43            self.is_dead, self.id, self.name_id, self.variant_id, self.experience
44        )
45    }
46}
47
48impl Mercenary {
49    pub fn write(&self) -> [u8; 14] {
50        let mut bytes: [u8; 14] = [0x00; 14];
51        bytes[Section::IsDead.range()].copy_from_slice(match self.is_dead {
52            true => &[0x01, 0x00],
53            false => &[0x00, 0x00],
54        });
55
56        bytes[Section::Id.range()].copy_from_slice(&self.id.to_le_bytes());
57        bytes[Section::NameId.range()].copy_from_slice(&self.name_id.to_le_bytes());
58        bytes[Section::VariantId.range()].copy_from_slice(&self.variant_id.to_le_bytes());
59        bytes[Section::Experience.range()].copy_from_slice(&self.experience.to_le_bytes());
60        bytes
61    }
62
63    pub fn parse(data: &[u8; 14]) -> Mercenary {
64        let mut mercenary: Mercenary = Mercenary::default();
65        if u16_from(&data[Section::IsDead.range()], "mercenary.is_dead") != 0 {
66            mercenary.is_dead = true;
67        }
68
69        mercenary.id = u32_from(&data[Section::Id.range()], "mercenary.id");
70        mercenary.variant_id = u16_from(&data[Section::VariantId.range()], "mercenary.variant_id");
71        mercenary.name_id = u16_from(&data[Section::NameId.range()], "mercenary.name_id");
72        mercenary.experience = u32_from(&data[Section::Experience.range()], "mercenary.experience");
73
74        mercenary
75    }
76
77    pub fn is_hired(&self) -> bool {
78        self.id != 0u32
79    }
80}