wolfrpg_map_parser/command/
string_condition_command.rs1pub mod operator;
2pub mod compare_operator;
3pub mod condition;
4
5use crate::byte_utils::{as_u32_vec, parse_string_vec};
6use crate::command::common::case::Case;
7use crate::common::u32_or_string::U32OrString;
8use crate::command::common::CASES_END_SIGNATURE;
9use crate::command::string_condition_command::condition::Condition;
10use crate::command::string_condition_command::operator::Operator;
11#[cfg(feature = "serde")]
12use serde::{Serialize, Deserialize};
13
14#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
15#[derive(PartialEq, Clone)]
16pub struct StringConditionCommand {
17 else_case: bool,
18 conditions: Vec<Condition>,
19 cases: Vec<Case>
20}
21
22impl StringConditionCommand {
23 pub(crate) fn parse(bytes: &[u8], signature: u32) -> (usize, u32, Self) {
24 let mut offset: usize = 0;
25
26 let (case_count, else_case): (u8,bool) = Self::parse_case_count(bytes[offset]);
27 offset += 1;
28
29 offset += 3; let variables: Vec<u32> = as_u32_vec(&bytes[offset..offset + (4 * case_count) as usize]);
32 offset += 4 * case_count as usize;
33
34 let value_count:usize = Self::value_count(signature, case_count as u32);
35 let values: Vec<u32> = as_u32_vec(&bytes[offset..offset + (4 * value_count)]);
36 offset += 4 * value_count;
37
38 offset += 1; let condition_count: usize = bytes[offset] as usize;
41 offset += 1;
42
43 let (bytes_read, conditions): (usize, Vec<String>)
44 = parse_string_vec(&bytes[offset..], condition_count);
45 offset += bytes_read;
46
47 offset += 1; let conditions: Vec<Condition> = Self::make_conditions(variables, values, conditions);
50
51 let case_count: usize = case_count as usize + else_case as usize;
52 let (bytes_read, mut commands_read, cases): (usize, u32, Vec<Case>)
53 = Case::parse_multiple(&bytes[offset..], case_count);
54 offset += bytes_read;
55
56 let cases_end: &[u8] = &bytes[offset..offset+8];
57 offset += 8;
58 commands_read += 1;
59
60 if &cases_end[..4] != CASES_END_SIGNATURE {
61 panic!("Invalid cases end.");
62 }
63
64 (offset, commands_read, Self {
65 else_case,
66 conditions,
67 cases
68 })
69 }
70
71 fn parse_case_count(cases: u8) -> (u8, bool) {
72 (cases & 0x0f, cases & 0b00010000 != 0)
73 }
74
75 fn value_count(signature: u32, case_count: u32) -> usize {
76 ((signature >> 24) - 2 - case_count) as usize
77 }
78
79 fn make_conditions(variables: Vec<u32>, values: Vec<u32>,
80 conditions: Vec<String>) -> Vec<Condition> {
81 let mut ret_conditions: Vec<Condition> = Vec::with_capacity(variables.len());
82
83 for i in 0..variables.len() {
84 let operator: u8 = (variables[i] >> 24) as u8;
85 let operator: Operator = Operator::new(operator);
86 let variable: u32 = variables[i] & 0x00ffffff;
87
88 let value: U32OrString = if operator.value_is_variable() {
89 U32OrString::U32(values[i])
90 } else {
91 U32OrString::String(conditions[i].clone())
92 };
93
94 ret_conditions.push(Condition::new(variable, operator, value));
95 }
96
97 ret_conditions
98 }
99
100 pub fn else_case(&self) -> bool {
101 self.else_case
102 }
103
104 pub fn else_case_mut(&mut self) -> &mut bool {
105 &mut self.else_case
106 }
107
108 pub fn conditions(&self) -> &Vec<Condition> {
109 &self.conditions
110 }
111
112 pub fn conditions_mut(&mut self) -> &mut Vec<Condition> {
113 &mut self.conditions
114 }
115
116 pub fn cases(&self) -> &Vec<Case> {
117 &self.cases
118 }
119
120 pub fn cases_mut(&mut self) -> &mut Vec<Case> {
121 &mut self.cases
122 }
123}