1use std::collections::{
2 hash_map::{self, Entry},
3 HashMap,
4};
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9use crate::{
10 definition::osrs::{
11 Definition, FetchDefinition, ItemDefinition, LocationDefinition, MapDefinition,
12 NpcDefinition, ObjectDefinition,
13 },
14 Cache,
15};
16
17#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
19#[derive(Clone, Eq, PartialEq, Debug, Default)]
20pub struct ItemLoader(HashMap<u16, ItemDefinition>);
21
22impl_osrs_loader!(ItemLoader, ItemDefinition, index_id: 2, archive_id: 10);
23
24#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
26#[derive(Clone, Eq, PartialEq, Debug, Default)]
27pub struct NpcLoader(HashMap<u16, NpcDefinition>);
28
29impl_osrs_loader!(NpcLoader, NpcDefinition, index_id: 2, archive_id: 9);
30
31#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
33#[derive(Clone, Eq, PartialEq, Debug, Default)]
34pub struct ObjectLoader(HashMap<u16, ObjectDefinition>);
35
36impl_osrs_loader!(ObjectLoader, ObjectDefinition, index_id: 2, archive_id: 6);
37
38#[derive(Debug)]
40pub struct MapLoader<'cache> {
41 cache: &'cache Cache,
42 maps: HashMap<u16, MapDefinition>,
43}
44
45impl<'cache> MapLoader<'cache> {
46 pub fn new(cache: &'cache Cache) -> Self {
52 Self {
53 cache,
54 maps: HashMap::new(),
55 }
56 }
57
58 pub fn load(&mut self, id: u16) -> crate::Result<&MapDefinition> {
59 if let Entry::Vacant(entry) = self.maps.entry(id) {
60 let x = id >> 8;
61 let y = id & 0xFF;
62
63 let map_archive = self.cache.archive_by_name(5, format!("m{}_{}", x, y))?;
64 let buffer = self.cache.read_archive(map_archive)?.decode()?;
65
66 entry.insert(MapDefinition::new(id, &buffer)?);
67 }
68
69 Ok(&self.maps[&id])
70 }
71}
72
73#[derive(Debug)]
75pub struct LocationLoader<'cache> {
76 cache: &'cache Cache,
77 locations: HashMap<u16, LocationDefinition>,
78}
79
80impl<'cache> LocationLoader<'cache> {
81 pub fn new(cache: &'cache Cache) -> Self {
87 Self {
88 cache,
89 locations: HashMap::new(),
90 }
91 }
92
93 pub fn load(&mut self, id: u16, keys: &[u32; 4]) -> crate::Result<&LocationDefinition> {
98 if let Entry::Vacant(entry) = self.locations.entry(id) {
99 let x = id >> 8;
100 let y = id & 0xFF;
101
102 let loc_archive = self.cache.archive_by_name(5, format!("l{}_{}", x, y))?;
103 let buffer = self
104 .cache
105 .read_archive(loc_archive)?
106 .with_xtea_keys(*keys)
107 .decode()?;
108
109 entry.insert(LocationDefinition::new(id, &buffer)?);
110 }
111
112 Ok(&self.locations[&id])
113 }
114}
115