Skip to main content

uorustlibs/map/
static_location.rs

1//! Methods for reading static prop locations from muls
2//!
3//! Each index location maps directly to a block in the map files. Each mul record represents
4//! all of the static objects in a block, as a list of StaticLocations
5//!
6//! A StaticLocation is defined as
7//!
8//! `|object_id:u16|x:y8|y:u8|altitude:i8|`
9//!
10//! As with MapReader, methods allow the passing of a patch reader to simplify applying patches.
11use super::diff::StaticLocationDiffReader;
12use super::shared::{StaticLocation, read_block_statics};
13use crate::error::{MulReaderError, MulReaderResult};
14use crate::mul::MulReader;
15use std::fs::File;
16use std::io::{Read, Seek};
17use std::path::Path;
18
19/// A struct to help read out Static locations for a map
20///
21/// The methods on this struct optionally take a StaticLocationDiffReader,
22/// to make it easier to apply patches to a map
23#[derive(Debug)]
24pub struct StaticLocationReader<T: Read + Seek> {
25    mul_reader: MulReader<T>,
26    /// Width, in blocks
27    width: u32,
28    /// Height, in blocks
29    height: u32,
30}
31
32impl StaticLocationReader<File> {
33    /// Create a new StaticLocationReader from an index and mul path
34    pub fn new(
35        index_path: &Path,
36        mul_path: &Path,
37        width_blocks: u32,
38        height_blocks: u32,
39    ) -> MulReaderResult<StaticLocationReader<File>> {
40        let mul_reader = MulReader::new(index_path, mul_path)?;
41
42        Ok(StaticLocationReader {
43            mul_reader,
44            width: width_blocks,
45            height: height_blocks,
46        })
47    }
48}
49
50impl<T: Read + Seek> StaticLocationReader<T> {
51    /// Create an ArtReader from an existing mul reader
52    pub fn from_mul(
53        mul_reader: MulReader<T>,
54        width_blocks: u32,
55        height_blocks: u32,
56    ) -> StaticLocationReader<T> {
57        StaticLocationReader {
58            mul_reader,
59            width: width_blocks,
60            height: height_blocks,
61        }
62    }
63
64    /// Read all statics for a block from the map by its id
65    /// Blocks are stored in columns, from top of the map to to bottom
66    pub fn read_block(
67        &mut self,
68        id: u32,
69        patch: Option<&mut StaticLocationDiffReader<T>>,
70    ) -> MulReaderResult<Vec<StaticLocation>> {
71        match patch {
72            Some(reader) => reader
73                .read(id)
74                .unwrap_or_else(|| read_block_statics(&mut self.mul_reader, id)),
75            None => read_block_statics(&mut self.mul_reader, id),
76        }
77    }
78
79    /// Read all statics block from the map by its absolute coordinates
80    pub fn read_block_from_coordinates(
81        &mut self,
82        x: u32,
83        y: u32,
84        patch: Option<&mut StaticLocationDiffReader<T>>,
85    ) -> MulReaderResult<Vec<StaticLocation>> {
86        let width = self.width;
87        let height = self.height;
88        if x < width && y < height {
89            self.read_block(y + (x * height), patch)
90        } else {
91            Err(MulReaderError::CoordinatesOutOfBounds { x, y })
92        }
93    }
94}