Skip to main content

banished_formats/
weather.rs

1//! `Weather`: a precipitation effect description (`Environment/Rain.rsc`, `Environment/Snow.rsc`),
2//! referenced from the EnvironmentDescription's weather list.
3//!
4//! Original: `FUN_1400d9160`.
5
6use crate::crc::type_id;
7use crate::crs::{self, Reader};
8use crate::error::{format_err, Result};
9
10/// A weather effect: rain or snow particles and how they fall.
11#[derive(Debug, Clone)]
12pub struct Weather {
13    // +0x20
14    /// Particle material.
15    pub material: Option<String>,
16    // +0x28
17    /// Particle count.
18    pub count: i32,
19    // +0x2c; normalised by FUN_1400d9450.
20    /// The direction the particles fall in (the game normalises it).
21    pub direction: [f32; 3],
22    // +0x38, +0x3c
23    /// Particle speed base and random range.
24    pub speed: [f32; 2],
25    // +0x40
26    /// Not identified yet.
27    pub flag: bool,
28    // +0x44..+0x58; +0x48
29    /// is the particle volume's size.
30    pub floats_44: [f32; 6],
31    // +0x5c; geometry +0xc0
32    /// Seconds to fade the intensity (`geometry`) from 0 to 1.
33    ///
34    /// Original: `FUN_1400d8330`.
35    pub fade_time: f32,
36    // +0x60..+0x68
37    /// Not identified yet.
38    pub colors: [u32; 3],
39    // +0x6c..+0x7c
40    /// Not identified yet.
41    pub floats_6c: [f32; 5],
42}
43
44/// Read a [`Weather`] from the bytes of its resource.
45pub fn weather(data: &[u8]) -> Result<Weather> {
46    let (_, value) = crs::parse(data, |r: &mut Reader, h| {
47        if h.type_id != type_id("Weather") {
48            return format_err(format!("expected Weather, found {:#010x}", h.type_id));
49        }
50        r.block(|r, _| {
51            Ok(Weather {
52                material: r.external_ref()?,
53                count: r.u32()? as i32,
54                direction: r.f32s()?,
55                speed: r.f32s()?,
56                flag: r.bool()?,
57                floats_44: r.f32s()?,
58                fade_time: r.f32()?,
59                colors: [r.u32()?, r.u32()?, r.u32()?],
60                floats_6c: r.f32s()?,
61            })
62        })
63    })?;
64    Ok(value)
65}