use crate::error::Result;
use crate::reader::{parse_counted, ByteReader};
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone)]
pub struct RandomUnit {
pub chance: i32,
pub ids: Vec<[u8; 4]>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone)]
pub struct RandomUnitTable {
pub id: i32,
pub name: String,
pub columns: i32,
pub column_types: Vec<i32>,
pub units: Vec<RandomUnit>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone)]
pub struct RandomItem {
pub chance: i32,
pub id: [u8; 4],
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone)]
pub struct RandomItemSet {
pub items: Vec<RandomItem>,
}
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone)]
pub struct RandomItemTable {
pub id: i32,
pub name: String,
pub sets: Vec<RandomItemSet>,
}
impl RandomUnitTable {
pub(crate) fn parse(r: &mut ByteReader<'_>) -> Result<Self> {
let id = r.i32()?;
let name = r.cstr_lossy()?;
let columns = r.i32()?;
let mut column_types = Vec::with_capacity(columns.max(0) as usize);
for _ in 0..columns {
column_types.push(r.i32()?);
}
let rows = r.u32()?;
let mut units = Vec::with_capacity((rows as usize).min(4096));
for _ in 0..rows {
let chance = r.i32()?;
let mut ids = Vec::with_capacity(columns.max(0) as usize);
for _ in 0..columns {
ids.push(r.bytes()?);
}
units.push(RandomUnit { chance, ids });
}
Ok(Self {
id,
name,
columns,
column_types,
units,
})
}
}
impl RandomItemTable {
pub(crate) fn parse(r: &mut ByteReader<'_>) -> Result<Self> {
Ok(Self {
id: r.i32()?,
name: r.cstr_lossy()?,
sets: parse_counted(r, |r| {
Ok(RandomItemSet {
items: parse_counted(r, |r| {
Ok(RandomItem {
chance: r.i32()?,
id: r.bytes()?,
})
})?,
})
})?,
})
}
}