1use serde::{Deserialize, Serialize};
7use serde_with::{serde_as, Bytes};
8
9const V99_EMPTY_ITEMS_CLASSIC: [u8; 4] = [0x4A, 0x4D, 0x00, 0x00];
10const V99_EMPTY_ITEMS_EXPANSION: [u8; 13] =
11 [0x4A, 0x4D, 0x00, 0x00, 0x4A, 0x4D, 0x00, 0x00, 0x6A, 0x66, 0x6B, 0x66, 0x00];
12const V99_EMPTY_ITEMS_EXPANSION_MERC: [u8; 17] = [
13 0x4A, 0x4D, 0x00, 0x00, 0x4A, 0x4D, 0x00, 0x00, 0x6A, 0x66, 0x4A, 0x4D, 0x00, 0x00, 0x6B, 0x66,
14 0x00,
15];
16
17const V105_EMPTY_ITEMS_CLASSIC: [u8; 4] = [0x4A, 0x4D, 0x00, 0x00];
18const V105_EMPTY_ITEMS_EXPANSION: [u8; 13] =
19 [0x4A, 0x4D, 0x00, 0x00, 0x4A, 0x4D, 0x00, 0x00, 0x6A, 0x66, 0x6B, 0x66, 0x00];
20const V105_EMPTY_ITEMS_EXPANSION_MERC: [u8; 17] = [
21 0x4A, 0x4D, 0x00, 0x00, 0x4A, 0x4D, 0x00, 0x00, 0x6A, 0x66, 0x4A, 0x4D, 0x00, 0x00, 0x6B, 0x66,
22 0x00,
23];
24const V105_EMPTY_ITEMS_ROTW: [u8; 19] = [
25 0x4A, 0x4D, 0x00, 0x00, 0x4A, 0x4D, 0x00, 0x00, 0x6A, 0x66, 0x6B, 0x66, 0x00, 0x01, 0x00, 0x6C,
26 0x66, 0x00, 0x00,
27];
28
29const V105_EMPTY_ITEMS_ROTW_MERC: [u8; 23] = [
30 0x4A, 0x4D, 0x00, 0x00, 0x4A, 0x4D, 0x00, 0x00, 0x6A, 0x66, 0x4A, 0x4D, 0x00, 0x00, 0x6B, 0x66,
31 0x00, 0x01, 0x00, 0x6C, 0x66, 0x00, 0x00,
32];
33
34#[derive(Clone, Copy, Debug, PartialEq, Eq)]
35pub enum EmptyLayout {
36 LegacyClassic,
38 LegacyExpansion,
40 V105Classic,
42 V105Expansion,
44 V105RotW,
46}
47
48#[serde_as]
50#[derive(PartialEq, Eq, Debug, Default, Clone, Serialize, Deserialize)]
51pub struct Placeholder {
52 #[serde_as(as = "Bytes")]
53 data: Vec<u8>,
54 #[serde(default)]
55 original_mercenary_hired: bool,
56}
57
58pub fn parse(byte_vector: &[u8], mercenary_hired: bool) -> Placeholder {
60 Placeholder { data: byte_vector.to_vec(), original_mercenary_hired: mercenary_hired }
61}
62
63impl Placeholder {
64 pub(crate) fn mercenary_hire_state_changed(&self, mercenary_hired: bool) -> bool {
65 self.original_mercenary_hired != mercenary_hired
66 }
67}
68
69pub fn generate(
74 placeholder: &Placeholder,
75 empty_layout: EmptyLayout,
76 mercenary_hired: bool,
77) -> Vec<u8> {
78 if !placeholder.data.is_empty() {
79 return placeholder.data.clone();
80 }
81
82 match (empty_layout, mercenary_hired) {
83 (EmptyLayout::LegacyClassic, _) => V99_EMPTY_ITEMS_CLASSIC.to_vec(),
84 (EmptyLayout::LegacyExpansion, false) => V99_EMPTY_ITEMS_EXPANSION.to_vec(),
85 (EmptyLayout::LegacyExpansion, true) => V99_EMPTY_ITEMS_EXPANSION_MERC.to_vec(),
86 (EmptyLayout::V105Classic, _) => V105_EMPTY_ITEMS_CLASSIC.to_vec(),
87 (EmptyLayout::V105Expansion, false) => V105_EMPTY_ITEMS_EXPANSION.to_vec(),
88 (EmptyLayout::V105Expansion, true) => V105_EMPTY_ITEMS_EXPANSION_MERC.to_vec(),
89 (EmptyLayout::V105RotW, false) => V105_EMPTY_ITEMS_ROTW.to_vec(),
90 (EmptyLayout::V105RotW, true) => V105_EMPTY_ITEMS_ROTW_MERC.to_vec(),
91 }
92}