halbu/character/mercenary/
mod.rs1use 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}