rscache/definition/rs3/
item_def.rs1use std::{io, io::BufReader};
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6use super::Definition;
7use crate::{extension::ReadExt, util};
8
9#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
13pub struct ItemDefinition {
14 pub id: u32,
15 pub model_data: ModelData,
16 pub name: String,
17 pub stackable: bool,
18 pub cost: i32,
19 pub members_only: bool,
20 pub options: [String; 5],
21 pub interface_options: [String; 5],
22 pub unnoted: bool,
23 pub equip_slot: u8,
25 pub equip_hide_slot1: u8,
26 pub equip_hide_slot2: u8,
27 pub noted_id: Option<u16>,
28 pub noted_template: Option<u16>,
29 pub stack_ids: Option<[u16; 10]>,
30 pub stack_count: Option<[u16; 10]>,
31 pub team: u8,
32 pub lend_id: Option<u16>,
33 pub lend_tempalte: Option<u16>,
34 pub lent: bool,
35 pub bind_link: Option<u16>,
36 pub bind_tempalte: Option<u16>,
37}
38
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
40#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
41pub struct ModelData {
42 pub id: u32,
43 pub zoom: u16,
44 pub rotation1: u16,
45 pub rotation2: u16,
46 pub offset1: u16,
47 pub offset2: u16,
48 pub male_equip_id: u32,
49 pub female_equip_id: u32,
50 pub male_equip1: u32,
51 pub male_equip2: u32,
52 pub female_equip1: u32,
53 pub female_equip2: u32,
54 pub original_colors: Vec<u16>,
55 pub modified_colors: Vec<u16>,
56 pub original_texture_colors: Vec<u16>,
57 pub modified_texture_colors: Vec<u16>,
58}
59
60impl Definition for ItemDefinition {
61 fn new(id: u32, buffer: &[u8]) -> crate::Result<Self> {
62 let mut reader = BufReader::new(buffer);
63 let item_def = decode_buffer(id, &mut reader)?;
64
65 Ok(item_def)
66 }
67}
68
69fn decode_buffer(id: u32, reader: &mut BufReader<&[u8]>) -> io::Result<ItemDefinition> {
70 let mut item_def = ItemDefinition {
71 id,
72 options: [
73 "".to_string(),
74 "".to_string(),
75 "Take".to_string(),
76 "".to_string(),
77 "".to_string(),
78 ],
79 interface_options: [
80 "".to_string(),
81 "".to_string(),
82 "".to_string(),
83 "".to_string(),
84 "Drop".to_string(),
85 ],
86 ..ItemDefinition::default()
87 };
88
89 loop {
90 let opcode = reader.read_u8()?;
91
92 match opcode {
93 0 => break,
94 1 => {
95 item_def.model_data.id = reader.read_smart()?;
96 }
97 2 => {
98 item_def.name = reader.read_string()?;
99 }
100 4 => {
101 item_def.model_data.zoom = reader.read_u16()?;
102 }
103 5 => {
104 item_def.model_data.rotation1 = reader.read_u16()?;
105 }
106 6 => {
107 item_def.model_data.rotation2 = reader.read_u16()?;
108 }
109 7 => {
110 item_def.model_data.offset1 = reader.read_u16()?;
111 }
112 8 => {
113 item_def.model_data.offset2 = reader.read_u16()?;
114 }
115 11 => item_def.stackable = true,
116 12 => {
117 item_def.cost = reader.read_i32()?;
118 }
119 13 => {
120 item_def.equip_slot = reader.read_u8()?;
121 }
122 14 => {
123 item_def.equip_hide_slot1 = reader.read_u8()?;
124 }
125 16 => item_def.members_only = true,
126 23 => {
127 item_def.model_data.male_equip1 = reader.read_smart()?;
128 }
129 24 => {
130 item_def.model_data.male_equip2 = reader.read_smart()?;
131 }
132 25 => {
133 item_def.model_data.female_equip1 = reader.read_smart()?;
134 }
135 26 => {
136 item_def.model_data.female_equip2 = reader.read_smart()?;
137 }
138 27 => {
139 item_def.equip_hide_slot2 = reader.read_u8()?;
140 }
141 30..=34 => {
142 item_def.options[opcode as usize - 30] = reader.read_string()?;
143 }
144 35..=39 => {
145 item_def.interface_options[opcode as usize - 35] = reader.read_string()?;
146 }
147 40 => {
148 let len = reader.read_u8()? as usize;
149 item_def.model_data.original_colors = Vec::with_capacity(len);
150 item_def.model_data.modified_colors = Vec::with_capacity(len);
151 for _ in 0..len {
152 item_def.model_data.original_colors.push(reader.read_u16()?);
153 item_def.model_data.modified_colors.push(reader.read_u16()?);
154 }
155 }
156 41 => {
157 let len = reader.read_u8()? as usize;
158 item_def.model_data.original_texture_colors = Vec::with_capacity(len);
159 item_def.model_data.original_texture_colors = Vec::with_capacity(len);
160 for _ in 0..len {
161 item_def
162 .model_data
163 .original_texture_colors
164 .push(reader.read_u16()?);
165 item_def
166 .model_data
167 .original_texture_colors
168 .push(reader.read_u16()?);
169 }
170 }
171 42 => {
172 let len = reader.read_u8()?;
173 for _ in 0..len {
174 reader.read_u8()?;
175 }
176 }
177 65 => {
178 item_def.unnoted = true;
179 }
180 78 => {
181 item_def.model_data.male_equip_id = reader.read_smart()?;
182 }
183 79 => {
184 item_def.model_data.female_equip_id = reader.read_smart()?;
185 }
186 97 => {
187 item_def.noted_id = Some(reader.read_u16()?);
188 }
189 98 => {
190 item_def.noted_template = Some(reader.read_u16()?);
191 item_def.stackable = true;
192 }
193 100..=109 => {
194 item_def.stack_ids = Some([0; 10]);
195 item_def.stack_count = Some([0; 10]);
196 match item_def.stack_ids {
197 Some(mut stack_ids) => {
198 stack_ids[opcode as usize - 100] = reader.read_u16()?;
199 }
200 _ => unreachable!(),
201 }
202 match item_def.stack_count {
203 Some(mut stack_count) => {
204 stack_count[opcode as usize - 100] = reader.read_u16()?;
205 }
206 _ => unreachable!(),
207 }
208 }
209 115 => {
210 item_def.team = reader.read_u8()?;
211 }
212 121 => {
213 item_def.lend_id = Some(reader.read_u16()?);
214 item_def.interface_options[4] = "Discard".to_owned();
215 item_def.lent = true;
216 }
217 122 => {
218 item_def.lend_tempalte = Some(reader.read_u16()?);
219 }
220 125 | 126 => {
221 reader.read_u8()?;
222 reader.read_u8()?;
223 reader.read_u8()?;
224 }
225 127..=130 => {
226 reader.read_u8()?;
227 reader.read_u16()?;
228 }
229 132 => {
230 let len = reader.read_u8()?;
231 for _ in 0..len {
232 reader.read_u16()?;
233 }
234 }
235 139 => {
236 item_def.bind_link = Some(reader.read_u16()?);
237 item_def.interface_options[4] = "Destroy".to_owned();
238 }
239 140 => {
240 item_def.bind_tempalte = Some(reader.read_u16()?);
241 }
242 164 => {
243 reader.read_string()?;
244 }
245 251 | 252 => {
246 let len = reader.read_u8()?;
247 for _ in 0..len {
248 reader.read_u16()?;
249 reader.read_u16()?;
250 }
251 }
252 249 => {
253 util::read_parameters(reader)?;
254 }
255 15 | 156 | 157 | 165 | 167 => {}
256 96 | 113 | 114 | 134 => {
257 reader.read_u8()?;
258 }
259 18 | 44 | 45 | 94 | 95 | 110..=112 | 142..=146 | 150..=154 | 161..=163 => {
260 reader.read_u16()?;
261 }
262 90..=93 | 242..=248 => {
263 reader.read_smart()?;
264 }
265 _ => {
266 println!("{} {}", id, opcode);
267 unreachable!()
268 }
269 }
270 }
271
272 Ok(item_def)
273}