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}