use std::collections::{
hash_map::{self, Entry},
HashMap,
};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::{
definition::osrs::{
Definition, FetchDefinition, ItemDefinition, LocationDefinition, MapDefinition,
NpcDefinition, ObjectDefinition,
},
Cache,
};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Eq, PartialEq, Debug, Default)]
pub struct ItemLoader(HashMap<u16, ItemDefinition>);
impl_osrs_loader!(ItemLoader, ItemDefinition, index_id: 2, archive_id: 10);
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Eq, PartialEq, Debug, Default)]
pub struct NpcLoader(HashMap<u16, NpcDefinition>);
impl_osrs_loader!(NpcLoader, NpcDefinition, index_id: 2, archive_id: 9);
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Clone, Eq, PartialEq, Debug, Default)]
pub struct ObjectLoader(HashMap<u16, ObjectDefinition>);
impl_osrs_loader!(ObjectLoader, ObjectDefinition, index_id: 2, archive_id: 6);
#[derive(Debug)]
pub struct MapLoader<'cache> {
cache: &'cache Cache,
maps: HashMap<u16, MapDefinition>,
}
impl<'cache> MapLoader<'cache> {
pub fn new(cache: &'cache Cache) -> Self {
Self {
cache,
maps: HashMap::new(),
}
}
pub fn load(&mut self, id: u16) -> crate::Result<&MapDefinition> {
if let Entry::Vacant(entry) = self.maps.entry(id) {
let x = id >> 8;
let y = id & 0xFF;
let map_archive = self.cache.archive_by_name(5, format!("m{}_{}", x, y))?;
let buffer = self.cache.read_archive(map_archive)?.decode()?;
entry.insert(MapDefinition::new(id, &buffer)?);
}
Ok(&self.maps[&id])
}
}
#[derive(Debug)]
pub struct LocationLoader<'cache> {
cache: &'cache Cache,
locations: HashMap<u16, LocationDefinition>,
}
impl<'cache> LocationLoader<'cache> {
pub fn new(cache: &'cache Cache) -> Self {
Self {
cache,
locations: HashMap::new(),
}
}
pub fn load(&mut self, id: u16, keys: &[u32; 4]) -> crate::Result<&LocationDefinition> {
if let Entry::Vacant(entry) = self.locations.entry(id) {
let x = id >> 8;
let y = id & 0xFF;
let loc_archive = self.cache.archive_by_name(5, format!("l{}_{}", x, y))?;
let buffer = self
.cache
.read_archive(loc_archive)?
.with_xtea_keys(*keys)
.decode()?;
entry.insert(LocationDefinition::new(id, &buffer)?);
}
Ok(&self.locations[&id])
}
}