wolfrpg_map_parser/command/
string_condition_command.rs

1pub 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; // Padding
30
31        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; // Padding;
39
40        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; // Conditions end
48
49        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}