1use super::*;
4
5#[derive(Debug, Clone, PartialEq)]
12pub struct QuarryDescription {
13 pub deep: f32,
15 pub shallow: f32,
17 pub mesh: Option<String>,
19}
20
21pub fn quarry_description(data: &[u8]) -> Result<QuarryDescription> {
23 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
24 if h.type_id != type_id("QuarryDescription") {
25 return format_err(format!(
26 "expected QuarryDescription, found {:#010x}",
27 h.type_id
28 ));
29 }
30 r.block(|r, _| {
31 Ok(QuarryDescription {
32 deep: r.f32()?,
33 shallow: r.f32()?,
34 mesh: r.external_ref()?,
35 })
36 })
37 })?;
38 Ok(value)
39}
40
41#[derive(Debug, Clone, PartialEq, Eq)]
47pub struct HerbalistDescription {
48 pub resources: Vec<Option<String>>,
50 pub group: i32,
52}
53
54pub fn herbalist_description(data: &[u8]) -> Result<HerbalistDescription> {
56 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
57 if h.type_id != type_id("HerbalistDescription") {
58 return format_err(format!(
59 "expected HerbalistDescription, found {:#010x}",
60 h.type_id
61 ));
62 }
63 r.block(|r, _| {
64 let n = r.i32()?;
65 let resources = (0..n.max(0))
66 .map(|_| r.external_ref())
67 .collect::<Result<Vec<_>>>()?;
68 Ok(HerbalistDescription {
69 resources,
70 group: r.i32()?,
71 })
72 })
73 })?;
74 Ok(value)
75}
76
77#[derive(Debug, Clone, PartialEq, Eq)]
83pub struct ForesterDescription {
84 pub tree: Option<String>,
86 pub group: i32,
88}
89
90pub fn forester_description(data: &[u8]) -> Result<ForesterDescription> {
92 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
93 if h.type_id != type_id("ForesterDescription") {
94 return format_err(format!(
95 "expected ForesterDescription, found {:#010x}",
96 h.type_id
97 ));
98 }
99 r.block(|r, version| {
100 let tree = r.external_ref()?;
101 let group = if version > 0 { r.i32()? } else { 0 };
102 Ok(ForesterDescription { tree, group })
103 })
104 })?;
105 Ok(value)
106}
107
108#[derive(Debug, Clone, PartialEq, Eq)]
114pub struct FishingDescription {
115 pub output: Option<String>,
117 pub mask: u32,
119 pub group: i32,
121}
122
123pub fn fishing_description(data: &[u8]) -> Result<FishingDescription> {
125 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
126 if h.type_id != type_id("FishingDescription") {
127 return format_err(format!(
128 "expected FishingDescription, found {:#010x}",
129 h.type_id
130 ));
131 }
132 r.block(|r, version| {
133 let output = r.external_ref()?;
134 let mask = r.u32()?;
135 let group = if version > 0 { r.i32()? } else { 0 };
136 Ok(FishingDescription {
137 output,
138 mask,
139 group,
140 })
141 })
142 })?;
143 Ok(value)
144}
145
146#[derive(Debug, Clone, Copy, PartialEq)]
152pub struct HuntDescription {
153 pub time: f32,
155 pub group: i32,
157}
158
159pub fn hunt_description(data: &[u8]) -> Result<HuntDescription> {
161 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
162 if h.type_id != type_id("HuntDescription") {
163 return format_err(format!(
164 "expected HuntDescription, found {:#010x}",
165 h.type_id
166 ));
167 }
168 r.block(|r, version| {
169 let time = r.f32()?;
170 let group = if version > 0 { r.i32()? } else { 0 };
171 Ok(HuntDescription { time, group })
172 })
173 })?;
174 Ok(value)
175}
176
177pub fn crop_field_description(data: &[u8]) -> Result<(f32, i32)> {
183 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
184 if h.type_id != type_id("CropFieldDescription") {
185 return format_err(format!(
186 "expected CropFieldDescription, found {:#010x}",
187 h.type_id
188 ));
189 }
190 r.block(|r, version| {
191 let tend = r.f32()?;
192 let group = if version > 0 { r.i32()? } else { 0 };
193 Ok((tend, group))
194 })
195 })?;
196 Ok(value)
197}
198
199pub fn orchard_description(data: &[u8]) -> Result<((i32, i32), f32, i32)> {
205 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
206 if h.type_id != type_id("OrchardDescription") {
207 return format_err(format!(
208 "expected OrchardDescription, found {:#010x}",
209 h.type_id
210 ));
211 }
212 r.block(|r, version| {
213 let spacing = (r.i32()?, r.i32()?);
214 let tend = r.f32()?;
215 let group = if version > 0 { r.i32()? } else { 0 };
216 Ok((spacing, tend, group))
217 })
218 })?;
219 Ok(value)
220}
221
222pub fn pasture_description(data: &[u8]) -> Result<i32> {
228 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
229 if h.type_id != type_id("PastureDescription") {
230 return format_err(format!(
231 "expected PastureDescription, found {:#010x}",
232 h.type_id
233 ));
234 }
235 r.block(|r, version| if version > 0 { r.i32() } else { Ok(5) })
236 })?;
237 Ok(value)
238}
239
240#[derive(Debug, Clone, Default, PartialEq)]
246pub struct LivestockDescription {
247 pub product: Option<String>,
249 pub interval: f32,
251 pub group: i32,
253}
254
255pub fn livestock_description(data: &[u8]) -> Result<LivestockDescription> {
257 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
258 if h.type_id != type_id("LivestockDescription") {
259 return format_err(format!(
260 "expected LivestockDescription, found {:#010x}",
261 h.type_id
262 ));
263 }
264 r.block(|r, version| {
265 let product = r.external_ref()?;
266 let interval = r.f32()?;
267 let group = if version > 0 { r.i32()? } else { 0 };
268 Ok(LivestockDescription {
269 product,
270 interval,
271 group,
272 })
273 })
274 })?;
275 Ok(value)
276}
277
278#[derive(Debug, Clone, Default)]
284pub struct WorkPlaceDescription {
285 pub profession: Option<String>,
287 pub reference_28: Option<String>,
289}
290
291pub fn workplace_description(data: &[u8]) -> Result<WorkPlaceDescription> {
293 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
294 if h.type_id != type_id("WorkPlaceDescription") {
295 return format_err(format!(
296 "expected WorkPlaceDescription, found {:#010x}",
297 h.type_id
298 ));
299 }
300 r.block(|r, _| {
301 Ok(WorkPlaceDescription {
302 profession: r.external_ref()?,
303 reference_28: r.external_ref()?,
304 })
305 })
306 })?;
307 Ok(value)
308}
309
310#[derive(Debug, Clone, Default)]
314pub struct WorkDescription {
315 pub max_workers: i32,
320 pub value_28: i32,
322 pub value_2c: i32,
324 pub per_area: bool,
327 pub area: i32,
329 pub flag_20: bool,
331}
332
333pub fn work_description(data: &[u8]) -> Result<WorkDescription> {
335 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
336 if h.type_id != type_id("WorkDescription") {
337 return format_err(format!(
338 "expected WorkDescription, found {:#010x}",
339 h.type_id
340 ));
341 }
342 r.block(|r, _| {
343 Ok(WorkDescription {
344 max_workers: r.i32()?,
345 value_28: r.i32()?,
346 value_2c: r.i32()?,
347 per_area: r.bool()?,
348 area: r.i32()?,
349 flag_20: r.bool()?,
350 })
351 })
352 })?;
353 Ok(value)
354}
355
356#[derive(Debug, Clone, Default)]
361pub struct ProduceRecipe {
362 pub inputs: Vec<(Option<String>, i32)>,
365 pub output: Option<String>,
368 pub group: i32,
371 pub label: String,
374}
375
376#[derive(Debug, Clone, Default)]
380pub struct ConsumeProduceDescription {
381 pub string_table: Option<String>,
384 pub recipes: Vec<ProduceRecipe>,
387 pub cycles: i32,
390 pub work_type: u32,
393 pub message_type: u32,
397 pub message_value: i32,
399 pub duration: f32,
402 pub lifetime: i32,
405 pub selector: i32,
408}
409
410pub fn consume_produce_description(data: &[u8]) -> Result<ConsumeProduceDescription> {
412 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
413 if h.type_id != type_id("ConsumeProduceDescription") {
414 return format_err(format!(
415 "expected ConsumeProduceDescription, found {:#010x}",
416 h.type_id
417 ));
418 }
419 r.block(|r, _| {
420 let string_table = r.external_ref()?;
421 let n = r.count()?;
422 let mut recipes = Vec::with_capacity(n);
423 for _ in 0..n {
424 let k = r.count()?;
425 let inputs = (0..k)
426 .map(|_| Ok((r.external_ref()?, r.i32()?)))
427 .collect::<Result<_>>()?;
428 recipes.push(ProduceRecipe {
429 inputs,
430 output: r.external_ref()?,
431 group: r.i32()?,
432 label: r.string()?,
433 });
434 }
435 Ok(ConsumeProduceDescription {
436 string_table,
437 recipes,
438 cycles: r.i32()?,
439 work_type: r.u32()?,
440 message_type: r.u32()?,
441 message_value: r.i32()?,
442 duration: r.f32()?,
443 lifetime: r.i32()?,
444 selector: r.i32()?,
445 })
446 })
447 })?;
448 Ok(value)
449}
450
451#[derive(Debug, Clone)]
455pub struct Profession {
456 pub string_table: Option<String>,
459 pub sprite_sheet: Option<String>,
461 pub name: String,
464 pub tooltip: String,
467 pub death: String,
469 pub value_48: i32,
471 pub flag_4c: bool,
473 pub flag_4d: bool,
475 pub value_54: f32,
477 pub value_58: f32,
479 pub value_50: i32,
481 pub flag_4e: bool,
483}
484
485pub fn profession(data: &[u8]) -> Result<Profession> {
487 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
488 if h.type_id != type_id("Profession") {
489 return format_err(format!("expected Profession, found {:#010x}", h.type_id));
490 }
491 r.block(|r, _| {
492 Ok(Profession {
493 string_table: r.external_ref()?,
494 sprite_sheet: r.external_ref()?,
495 name: r.string()?,
496 tooltip: r.string()?,
497 death: r.string()?,
498 value_48: r.i32()?,
499 flag_4c: r.bool()?,
500 flag_4d: r.bool()?,
501 value_54: r.f32()?,
502 value_58: r.f32()?,
503 value_50: r.i32()?,
504 flag_4e: r.bool()?,
505 })
506 })
507 })?;
508 Ok(value)
509}
510
511pub fn radius_description(data: &[u8]) -> Result<(i32, Option<String>)> {
516 let (_, value) = crs::parse(data, |r: &mut Reader, h| {
517 if h.type_id != type_id("RadiusDescription") {
518 return format_err("expected RadiusDescription");
519 }
520 r.block(|r, _| Ok((r.i32()?, r.external_ref()?)))
521 })?;
522 Ok(value)
523}