Skip to main content

steel_protocol/packets/game/
c_level_particles.rs

1use steel_macros::{ClientPacket, WriteTo};
2use steel_registry::{packets::play::C_LEVEL_PARTICLES, particle_type::ParticleData};
3
4/// Sent to create particles on the client.
5///
6/// The client samples particle positions and velocities from the supplied
7/// distribution. A count of zero has Vanilla's special single-particle
8/// velocity behavior.
9#[derive(ClientPacket, WriteTo, Clone, Debug)]
10#[packet_id(Play = C_LEVEL_PARTICLES)]
11pub struct CLevelParticles {
12    pub override_limiter: bool,
13    pub always_show: bool,
14    pub x: f64,
15    pub y: f64,
16    pub z: f64,
17    pub x_dist: f32,
18    pub y_dist: f32,
19    pub z_dist: f32,
20    pub max_speed: f32,
21    pub count: i32,
22    pub particle: ParticleData,
23}
24
25#[cfg(test)]
26mod tests {
27
28    use steel_registry::init_vanilla_registry;
29    use steel_registry::{RegistryEntry, vanilla_particle_types};
30    use steel_utils::{codec::VarInt, serial::WriteTo};
31
32    use super::CLevelParticles;
33
34    #[test]
35    fn writes_fields_in_vanilla_wire_order() {
36        init_vanilla_registry();
37
38        let packet = CLevelParticles {
39            override_limiter: true,
40            always_show: false,
41            x: 1.25,
42            y: -2.5,
43            z: 3.75,
44            x_dist: 0.5,
45            y_dist: -1.0,
46            z_dist: 2.0,
47            max_speed: 0.125,
48            count: -7,
49            particle: steel_registry::particle_type::ParticleData::simple(
50                &vanilla_particle_types::FLAME,
51            ),
52        };
53
54        let mut encoded = Vec::new();
55        let Ok(()) = packet.write(&mut encoded) else {
56            panic!("level particles packet should encode");
57        };
58
59        let mut expected = vec![1, 0];
60        expected.extend_from_slice(&1.25_f64.to_be_bytes());
61        expected.extend_from_slice(&(-2.5_f64).to_be_bytes());
62        expected.extend_from_slice(&3.75_f64.to_be_bytes());
63        expected.extend_from_slice(&0.5_f32.to_be_bytes());
64        expected.extend_from_slice(&(-1.0_f32).to_be_bytes());
65        expected.extend_from_slice(&2.0_f32.to_be_bytes());
66        expected.extend_from_slice(&0.125_f32.to_be_bytes());
67        expected.extend_from_slice(&(-7_i32).to_be_bytes());
68
69        let Ok(flame_id) = i32::try_from(vanilla_particle_types::FLAME.id()) else {
70            panic!("flame particle id should fit in i32");
71        };
72        let Ok(()) = VarInt(flame_id).write(&mut expected) else {
73            panic!("flame particle id should encode");
74        };
75
76        assert_eq!(encoded, expected);
77    }
78}