wow_dbc/vanilla_tables/
skill_race_class_info.rs

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