wow_dbc/tbc_tables/
rand_prop_points.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, Eq, PartialOrd, Ord, Hash)]
10pub struct RandPropPoints {
11    pub rows: Vec<RandPropPointsRow>,
12}
13
14impl DbcTable for RandPropPoints {
15    type Row = RandPropPointsRow;
16
17    const FILENAME: &'static str = "RandPropPoints.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 != 64 {
28            return Err(crate::DbcError::InvalidHeader(
29                crate::InvalidHeaderError::RecordSize {
30                    expected: 64,
31                    actual: header.record_size,
32                },
33            ));
34        }
35
36        if header.field_count != 16 {
37            return Err(crate::DbcError::InvalidHeader(
38                crate::InvalidHeaderError::FieldCount {
39                    expected: 16,
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 (RandPropPoints) int32
54            let id = RandPropPointsKey::new(crate::util::read_i32_le(chunk)?);
55
56            // epic: int32[5]
57            let epic = crate::util::read_array_i32::<5>(chunk)?;
58
59            // superior: int32[5]
60            let superior = crate::util::read_array_i32::<5>(chunk)?;
61
62            // good: int32[5]
63            let good = crate::util::read_array_i32::<5>(chunk)?;
64
65
66            rows.push(RandPropPointsRow {
67                id,
68                epic,
69                superior,
70                good,
71            });
72        }
73
74        Ok(RandPropPoints { rows, })
75    }
76
77    fn write(&self, b: &mut impl Write) -> Result<(), std::io::Error> {
78        let header = DbcHeader {
79            record_count: self.rows.len() as u32,
80            field_count: 16,
81            record_size: 64,
82            string_block_size: 1,
83        };
84
85        b.write_all(&header.write_header())?;
86
87        for row in &self.rows {
88            // id: primary_key (RandPropPoints) int32
89            b.write_all(&row.id.id.to_le_bytes())?;
90
91            // epic: int32[5]
92            for i in row.epic {
93                b.write_all(&i.to_le_bytes())?;
94            }
95
96
97            // superior: int32[5]
98            for i in row.superior {
99                b.write_all(&i.to_le_bytes())?;
100            }
101
102
103            // good: int32[5]
104            for i in row.good {
105                b.write_all(&i.to_le_bytes())?;
106            }
107
108
109        }
110
111        b.write_all(&[0_u8])?;
112
113        Ok(())
114    }
115
116}
117
118impl Indexable for RandPropPoints {
119    type PrimaryKey = RandPropPointsKey;
120    fn get(&self, key: impl TryInto<Self::PrimaryKey>) -> Option<&Self::Row> {
121        let key = key.try_into().ok()?;
122        self.rows.iter().find(|a| a.id.id == key.id)
123    }
124
125    fn get_mut(&mut self, key: impl TryInto<Self::PrimaryKey>) -> Option<&mut Self::Row> {
126        let key = key.try_into().ok()?;
127        self.rows.iter_mut().find(|a| a.id.id == key.id)
128    }
129}
130
131#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
132pub struct RandPropPointsKey {
133    pub id: i32
134}
135
136impl RandPropPointsKey {
137    pub const fn new(id: i32) -> Self {
138        Self { id }
139    }
140
141}
142
143impl From<u8> for RandPropPointsKey {
144    fn from(v: u8) -> Self {
145        Self::new(v.into())
146    }
147}
148
149impl From<u16> for RandPropPointsKey {
150    fn from(v: u16) -> Self {
151        Self::new(v.into())
152    }
153}
154
155impl From<i8> for RandPropPointsKey {
156    fn from(v: i8) -> Self {
157        Self::new(v.into())
158    }
159}
160
161impl From<i16> for RandPropPointsKey {
162    fn from(v: i16) -> Self {
163        Self::new(v.into())
164    }
165}
166
167impl From<i32> for RandPropPointsKey {
168    fn from(v: i32) -> Self {
169        Self::new(v)
170    }
171}
172
173impl TryFrom<u32> for RandPropPointsKey {
174    type Error = u32;
175    fn try_from(v: u32) -> Result<Self, Self::Error> {
176        Ok(TryInto::<i32>::try_into(v).ok().ok_or(v)?.into())
177    }
178}
179
180impl TryFrom<usize> for RandPropPointsKey {
181    type Error = usize;
182    fn try_from(v: usize) -> Result<Self, Self::Error> {
183        Ok(TryInto::<i32>::try_into(v).ok().ok_or(v)?.into())
184    }
185}
186
187impl TryFrom<u64> for RandPropPointsKey {
188    type Error = u64;
189    fn try_from(v: u64) -> Result<Self, Self::Error> {
190        Ok(TryInto::<i32>::try_into(v).ok().ok_or(v)?.into())
191    }
192}
193
194impl TryFrom<i64> for RandPropPointsKey {
195    type Error = i64;
196    fn try_from(v: i64) -> Result<Self, Self::Error> {
197        Ok(TryInto::<i32>::try_into(v).ok().ok_or(v)?.into())
198    }
199}
200
201impl TryFrom<isize> for RandPropPointsKey {
202    type Error = isize;
203    fn try_from(v: isize) -> Result<Self, Self::Error> {
204        Ok(TryInto::<i32>::try_into(v).ok().ok_or(v)?.into())
205    }
206}
207
208#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
209pub struct RandPropPointsRow {
210    pub id: RandPropPointsKey,
211    pub epic: [i32; 5],
212    pub superior: [i32; 5],
213    pub good: [i32; 5],
214}
215