1use std::collections::HashMap;
20
21use serde::{Deserialize, Serialize};
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct OpenStrandedMap {
30 pub meta: MapMeta,
32 pub terrain: TerrainData,
34 #[serde(default)]
36 pub entities: Vec<MapEntity>,
37 #[serde(default)]
39 pub player_spawn: Option<PlayerSpawn>,
40 #[serde(default)]
42 pub environment: HashMap<String, String>,
43 #[serde(default)]
45 pub colormap: Option<ColormapData>,
46 #[serde(default)]
48 pub grass: Option<GrassData>,
49 #[serde(default)]
51 pub password: String,
52 #[serde(default)]
54 pub scripts: Vec<ScriptData>,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize)]
59pub struct MapMeta {
60 pub name: String,
62 pub engine_version: String,
64 pub map_version: String,
66 #[serde(default)]
68 pub source_file: String,
69 #[serde(default)]
71 pub s2_header: Option<S2Header>,
72 #[serde(default)]
74 pub created_at: String,
75}
76
77#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct S2Header {
80 pub version: String,
81 pub date: String,
82 pub time: String,
83 pub author: String,
84 pub map_type: String,
85 #[serde(default)]
89 pub type_format: String,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
94pub struct TerrainData {
95 pub size: u32,
97 pub heights: Vec<f32>,
100 #[serde(default = "default_seaground")]
102 pub seaground_level: f32,
103}
104
105fn default_seaground() -> f32 {
106 -2.0
107}
108
109#[derive(Debug, Clone, Serialize, Deserialize)]
111pub struct ColormapData {
112 pub dim: u32,
114 pub pixels: Vec<u8>,
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize)]
120pub struct GrassData {
121 pub dim: u32,
123 pub values: Vec<u8>,
126}
127
128#[derive(Debug, Clone, Serialize, Deserialize)]
130pub struct MapEntity {
131 pub class: String,
133 pub type_id: u32,
135 pub id: u32,
137 pub position: (f32, f32, f32),
139 #[serde(default)]
141 pub rotation_yaw: f32,
142 #[serde(default)]
144 pub rotation_pitch: f32,
145 #[serde(default)]
147 pub rotation_roll: f32,
148 #[serde(default)]
150 pub health: f32,
151 #[serde(default)]
153 pub health_max: f32,
154 #[serde(default)]
156 pub states: Vec<String>,
157 #[serde(default)]
159 pub script: Option<String>,
160 #[serde(default)]
162 pub amount: u32,
163 #[serde(default)]
165 pub parent_id: u32,
166 #[serde(default)]
168 pub parent_class: u8,
169 #[serde(default)]
171 pub links: Vec<u32>,
172 #[serde(default)]
174 pub build_progress: u32,
175 #[serde(default)]
177 pub unit_data: Option<UnitData>,
178 #[serde(default)]
180 pub extensions: HashMap<String, String>,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
185pub struct UnitData {
186 #[serde(default)]
187 pub hunger: f32,
188 #[serde(default)]
189 pub thirst: f32,
190 #[serde(default)]
191 pub exhaustion: f32,
192 #[serde(default)]
193 pub ai_center_x: f32,
194 #[serde(default)]
195 pub ai_center_z: f32,
196 #[serde(default)]
197 pub day_timer: f32,
198}
199
200#[derive(Debug, Clone, Serialize, Deserialize)]
202pub struct PlayerSpawn {
203 pub position: (f32, f32, f32),
204 pub rotation_yaw: f32,
205}
206
207#[derive(Debug, Clone, Serialize, Deserialize)]
209pub struct ScriptData {
210 pub text: String,
211 pub entity_id: u32,
212}
213
214#[derive(Debug, Clone)]
220pub struct S2Map {
221 pub header: S2Header,
222 pub minimap: Vec<u8>,
223 pub password: S2Password,
224 pub env_vars: S2EnvVars,
225 pub quickslots: Vec<String>,
226 pub colormap_dim: u32,
227 pub colormap: Vec<u8>,
228 pub terrain_size: u32,
229 pub heights: Vec<f32>,
230 pub grass: Vec<u8>,
231 pub objects: Vec<S2Object>,
232 pub units: Vec<S2Unit>,
233 pub items: Vec<S2Item>,
234 pub infos: Vec<S2Info>,
235 pub states: Vec<S2State>,
236 pub extensions: Vec<S2Extension>,
237 pub trailer: S2Trailer,
238}
239
240#[derive(Debug, Clone)]
243pub struct S2Password {
244 pub key: u8,
246 pub encoded: String,
248 pub decoded: String,
250}
251
252#[derive(Debug, Clone)]
253pub struct S2EnvVars {
254 pub day: u32,
255 pub hour: u8,
256 pub minute: u8,
257 pub freezetime: u8,
258 pub skybox: String,
259 pub multiplayer: u8,
260 pub climate: u8,
261 pub music: String,
262 pub briefing: String,
263 pub fog: [u8; 4],
264 pub extra: u8,
265}
266
267#[derive(Debug, Clone)]
269pub struct S2Object {
270 pub id: u32,
271 pub typ: u32,
272 pub x: f32,
273 pub z: f32,
274 pub yaw: f32,
275 pub health: f32,
276 pub health_max: f32,
277 pub day_timer: u32,
278}
279
280#[derive(Debug, Clone)]
284pub struct S2Unit {
285 pub id: u32,
286 pub typ: u32,
287 pub x: f32,
288 pub y: f32,
289 pub z: f32,
290 pub yaw: f32,
291 pub health: f32,
292 pub health_max: f32,
293 pub hunger: f32,
294 pub thirst: f32,
295 pub exhaustion: f32,
296 pub ai_center_x: f32,
297 pub ai_center_z: f32,
298}
299
300#[derive(Debug, Clone)]
302pub struct S2Item {
303 pub id: u32,
304 pub typ: u32,
305 pub x: f32,
306 pub y: f32,
307 pub z: f32,
308 pub yaw: f32,
309 pub health: f32,
310 pub count: u32,
311 pub parent_class: u8,
312 pub parent_mode: u8,
313 pub parent_id: u32,
314}
315
316#[derive(Debug, Clone)]
318pub struct S2Info {
319 pub id: u32,
320 pub typ: u8,
321 pub x: f32,
322 pub y: f32,
323 pub z: f32,
324 pub pitch: f32,
325 pub yaw: f32,
326 pub vars: String,
327}
328
329#[derive(Debug, Clone)]
331pub struct S2State {
332 pub typ: u32,
333 pub parent_class: u32,
334 pub parent_id: u32,
335 pub x: f32,
336 pub y: f32,
337 pub z: f32,
338 pub fx: f32,
339 pub fy: f32,
340 pub fz: f32,
341 pub value: u32,
342 pub value_f: f32,
343 pub value_s: String,
344}
345
346#[derive(Debug, Clone)]
348pub struct S2Extension {
349 pub typ: u8,
350 pub parent_class: u8,
351 pub parent_id: u32,
352 pub mode: u32,
353 pub key: String,
354 pub value: String,
355 pub stuff: String,
356}
357
358#[derive(Debug, Clone)]
360pub struct S2Trailer {
361 pub blank: String,
362 pub eof_marker: String,
363 pub url: String,
364}