rpfm_lib/files/group_formations/versions/
troy.rs1use crate::binary::{ReadBytes, WriteBytes};
12use crate::error::Result;
13
14use super::*;
15use super::versions::v2;
16
17impl GroupFormations {
18
19 pub(crate) fn decode_troy<R: ReadBytes>(&mut self, data: &mut R) -> Result<()> {
20
21 for _ in 0..data.read_u32()? {
23 let mut formation = GroupFormation::default();
24 formation.name = data.read_sized_string_u8()?;
25 formation.ai_priority = data.read_f32()?;
26 formation.ai_purpose = AIPurpose::V2(v2::AIPurposeFlags::from_bits_truncate(data.read_u32()?));
27 formation.uk_2 = data.read_u32()?;
28
29 for _ in 0..data.read_u32()? {
31 let mut min_unit_category_percentage = MinUnitCategoryPercentage::default();
32
33 min_unit_category_percentage.category = UnitCategory::try_from(data.read_u32()?)?;
34 min_unit_category_percentage.percentage = data.read_u32()?;
35
36 formation.min_unit_category_percentage.push(min_unit_category_percentage);
37 }
38
39 for _ in 0..data.read_u32()? {
40 formation.ai_supported_subcultures.push(data.read_sized_string_u8()?);
41 }
42
43 for _ in 0..data.read_u32()? {
47 let mut block = GroupFormationBlock::default();
48 block.block_id = data.read_u32()?;
49
50 let block_type = data.read_u32()?;
52 match block_type {
53
54 0 => {
56 let mut container = ContainerAbsolute::default();
57 container.block_priority = data.read_f32()?;
58 container.entity_arrangement = EntityArrangement::try_from(data.read_u32()?)?;
59 container.inter_entity_spacing = data.read_f32()?;
60 container.crescent_y_offset = data.read_f32()?;
61 container.position_x = data.read_f32()?;
62 container.position_y = data.read_f32()?;
63 container.minimum_entity_threshold = data.read_i32()?;
64 container.maximum_entity_threshold = data.read_i32()?;
65
66 for _ in 0..data.read_u32()? {
68 let mut entity_pref = EntityPreference::default();
69 entity_pref.priority = data.read_f32()?;
70 entity_pref.entity = Entity::V2(v2::EntityType::try_from(data.read_u32()?)?);
71 entity_pref.entity_weight = EntityWeight::try_from(data.read_u32()?)?;
72 entity_pref.uk_1 = data.read_u32()?;
73 entity_pref.entity_class = data.read_sized_string_u8()?;
74 container.entity_preferences.push(entity_pref);
75 }
76
77 block.block = Block::ContainerAbsolute(container);
78 },
79
80 1 => {
82 let mut container = ContainerRelative::default();
83 container.block_priority = data.read_f32()?;
84 container.relative_block_id = data.read_u32()?;
85 container.entity_arrangement = EntityArrangement::try_from(data.read_u32()?)?;
86 container.inter_entity_spacing = data.read_f32()?;
87 container.crescent_y_offset = data.read_f32()?;
88 container.position_x = data.read_f32()?;
89 container.position_y = data.read_f32()?;
90 container.minimum_entity_threshold = data.read_i32()?;
91 container.maximum_entity_threshold = data.read_i32()?;
92
93 for _ in 0..data.read_u32()? {
95 let mut entity_pref = EntityPreference::default();
96 entity_pref.priority = data.read_f32()?;
97 entity_pref.entity = Entity::V2(v2::EntityType::try_from(data.read_u32()?)?);
98 entity_pref.entity_weight = EntityWeight::try_from(data.read_u32()?)?;
99 entity_pref.uk_1 = data.read_u32()?;
100 entity_pref.entity_class = data.read_sized_string_u8()?;
101 container.entity_preferences.push(entity_pref);
102 }
103
104 block.block = Block::ContainerRelative(container);
105 },
106
107 3 => {
109 let mut container = Spanning::default();
110 for _ in 0..data.read_u32()? {
111 container.spanned_block_ids.push(data.read_u32()?);
112 }
113 block.block = Block::Spanning(container);
114 },
115 _ => return Err(RLibError::DecodingGroupFormationsUnknownBlockType(block_type)),
116 }
117
118 formation.group_formation_blocks.push(block);
119 }
120
121 self.formations.push(formation);
122 }
123
124 Ok(())
125 }
126
127 pub(crate) fn encode_troy<W: WriteBytes>(&mut self, buffer: &mut W) -> Result<()> {
128 buffer.write_u32(self.formations.len() as u32)?;
129 for formation in self.formations() {
130 buffer.write_sized_string_u8(formation.name())?;
131
132 buffer.write_f32(formation.ai_priority)?;
133 buffer.write_u32(formation.ai_purpose.v2_bits()?)?;
134
135 buffer.write_u32(formation.uk_2)?;
136 buffer.write_u32(formation.min_unit_category_percentage.len() as u32)?;
137 for mucp in formation.min_unit_category_percentage() {
138 buffer.write_u32(mucp.category.into())?;
139 buffer.write_u32(mucp.percentage)?;
140 }
141
142 buffer.write_u32(formation.ai_supported_subcultures.len() as u32)?;
143 for ai_supported_subculture in formation.ai_supported_subcultures() {
144 buffer.write_sized_string_u8(ai_supported_subculture)?;
145 }
146
147 buffer.write_u32(formation.group_formation_blocks.len() as u32)?;
148 for block in formation.group_formation_blocks() {
149 buffer.write_u32(block.block_id)?;
150
151 match block.block {
152 Block::ContainerAbsolute(ref b) => {
153 buffer.write_u32(0)?;
154
155 buffer.write_f32(b.block_priority)?;
156 buffer.write_u32(b.entity_arrangement.into())?;
157 buffer.write_f32(b.inter_entity_spacing)?;
158 buffer.write_f32(b.crescent_y_offset)?;
159 buffer.write_f32(b.position_x)?;
160 buffer.write_f32(b.position_y)?;
161 buffer.write_i32(b.minimum_entity_threshold)?;
162 buffer.write_i32(b.maximum_entity_threshold)?;
163
164 buffer.write_u32(b.entity_preferences.len() as u32)?;
165 for ep in b.entity_preferences() {
166 buffer.write_f32(ep.priority)?;
167 buffer.write_u32(ep.entity.v2_value()?)?;
168 buffer.write_u32(ep.entity_weight.into())?;
169 buffer.write_u32(ep.uk_1)?;
170 buffer.write_sized_string_u8(&ep.entity_class)?;
171 }
172 },
173
174 Block::ContainerRelative(ref b) => {
175 buffer.write_u32(1)?;
176
177 buffer.write_f32(b.block_priority)?;
178 buffer.write_u32(b.relative_block_id)?;
179 buffer.write_u32(b.entity_arrangement.into())?;
180 buffer.write_f32(b.inter_entity_spacing)?;
181 buffer.write_f32(b.crescent_y_offset)?;
182 buffer.write_f32(b.position_x)?;
183 buffer.write_f32(b.position_y)?;
184 buffer.write_i32(b.minimum_entity_threshold)?;
185 buffer.write_i32(b.maximum_entity_threshold)?;
186
187 buffer.write_u32(b.entity_preferences.len() as u32)?;
188 for ep in b.entity_preferences() {
189 buffer.write_f32(ep.priority)?;
190 buffer.write_u32(ep.entity.v2_value()?)?;
191 buffer.write_u32(ep.entity_weight.into())?;
192
193 buffer.write_u32(ep.uk_1)?;
194 buffer.write_sized_string_u8(&ep.entity_class)?;
195 }
196 },
197
198 Block::Spanning(ref block) => {
199 buffer.write_u32(3)?;
200 buffer.write_u32(block.spanned_block_ids.len() as u32)?;
201 for id in block.spanned_block_ids() {
202 buffer.write_u32(*id)?;
203 }
204 },
205 }
206 }
207 }
208
209 Ok(())
210 }
211}