aoe2_probe/tweak/
triggers.rs1use std::collections::HashMap;
2
3use crate::{parse::Token, Scenario, TriggerTweak};
4
5pub struct TriggersTweak {}
6
7impl TriggersTweak {
8 pub fn push(scenario: &mut Scenario, trigger: Token) -> Result<(), String> {
22 let version = scenario.version().to_string();
23 match version.as_str() {
24 "1.46" | "1.47" => {
25 TriggerTweak::is_trigger(&trigger, &version)?;
26
27 let trigger_data = scenario
28 .versio
29 .get_by_path_mut("/triggers/trigger_data")
30 .try_mut_vec();
31 trigger_data.push(trigger);
32
33 let trigger_display_order_array = scenario
34 .versio
35 .get_by_path_mut("/triggers/trigger_display_order_array")
36 .try_mut_vec();
37 trigger_display_order_array.push((trigger_display_order_array.len() as u32).into());
38
39 let trigger_count = scenario
40 .versio
41 .get_by_path("/triggers/number_of_triggers")
42 .try_u32();
43 Self::set_trigger_count(scenario, &version, *trigger_count + 1).unwrap();
44
45 Ok(())
46 }
47 _ => Err("Incompatible version!".to_string()),
48 }
49 }
50
51 pub fn insert(
52 scenario: &mut Scenario,
53 trigger: Token,
54 display_index: usize,
55 execute_index: usize,
56 ) -> Result<(), String> {
57 let version = scenario.version().to_string();
58 match version.as_str() {
59 "1.46" | "1.47" => {
60 TriggerTweak::is_trigger(&trigger, &version)?;
61
62 let trigger_display_order_array = scenario
63 .versio
64 .get_by_path_mut("/triggers/trigger_display_order_array")
65 .try_mut_vec();
66
67 for index in trigger_display_order_array.iter_mut() {
68 let index = index.try_mut_u32();
69 if *index >= execute_index as u32 {
70 *index += 1;
71 }
72 }
73 trigger_display_order_array.insert(display_index, (execute_index as u32).into());
74
75 let trigger_data = scenario
76 .versio
77 .get_by_path_mut("/triggers/trigger_data")
78 .try_mut_vec();
79
80 for trigger in trigger_data.iter_mut() {
81 let map = trigger.try_mut_map();
82 let effects = map["effect_data"].try_mut_vec();
83 for effect in effects.iter_mut() {
84 let map = effect.try_mut_map();
85 let target_id = *map["trigger_id"].try_i32();
86 if target_id >= execute_index.try_into().unwrap() {
87 map.update("trigger_id", target_id + 1).unwrap();
88 }
89 }
90 }
91
92 trigger_data.insert(execute_index, trigger);
93
94 let trigger_count = scenario
95 .versio
96 .get_by_path("/triggers/number_of_triggers")
97 .try_u32();
98 Self::set_trigger_count(scenario, &version, *trigger_count + 1)?;
99
100 Ok(())
101 }
102 _ => Err("Incompatible version!".to_string()),
103 }
104 }
105
106 pub fn sort_by_display_order(scenario: &mut Scenario) -> Result<(), String> {
119 let version = scenario.version().to_string();
120 match version.as_str() {
121 "1.46" | "1.47" => {
122 let display_order: Vec<u32> = scenario
123 .versio
124 .get_by_path("/triggers/trigger_display_order_array")
125 .try_vec()
126 .iter()
127 .map(|token| *token.try_u32())
128 .collect();
129
130 let trigger_data = scenario
131 .versio
132 .get_by_path("/triggers/trigger_data")
133 .try_vec();
134
135 let mut sorted_triggers = vec![];
136 let mut order: Vec<Token> = vec![];
137 let mut map = HashMap::new();
138
139 for index in 0..display_order.len() as u32 {
140 let position = display_order
141 .iter()
142 .position(|&value| value == index)
143 .unwrap();
144 map.insert(position, index);
145 sorted_triggers.push(trigger_data[position].clone());
146 order.push(index.into());
147 }
148
149 for token in sorted_triggers.iter_mut() {
150 let effects = token.get_by_path_mut("/effect_data").try_mut_vec();
151 for token in effects.iter_mut() {
152 let target_trigger_id = token.get_by_path_mut("trigger_id").try_mut_i32();
153 if *target_trigger_id >= 0 {
154 let new_id = map[&(*target_trigger_id as usize)] as i32;
155 *target_trigger_id = new_id;
156 }
157 }
158 }
159
160 let triggers = scenario.versio.get_by_path_mut("/triggers").try_mut_map();
161 triggers.update("trigger_data", sorted_triggers).unwrap();
162 triggers
163 .update("trigger_display_order_array", order)
164 .unwrap();
165
166 Ok(())
167 }
168 _ => Err("Incompatible version!".to_string()),
169 }
170 }
171
172 fn set_trigger_count(scenario: &mut Scenario, version: &str, count: u32) -> Result<(), String> {
173 match version {
174 "1.46" | "1.47" => {
175 let trigger_count = scenario
176 .versio
177 .get_by_path_mut("/file_header/trigger_count")
178 .try_mut_u32();
179 *trigger_count = count;
180
181 let number_of_triggers = scenario
182 .versio
183 .get_by_path_mut("/options/number_of_triggers")
184 .try_mut_u32();
185 *number_of_triggers = count;
186
187 let number_of_triggers = scenario
188 .versio
189 .get_by_path_mut("/triggers/number_of_triggers")
190 .try_mut_u32();
191 *number_of_triggers = count;
192 Ok(())
193 }
194 _ => Err("Incompatible version!".to_string()),
195 }
196 }
197}