tf_demo_parser/demo/message/
bspdecal.rs1use crate::demo::sendprop::{read_bit_coord, write_bit_coord};
2use crate::demo::vector::Vector;
3use crate::{ReadResult, Stream};
4use bitbuffer::{BitRead, BitWrite, BitWriteSized, BitWriteStream, LittleEndian};
5use serde::{Deserialize, Serialize};
6
7#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9pub struct BSPDecalMessage {
10 pub position: Vector,
11 pub texture_index: u16,
12 pub ent_index: u16,
13 pub model_index: u16,
14 pub low_priority: bool,
15}
16
17impl BitRead<'_, LittleEndian> for BSPDecalMessage {
18 fn read(stream: &mut Stream) -> ReadResult<Self> {
19 let position = {
20 let (has_x, has_y, has_z) = stream.read()?;
21
22 Vector {
23 x: if has_x { read_bit_coord(stream)? } else { 0f32 },
24 y: if has_y { read_bit_coord(stream)? } else { 0f32 },
25 z: if has_z { read_bit_coord(stream)? } else { 0f32 },
26 }
27 };
28
29 let texture_index = stream.read_sized(9)?;
30 let (ent_index, model_index): (u16, u16) = if stream.read()? {
31 (stream.read_sized(11)?, stream.read_sized(13)?)
32 } else {
33 (0, 0)
34 };
35 let low_priority = stream.read()?;
36
37 Ok(BSPDecalMessage {
38 position,
39 texture_index,
40 ent_index,
41 model_index,
42 low_priority,
43 })
44 }
45}
46
47impl BitWrite<LittleEndian> for BSPDecalMessage {
48 fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
49 let has_x = self.position.x != 0.0;
50 let has_y = self.position.y != 0.0;
51 let has_z = self.position.z != 0.0;
52 (has_x, has_y, has_z).write(stream)?;
53
54 if has_x {
55 write_bit_coord(self.position.x, stream)?;
56 }
57 if has_y {
58 write_bit_coord(self.position.y, stream)?;
59 }
60 if has_z {
61 write_bit_coord(self.position.z, stream)?;
62 }
63 self.texture_index.write_sized(stream, 9)?;
64 if self.ent_index != 0 || self.model_index != 0 {
65 true.write(stream)?;
66 self.ent_index.write_sized(stream, 11)?;
67 self.model_index.write_sized(stream, 13)?;
68 } else {
69 false.write(stream)?;
70 }
71 self.low_priority.write(stream)?;
72
73 Ok(())
74 }
75}
76
77#[test]
78fn test_decal_roundtrip() {
79 crate::test_roundtrip_write(BSPDecalMessage {
80 position: Vector::default(),
81 texture_index: 0,
82 ent_index: 0,
83 model_index: 0,
84 low_priority: false,
85 });
86 crate::test_roundtrip_write(BSPDecalMessage {
87 position: Vector {
88 x: 1.0,
89 y: 0.5,
90 z: 0.0,
91 },
92 texture_index: 12,
93 ent_index: 15,
94 model_index: 2,
95 low_priority: true,
96 });
97}