simple_anvil/
block.rs

1use core::{fmt, panic};
2
3use nbt::Value;
4
5/// A Minecraft block. This struct does not store any data about the location because
6/// to get a block one must use x, y, and z coordinates on a Chunk and thus would
7/// already have the location data.
8#[derive(Debug, Eq, PartialEq)]
9pub struct Block {
10    namespace: String,
11    /// The general name of a block, ie. 'stone'
12    pub id: String,
13    /// The coordinates of the block, None if not included.
14    pub coords: Option<(i32, i32, i32)>,
15    /// Any properties that a block might have.
16    pub properties: Option<Vec<(String, String)>>
17}
18
19impl Block {
20    /// Returns a new block with a given namespace and id.
21    ///
22    /// # Arguments
23    ///
24    /// * `namespace` - The namespace for the found block, for vanilla this will always be 'minecraft'. For modded
25    /// versions of Minecraft this would represent the namespace of the mod.
26    /// * `block_id` - The id of the block, this is typically the name of the block without spaces.
27    ///
28    /// # Examples
29    ///
30    /// ```rust
31    /// use simple_anvil::block::Block;
32    /// let block = Block::new("minecraft".into(), Some("stone".into()));
33    /// println!("{}", block.id);
34    /// ```
35    pub fn new(namespace: String, block_id: Option<String>, coords: Option<(i32, i32, i32)>, properties: Option<Vec<(String, String)>>) -> Block {
36        match block_id {
37            Some(id) => return Block { namespace, id, coords, properties },
38            None => {
39                return Block {
40                    namespace: namespace.clone(),
41                    id: namespace,
42                    coords,
43                    properties
44                };
45            }
46        }
47    }
48
49    /// Returns the full name of the block in question, this looks like 'namespace:block_id' or 'minecraft:stone'.
50    ///
51    /// # Examples
52    ///
53    /// ```rust
54    /// use simple_anvil::block::Block;
55    /// let block = Block::new("minecraft".into(), Some("stone".into()));
56    /// println!("{}", block.name());
57    /// ```
58    pub fn name(self) -> String {
59        let mut name = self.namespace;
60        name += ":";
61        name += self.id.as_str();
62        return name;
63    }
64
65    /// Returns a Block from a name
66    ///
67    /// # Arguments
68    ///
69    /// * `name` - The fullname of the block, this includes the namespace and the colon.
70    /// * `coords` - The coordinates of the block, None if not included.
71    ///  
72    /// # Examples
73    ///
74    /// ```rust
75    /// use simple_anvil::block::Block;
76    /// let block = Block::from_name("minecraft:stone".into());
77    /// println!("{}", block.id);
78    /// ```
79    pub fn from_name(name: String, coords: Option<(i32, i32, i32)>, properties: Option<Vec<(String, String)>>) -> Block {
80        let temp: Vec<&str> = name.split(":").collect();
81        return Block {
82            namespace: temp[0].to_owned(),
83            id: temp[1].to_owned(),
84            coords,
85            properties
86        };
87    }
88
89    /// Returns a block from a Chunk palette value
90    ///
91    /// # Arguments
92    /// * `tag` - The page representing the palette from a Chunk.
93    /// * `coords` - The coordinates of the block, None if not included.
94    /// * `tag` - The value for the block from a chunk. This should be a HashMap containing all of the contents of the block.
95    pub fn from_palette(tag: &Value, coords: Option<(i32, i32, i32)>, properties: Option<Vec<(String, String)>>) -> Block {
96        let tag = if let Value::Compound(t) = tag {
97            t
98        } else {
99            panic!("Tag passed from palette is not compound")
100        };
101        let name = if let Value::String(n) = tag.get("Name").unwrap() {
102            n
103        } else {
104            panic!("Palette tag missing name?")
105        };
106        return Block::from_name(name.to_string(), coords, properties);
107    }
108}
109
110impl fmt::Display for Block {
111    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
112        write!(f, "{}:{}", self.namespace, self.id)
113    }
114}