wow_dbc/tbc_tables/
char_variations.rs

1use crate::DbcTable;
2use crate::header::{
3    DbcHeader, HEADER_SIZE, parse_header,
4};
5use crate::tbc_tables::chr_races::ChrRacesKey;
6use std::io::Write;
7
8#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
9pub struct CharVariations {
10    pub rows: Vec<CharVariationsRow>,
11}
12
13impl DbcTable for CharVariations {
14    type Row = CharVariationsRow;
15
16    const FILENAME: &'static str = "CharVariations.dbc";
17
18    fn rows(&self) -> &[Self::Row] { &self.rows }
19    fn rows_mut(&mut self) -> &mut [Self::Row] { &mut self.rows }
20
21    fn read(b: &mut impl std::io::Read) -> Result<Self, crate::DbcError> {
22        let mut header = [0_u8; HEADER_SIZE];
23        b.read_exact(&mut header)?;
24        let header = parse_header(&header)?;
25
26        if header.record_size != 24 {
27            return Err(crate::DbcError::InvalidHeader(
28                crate::InvalidHeaderError::RecordSize {
29                    expected: 24,
30                    actual: header.record_size,
31                },
32            ));
33        }
34
35        if header.field_count != 6 {
36            return Err(crate::DbcError::InvalidHeader(
37                crate::InvalidHeaderError::FieldCount {
38                    expected: 6,
39                    actual: header.field_count,
40                },
41            ));
42        }
43
44        let mut r = vec![0_u8; (header.record_count * header.record_size) as usize];
45        b.read_exact(&mut r)?;
46
47        let mut rows = Vec::with_capacity(header.record_count as usize);
48
49        for mut chunk in r.chunks(header.record_size as usize) {
50            let chunk = &mut chunk;
51
52            // race_id: foreign_key (ChrRaces) int32
53            let race_id = ChrRacesKey::new(crate::util::read_i32_le(chunk)?.into());
54
55            // sex_id: int32
56            let sex_id = crate::util::read_i32_le(chunk)?;
57
58            // texture_hold_layer: int32[4]
59            let texture_hold_layer = crate::util::read_array_i32::<4>(chunk)?;
60
61
62            rows.push(CharVariationsRow {
63                race_id,
64                sex_id,
65                texture_hold_layer,
66            });
67        }
68
69        Ok(CharVariations { rows, })
70    }
71
72    fn write(&self, b: &mut impl Write) -> Result<(), std::io::Error> {
73        let header = DbcHeader {
74            record_count: self.rows.len() as u32,
75            field_count: 6,
76            record_size: 24,
77            string_block_size: 1,
78        };
79
80        b.write_all(&header.write_header())?;
81
82        for row in &self.rows {
83            // race_id: foreign_key (ChrRaces) int32
84            b.write_all(&(row.race_id.id as i32).to_le_bytes())?;
85
86            // sex_id: int32
87            b.write_all(&row.sex_id.to_le_bytes())?;
88
89            // texture_hold_layer: int32[4]
90            for i in row.texture_hold_layer {
91                b.write_all(&i.to_le_bytes())?;
92            }
93
94
95        }
96
97        b.write_all(&[0_u8])?;
98
99        Ok(())
100    }
101
102}
103
104#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
105pub struct CharVariationsRow {
106    pub race_id: ChrRacesKey,
107    pub sex_id: i32,
108    pub texture_hold_layer: [i32; 4],
109}
110