wow_dbc/wrath_tables/
transport_physics.rs

1use crate::{
2    DbcTable, Indexable,
3};
4use crate::header::{
5    DbcHeader, HEADER_SIZE, parse_header,
6};
7use std::io::Write;
8
9#[derive(Debug, Clone, PartialEq, PartialOrd)]
10pub struct TransportPhysics {
11    pub rows: Vec<TransportPhysicsRow>,
12}
13
14impl DbcTable for TransportPhysics {
15    type Row = TransportPhysicsRow;
16
17    const FILENAME: &'static str = "TransportPhysics.dbc";
18
19    fn rows(&self) -> &[Self::Row] { &self.rows }
20    fn rows_mut(&mut self) -> &mut [Self::Row] { &mut self.rows }
21
22    fn read(b: &mut impl std::io::Read) -> Result<Self, crate::DbcError> {
23        let mut header = [0_u8; HEADER_SIZE];
24        b.read_exact(&mut header)?;
25        let header = parse_header(&header)?;
26
27        if header.record_size != 44 {
28            return Err(crate::DbcError::InvalidHeader(
29                crate::InvalidHeaderError::RecordSize {
30                    expected: 44,
31                    actual: header.record_size,
32                },
33            ));
34        }
35
36        if header.field_count != 11 {
37            return Err(crate::DbcError::InvalidHeader(
38                crate::InvalidHeaderError::FieldCount {
39                    expected: 11,
40                    actual: header.field_count,
41                },
42            ));
43        }
44
45        let mut r = vec![0_u8; (header.record_count * header.record_size) as usize];
46        b.read_exact(&mut r)?;
47
48        let mut rows = Vec::with_capacity(header.record_count as usize);
49
50        for mut chunk in r.chunks(header.record_size as usize) {
51            let chunk = &mut chunk;
52
53            // id: primary_key (TransportPhysics) int32
54            let id = TransportPhysicsKey::new(crate::util::read_i32_le(chunk)?);
55
56            // wave_amp: float
57            let wave_amp = crate::util::read_f32_le(chunk)?;
58
59            // wave_time_scale: float
60            let wave_time_scale = crate::util::read_f32_le(chunk)?;
61
62            // roll_amp: float
63            let roll_amp = crate::util::read_f32_le(chunk)?;
64
65            // roll_time_scale: float
66            let roll_time_scale = crate::util::read_f32_le(chunk)?;
67
68            // pitch_amp: float
69            let pitch_amp = crate::util::read_f32_le(chunk)?;
70
71            // pitch_time_scale: float
72            let pitch_time_scale = crate::util::read_f32_le(chunk)?;
73
74            // max_bank: float
75            let max_bank = crate::util::read_f32_le(chunk)?;
76
77            // max_bank_turn_speed: float
78            let max_bank_turn_speed = crate::util::read_f32_le(chunk)?;
79
80            // speed_damp_thresh: float
81            let speed_damp_thresh = crate::util::read_f32_le(chunk)?;
82
83            // speed_damp: float
84            let speed_damp = crate::util::read_f32_le(chunk)?;
85
86
87            rows.push(TransportPhysicsRow {
88                id,
89                wave_amp,
90                wave_time_scale,
91                roll_amp,
92                roll_time_scale,
93                pitch_amp,
94                pitch_time_scale,
95                max_bank,
96                max_bank_turn_speed,
97                speed_damp_thresh,
98                speed_damp,
99            });
100        }
101
102        Ok(TransportPhysics { rows, })
103    }
104
105    fn write(&self, b: &mut impl Write) -> Result<(), std::io::Error> {
106        let header = DbcHeader {
107            record_count: self.rows.len() as u32,
108            field_count: 11,
109            record_size: 44,
110            string_block_size: 1,
111        };
112
113        b.write_all(&header.write_header())?;
114
115        for row in &self.rows {
116            // id: primary_key (TransportPhysics) int32
117            b.write_all(&row.id.id.to_le_bytes())?;
118
119            // wave_amp: float
120            b.write_all(&row.wave_amp.to_le_bytes())?;
121
122            // wave_time_scale: float
123            b.write_all(&row.wave_time_scale.to_le_bytes())?;
124
125            // roll_amp: float
126            b.write_all(&row.roll_amp.to_le_bytes())?;
127
128            // roll_time_scale: float
129            b.write_all(&row.roll_time_scale.to_le_bytes())?;
130
131            // pitch_amp: float
132            b.write_all(&row.pitch_amp.to_le_bytes())?;
133
134            // pitch_time_scale: float
135            b.write_all(&row.pitch_time_scale.to_le_bytes())?;
136
137            // max_bank: float
138            b.write_all(&row.max_bank.to_le_bytes())?;
139
140            // max_bank_turn_speed: float
141            b.write_all(&row.max_bank_turn_speed.to_le_bytes())?;
142
143            // speed_damp_thresh: float
144            b.write_all(&row.speed_damp_thresh.to_le_bytes())?;
145
146            // speed_damp: float
147            b.write_all(&row.speed_damp.to_le_bytes())?;
148
149        }
150
151        b.write_all(&[0_u8])?;
152
153        Ok(())
154    }
155
156}
157
158impl Indexable for TransportPhysics {
159    type PrimaryKey = TransportPhysicsKey;
160    fn get(&self, key: impl TryInto<Self::PrimaryKey>) -> Option<&Self::Row> {
161        let key = key.try_into().ok()?;
162        self.rows.iter().find(|a| a.id.id == key.id)
163    }
164
165    fn get_mut(&mut self, key: impl TryInto<Self::PrimaryKey>) -> Option<&mut Self::Row> {
166        let key = key.try_into().ok()?;
167        self.rows.iter_mut().find(|a| a.id.id == key.id)
168    }
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
172pub struct TransportPhysicsKey {
173    pub id: i32
174}
175
176impl TransportPhysicsKey {
177    pub const fn new(id: i32) -> Self {
178        Self { id }
179    }
180
181}
182
183impl From<u8> for TransportPhysicsKey {
184    fn from(v: u8) -> Self {
185        Self::new(v.into())
186    }
187}
188
189impl From<u16> for TransportPhysicsKey {
190    fn from(v: u16) -> Self {
191        Self::new(v.into())
192    }
193}
194
195impl From<i8> for TransportPhysicsKey {
196    fn from(v: i8) -> Self {
197        Self::new(v.into())
198    }
199}
200
201impl From<i16> for TransportPhysicsKey {
202    fn from(v: i16) -> Self {
203        Self::new(v.into())
204    }
205}
206
207impl From<i32> for TransportPhysicsKey {
208    fn from(v: i32) -> Self {
209        Self::new(v)
210    }
211}
212
213impl TryFrom<u32> for TransportPhysicsKey {
214    type Error = u32;
215    fn try_from(v: u32) -> Result<Self, Self::Error> {
216        Ok(TryInto::<i32>::try_into(v).ok().ok_or(v)?.into())
217    }
218}
219
220impl TryFrom<usize> for TransportPhysicsKey {
221    type Error = usize;
222    fn try_from(v: usize) -> Result<Self, Self::Error> {
223        Ok(TryInto::<i32>::try_into(v).ok().ok_or(v)?.into())
224    }
225}
226
227impl TryFrom<u64> for TransportPhysicsKey {
228    type Error = u64;
229    fn try_from(v: u64) -> Result<Self, Self::Error> {
230        Ok(TryInto::<i32>::try_into(v).ok().ok_or(v)?.into())
231    }
232}
233
234impl TryFrom<i64> for TransportPhysicsKey {
235    type Error = i64;
236    fn try_from(v: i64) -> Result<Self, Self::Error> {
237        Ok(TryInto::<i32>::try_into(v).ok().ok_or(v)?.into())
238    }
239}
240
241impl TryFrom<isize> for TransportPhysicsKey {
242    type Error = isize;
243    fn try_from(v: isize) -> Result<Self, Self::Error> {
244        Ok(TryInto::<i32>::try_into(v).ok().ok_or(v)?.into())
245    }
246}
247
248#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
249pub struct TransportPhysicsRow {
250    pub id: TransportPhysicsKey,
251    pub wave_amp: f32,
252    pub wave_time_scale: f32,
253    pub roll_amp: f32,
254    pub roll_time_scale: f32,
255    pub pitch_amp: f32,
256    pub pitch_time_scale: f32,
257    pub max_bank: f32,
258    pub max_bank_turn_speed: f32,
259    pub speed_damp_thresh: f32,
260    pub speed_damp: f32,
261}
262