use serde::Serialize;
use super::ItemId;
use crate::Result;
use crate::io::Reader;
const RECORD_LEN: usize = 7;
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct Item {
pub id: ItemId,
pub name: String,
pub description: String,
pub price: u16,
pub pocket: Pocket,
pub held_effect: u8,
pub held_parameter: u8,
pub permissions: u8,
pub field_menu: u8,
pub battle_menu: u8,
}
raw_enum! {
pub enum Pocket: u8 {
Items = 1,
KeyItems = 2,
Balls = 3,
Machines = 4,
}
}
pub(super) fn parse(
attributes: &[u8],
names: &[String],
descriptions: &[String],
) -> Result<Vec<Item>> {
attributes
.as_chunks::<RECORD_LEN>()
.0
.iter()
.enumerate()
.map(|(index, bytes)| {
let mut record = Reader::new("Gen 2 item", bytes);
let price = record.u16()?;
let held_effect = record.u8()?;
let held_parameter = record.u8()?;
let permissions = record.u8()?;
let pocket = Pocket::from_raw(record.u8()?);
let menus = record.u8()?;
Ok(Item {
id: ItemId(index as u16 + 1),
name: names.get(index).cloned().unwrap_or_default(),
description: descriptions.get(index).cloned().unwrap_or_default(),
price,
pocket,
held_effect,
held_parameter,
permissions,
field_menu: menus >> 4,
battle_menu: menus & 0xF,
})
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn parses_attributes() {
let potion = [0x2C, 0x01, 0, 20, 0x40, 1, 0x55];
let items = parse(&potion, &["POTION".to_owned()], &[]).unwrap();
assert_eq!((items[0].price, items[0].pocket), (300, Pocket::Items));
assert_eq!((items[0].field_menu, items[0].battle_menu), (5, 5));
}
}