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