wow_vanilla_dbc/tables/
pet_loyalty.rs

1use crate::header::{HEADER_SIZE, DbcHeader};
2use crate::header;
3use crate::DbcTable;
4use std::io::Write;
5use crate::Indexable;
6use crate::LocalizedString;
7
8#[derive(Debug, Clone, PartialEq)]
9pub struct PetLoyalty {
10    pub rows: Vec<PetLoyaltyRow>,
11}
12
13impl DbcTable for PetLoyalty {
14    type Row = PetLoyaltyRow;
15
16    fn filename() -> &'static str { "PetLoyalty.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 = header::parse_header(&header)?;
25
26        if header.record_size != 40 {
27            return Err(crate::DbcError::InvalidHeader(
28                crate::InvalidHeaderError::RecordSize {
29                    expected: 40,
30                    actual: header.record_size,
31                },
32            ));
33        }
34
35        if header.field_count != 10 {
36            return Err(crate::DbcError::InvalidHeader(
37                crate::InvalidHeaderError::FieldCount {
38                    expected: 40,
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        let mut string_block = vec![0_u8; header.string_block_size as usize];
47        b.read_exact(&mut string_block)?;
48
49        let mut rows = Vec::with_capacity(header.record_count as usize);
50
51        for mut chunk in r.chunks(header.record_size as usize) {
52            let chunk = &mut chunk;
53
54            // id: primary_key (PetLoyalty) uint32
55            let id = PetLoyaltyKey::new(crate::util::read_u32_le(chunk)?);
56
57            // name: string_ref_loc
58            let name = crate::util::read_localized_string(chunk, &string_block)?;
59
60
61            rows.push(PetLoyaltyRow {
62                id,
63                name,
64            });
65        }
66
67        Ok(PetLoyalty { rows, })
68    }
69
70    fn write(&self, b: &mut impl Write) -> Result<(), std::io::Error> {
71        let header = DbcHeader {
72            record_count: self.rows.len() as u32,
73            field_count: 10,
74            record_size: 40,
75            string_block_size: self.string_block_size(),
76        };
77
78        b.write_all(&header.write_header())?;
79
80        let mut string_index = 1;
81        for row in &self.rows {
82            // id: primary_key (PetLoyalty) uint32
83            b.write_all(&row.id.id.to_le_bytes())?;
84
85            // name: string_ref_loc
86            b.write_all(&row.name.string_indices_as_array(&mut string_index))?;
87
88        }
89
90        self.write_string_block(b)?;
91
92        Ok(())
93    }
94
95}
96
97impl Indexable for PetLoyalty {
98    type PrimaryKey = PetLoyaltyKey;
99    fn get(&self, key: &Self::PrimaryKey) -> Option<&Self::Row> {
100        self.rows.iter().find(|a| a.id.id == key.id)
101    }
102
103    fn get_mut(&mut self, key: &Self::PrimaryKey) -> Option<&mut Self::Row> {
104        self.rows.iter_mut().find(|a| a.id.id == key.id)
105    }
106
107}
108
109impl PetLoyalty {
110    fn write_string_block(&self, b: &mut impl Write) -> Result<(), std::io::Error> {
111        b.write_all(&[0])?;
112
113        for row in &self.rows {
114            row.name.string_block_as_array(b)?;
115        }
116
117        Ok(())
118    }
119
120    fn string_block_size(&self) -> u32 {
121        let mut sum = 1;
122        for row in &self.rows {
123            sum += row.name.string_block_size();
124        }
125
126        sum as u32
127    }
128
129}
130
131#[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd)]
132pub struct PetLoyaltyKey {
133    pub id: u32
134}
135
136impl PetLoyaltyKey {
137    pub const fn new(id: u32) -> Self {
138        Self { id }
139    }
140
141}
142
143#[derive(Debug, Clone, PartialEq)]
144pub struct PetLoyaltyRow {
145    pub id: PetLoyaltyKey,
146    pub name: LocalizedString,
147}
148