1use std::fs::File;
14use std::io::{Read, Seek};
15use std::path::Path;
16
17pub mod diff;
18pub mod radarcol;
19#[cfg(not(test))]
20mod shared;
21#[cfg(test)]
22pub mod shared;
23pub mod static_location;
24
25use crate::error::{MulReaderError, MulReaderResult};
26use crate::map::diff::MapDiffReader;
27use crate::map::shared::read_block;
28pub use crate::map::shared::{Block, Cell, StaticLocation};
29
30pub mod map_size {
32 pub const SOSARIA: (u32, u32) = (896, 512);
33 pub const ILSHENAR: (u32, u32) = (288, 200);
34 pub const MALAS: (u32, u32) = (320, 256);
35 pub const TOKUNO: (u32, u32) = (181, 181);
36 pub const TER_MUR: (u32, u32) = (160, 512);
37}
38
39#[derive(Debug)]
44pub struct MapReader<T: Read + Seek> {
45 data_reader: T,
46 width: u32,
48 height: u32,
50}
51
52impl MapReader<File> {
53 pub fn new(
55 map_path: &Path,
56 width_blocks: u32,
57 height_blocks: u32,
58 ) -> MulReaderResult<MapReader<File>> {
59 let data_reader = File::open(map_path)?;
60
61 Ok(MapReader {
62 data_reader,
63 width: width_blocks,
64 height: height_blocks,
65 })
66 }
67}
68
69impl<T: Read + Seek> MapReader<T> {
70 pub fn from_readable(data_reader: T, width_blocks: u32, height_blocks: u32) -> MapReader<T> {
72 MapReader {
73 data_reader,
74 width: width_blocks,
75 height: height_blocks,
76 }
77 }
78
79 pub fn read_block<U: Read + Seek>(
82 &mut self,
83 id: u32,
84 patch: Option<&mut MapDiffReader<U>>,
85 ) -> MulReaderResult<Block> {
86 match patch {
87 Some(reader) => reader
88 .read(id)
89 .unwrap_or_else(|| read_block(&mut self.data_reader, id)),
90 None => read_block(&mut self.data_reader, id),
91 }
92 }
93
94 pub fn read_block_from_coordinates<U: Read + Seek>(
96 &mut self,
97 x: u32,
98 y: u32,
99 patch: Option<&mut MapDiffReader<U>>,
100 ) -> MulReaderResult<Block> {
101 let width = self.width;
102 let height = self.height;
103 if x < width && y < height {
104 self.read_block(y + (x * height), patch)
105 } else {
106 Err(MulReaderError::CoordinatesOutOfBounds { x, y })
107 }
108 }
109}