wolfrpg_map_parser/db_parser/models/
tileset.rs

1use crate::byte_utils::{as_u32_le, as_u32_vec, parse_string};
2use crate::db_parser::models::tile::Tile;
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6/// Detailed information on a tileset.
7#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
8#[derive(PartialEq, Clone)]
9pub struct Tileset {
10    index: usize,
11    name: String,
12    base_tileset: String,
13    auto_tiles: [String; 15],
14    tiles: Vec<Tile>
15}
16
17impl Tileset {
18    pub(crate) fn parse(bytes: &[u8], index: usize) -> (usize, Self) {
19        let mut offset: usize = 0;
20
21        let (bytes_read, name): (usize, String) = parse_string(&bytes[offset..]);
22        offset += bytes_read;
23        
24        let (bytes_read, base_tileset): (usize, String) = parse_string(&bytes[offset..]);
25        offset += bytes_read;
26        
27        let mut auto_tiles: Vec<String> = Vec::with_capacity(15);
28        
29        for _ in 0..15 {
30            let (bytes_read, string): (usize, String) = parse_string(&bytes[offset..]);
31            offset += bytes_read;
32            auto_tiles.push(string);
33        }
34        
35        let auto_tiles: [String; 15] = auto_tiles.try_into().unwrap();
36        
37        offset += 1; // Padding
38        
39        let tags_len: usize = as_u32_le(&bytes[offset..]) as usize;
40        offset += 4;
41        
42        let tag_numbers: Vec<u8> = bytes[offset..][..tags_len].to_vec();
43        offset += tags_len;
44        
45        offset += 1; // Padding
46        
47        // Should be equal to tags_len
48        let directions_len: usize = as_u32_le(&bytes[offset..]) as usize; 
49        offset += 4;
50        
51        let directions: Vec<u32> = as_u32_vec(&bytes[offset..][..4 * directions_len]);
52        offset += 4 * directions_len;
53        
54        let tiles: Vec<Tile> = tag_numbers.iter()
55            .zip(directions.iter())
56            .map(|(tag, options)| Tile::new(*tag, *options))
57            .collect();
58        
59        (offset, Self {
60            index,
61            name,
62            base_tileset,
63            auto_tiles,
64            tiles
65        })
66    }
67
68    /// The index of this tileset in the list.
69    pub fn index(&self) -> usize {
70        self.index
71    }
72
73    /// The name given to this tileset.
74    pub fn name(&self) -> &str {
75        &self.name
76    }
77
78    /// Mutable reference accessor for [`Tileset::name`].
79    pub fn name_mut(&mut self) -> &mut String {
80        &mut self.name
81    }
82
83    /// The file from which most of the tiles are taken.
84    pub fn base_tileset(&self) -> &str {
85        &self.base_tileset
86    }
87
88    /// Mutable reference accessor for [`Tileset::base_tileset`].
89    pub fn base_tileset_mut(&mut self) -> &mut String {
90        &mut self.base_tileset
91    }
92
93    /// A list of files from which the automatic tiles are taken.
94    /// 
95    /// Automatic tiles display differently based on the tiles they are next to, such as
96    /// water rendering the edge of a pond if it's close to grass.
97    pub fn auto_tiles(&self) -> &[String; 15] {
98        &self.auto_tiles
99    }
100
101    /// Mutable reference accessor for [`Tileset::auto_tiles`].
102    pub fn auto_tiles_mut(&mut self) -> &mut [String; 15] {
103        &mut self.auto_tiles
104    }
105
106    /// Specific settings for each tile of the tileset.
107    pub fn tiles(&self) -> &Vec<Tile> {
108        &self.tiles
109    }
110
111    /// Mutable reference accessor for [`Tileset::tiles`].
112    pub fn tiles_mut(&mut self) -> &mut Vec<Tile> {
113        &mut self.tiles
114    }
115}