rpfm_lib/files/group_formations/versions/
rome_2.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_rom_2<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
28 for _ in 0..data.read_u32()? {
30 let mut min_unit_category_percentage = MinUnitCategoryPercentage::default();
31 min_unit_category_percentage.category = UnitCategory::try_from(data.read_u32()?)?;
32 min_unit_category_percentage.percentage = data.read_u32()?;
33 formation.min_unit_category_percentage.push(min_unit_category_percentage);
34 }
35
36 for _ in 0..data.read_u32()? {
37 formation.ai_supported_subcultures.push(data.read_sized_string_u8()?);
38 }
39
40 for _ in 0..data.read_u32()? {
41 formation.ai_supported_factions.push(data.read_sized_string_u8()?);
42 }
43
44 for _ in 0..data.read_u32()? {
46 let mut block = GroupFormationBlock::default();
47 block.block_id = data.read_u32()?;
48
49 let block_type = data.read_u32()?;
50 match block_type {
51
52 0 => {
54 let mut container = ContainerAbsolute::default();
55 container.block_priority = data.read_f32()?;
56 container.entity_arrangement = EntityArrangement::try_from(data.read_u32()?)?;
57 container.inter_entity_spacing = data.read_f32()?;
58 container.crescent_y_offset = data.read_f32()?;
59 container.position_x = data.read_f32()?;
60 container.position_y = data.read_f32()?;
61 container.minimum_entity_threshold = data.read_i32()?;
62 container.maximum_entity_threshold = data.read_i32()?;
63
64 for _ in 0..data.read_u32()? {
65 let mut entity_pref = EntityPreference::default();
66 entity_pref.priority = data.read_f32()?;
67 entity_pref.entity = Entity::V2(v2::EntityType::try_from(data.read_u32()?)?);
68 entity_pref.entity_weight = EntityWeight::try_from(data.read_u32()?)?;
69 container.entity_preferences.push(entity_pref);
70 }
71
72 block.block = Block::ContainerAbsolute(container);
73 },
74
75 1 => {
77 let mut container = ContainerRelative::default();
78 container.block_priority = data.read_f32()?;
79 container.relative_block_id = data.read_u32()?;
80 container.entity_arrangement = EntityArrangement::try_from(data.read_u32()?)?;
81 container.inter_entity_spacing = data.read_f32()?;
82 container.crescent_y_offset = data.read_f32()?;
83 container.position_x = data.read_f32()?;
84 container.position_y = data.read_f32()?;
85 container.minimum_entity_threshold = data.read_i32()?;
86 container.maximum_entity_threshold = data.read_i32()?;
87
88 for _ in 0..data.read_u32()? {
89 let mut entity_pref = EntityPreference::default();
90 entity_pref.priority = data.read_f32()?;
91 entity_pref.entity = Entity::V2(v2::EntityType::try_from(data.read_u32()?)?);
92 entity_pref.entity_weight = EntityWeight::try_from(data.read_u32()?)?;
93 container.entity_preferences.push(entity_pref);
94 }
95
96 block.block = Block::ContainerRelative(container);
97 },
98
99 3 => {
101 let mut container = Spanning::default();
102 for _ in 0..data.read_u32()? {
103 container.spanned_block_ids.push(data.read_u32()?);
104 }
105 block.block = Block::Spanning(container);
106 },
107 _ => todo!("unknown block type {}.", block_type),
108 }
109
110 formation.group_formation_blocks.push(block);
111 }
112
113 self.formations.push(formation);
114 }
115
116 Ok(())
117 }
118
119 pub(crate) fn encode_rom_2<W: WriteBytes>(&mut self, buffer: &mut W) -> Result<()> {
120 buffer.write_u32(self.formations.len() as u32)?;
121 for formation in self.formations() {
122 buffer.write_sized_string_u8(formation.name())?;
123 buffer.write_f32(formation.ai_priority)?;
124
125 if let AIPurpose::V2(data) = &formation.ai_purpose {
126 buffer.write_u32(data.bits())?;
127 }
128
129 buffer.write_u32(formation.min_unit_category_percentage.len() as u32)?;
130 for mucp in formation.min_unit_category_percentage() {
131 buffer.write_u32(mucp.category.into())?;
132 buffer.write_u32(mucp.percentage)?;
133 }
134
135 buffer.write_u32(formation.ai_supported_subcultures.len() as u32)?;
136 for s in formation.ai_supported_subcultures() {
137 buffer.write_sized_string_u8(s)?;
138 }
139
140 buffer.write_u32(formation.ai_supported_factions.len() as u32)?;
141 for s in formation.ai_supported_factions() {
142 buffer.write_sized_string_u8(s)?;
143 }
144
145 buffer.write_u32(formation.group_formation_blocks.len() as u32)?;
146 for block in formation.group_formation_blocks() {
147 buffer.write_u32(block.block_id)?;
148
149 match block.block {
150 Block::ContainerAbsolute(ref b) => {
151 buffer.write_u32(0)?;
152 buffer.write_f32(b.block_priority)?;
153 buffer.write_u32(b.entity_arrangement.into())?;
154 buffer.write_f32(b.inter_entity_spacing)?;
155 buffer.write_f32(b.crescent_y_offset)?;
156 buffer.write_f32(b.position_x)?;
157 buffer.write_f32(b.position_y)?;
158 buffer.write_i32(b.minimum_entity_threshold)?;
159 buffer.write_i32(b.maximum_entity_threshold)?;
160
161 buffer.write_u32(b.entity_preferences.len() as u32)?;
162 for ep in b.entity_preferences() {
163 buffer.write_f32(ep.priority)?;
164 if let Entity::V2(data) = &ep.entity {
165 buffer.write_u32((*data).into())?;
166 }
167 buffer.write_u32(ep.entity_weight.into())?;
168 }
169 },
170
171 Block::ContainerRelative(ref b) => {
172 buffer.write_u32(1)?;
173 buffer.write_f32(b.block_priority)?;
174 buffer.write_u32(b.relative_block_id)?;
175 buffer.write_u32(b.entity_arrangement.into())?;
176 buffer.write_f32(b.inter_entity_spacing)?;
177 buffer.write_f32(b.crescent_y_offset)?;
178 buffer.write_f32(b.position_x)?;
179 buffer.write_f32(b.position_y)?;
180 buffer.write_i32(b.minimum_entity_threshold)?;
181 buffer.write_i32(b.maximum_entity_threshold)?;
182
183 buffer.write_u32(b.entity_preferences.len() as u32)?;
184 for ep in b.entity_preferences() {
185 buffer.write_f32(ep.priority)?;
186 if let Entity::V2(data) = &ep.entity {
187 buffer.write_u32((*data).into())?;
188 }
189 buffer.write_u32(ep.entity_weight.into())?;
190 }
191 },
192
193 Block::Spanning(ref b) => {
194 buffer.write_u32(3)?;
195 buffer.write_u32(b.spanned_block_ids.len() as u32)?;
196 for id in b.spanned_block_ids() {
197 buffer.write_u32(*id)?;
198 }
199 },
200 }
201 }
202 }
203
204 Ok(())
205 }
206}