wow_dbc/tbc_tables/
char_base_info.rs

1use crate::DbcTable;
2use crate::header::{
3    DbcHeader, HEADER_SIZE, parse_header,
4};
5use crate::tbc_tables::chr_classes::ChrClassesKey;
6use crate::tbc_tables::chr_races::ChrRacesKey;
7use std::io::Write;
8
9#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub struct CharBaseInfo {
11    pub rows: Vec<CharBaseInfoRow>,
12}
13
14impl DbcTable for CharBaseInfo {
15    type Row = CharBaseInfoRow;
16
17    const FILENAME: &'static str = "CharBaseInfo.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 != 2 {
28            return Err(crate::DbcError::InvalidHeader(
29                crate::InvalidHeaderError::RecordSize {
30                    expected: 2,
31                    actual: header.record_size,
32                },
33            ));
34        }
35
36        if header.field_count != 2 {
37            return Err(crate::DbcError::InvalidHeader(
38                crate::InvalidHeaderError::FieldCount {
39                    expected: 2,
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            // race_id: foreign_key (ChrRaces) int8
54            let race_id = ChrRacesKey::new(crate::util::read_i8_le(chunk)?.into());
55
56            // class_id: foreign_key (ChrClasses) int8
57            let class_id = ChrClassesKey::new(crate::util::read_i8_le(chunk)?.into());
58
59
60            rows.push(CharBaseInfoRow {
61                race_id,
62                class_id,
63            });
64        }
65
66        Ok(CharBaseInfo { rows, })
67    }
68
69    fn write(&self, b: &mut impl Write) -> Result<(), std::io::Error> {
70        let header = DbcHeader {
71            record_count: self.rows.len() as u32,
72            field_count: 2,
73            record_size: 2,
74            string_block_size: 1,
75        };
76
77        b.write_all(&header.write_header())?;
78
79        for row in &self.rows {
80            // race_id: foreign_key (ChrRaces) int8
81            b.write_all(&(row.race_id.id as i8).to_le_bytes())?;
82
83            // class_id: foreign_key (ChrClasses) int8
84            b.write_all(&(row.class_id.id as i8).to_le_bytes())?;
85
86        }
87
88        b.write_all(&[0_u8])?;
89
90        Ok(())
91    }
92
93}
94
95#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
96pub struct CharBaseInfoRow {
97    pub race_id: ChrRacesKey,
98    pub class_id: ChrClassesKey,
99}
100