mindustry logic execution, map- and schematic- parsing and rendering
Implement schematic type
| -rw-r--r-- | src/block/mod.rs | 1 | ||||
| -rw-r--r-- | src/data/mod.rs | 1 | ||||
| -rw-r--r-- | src/data/schematic.rs | 119 |
3 files changed, 121 insertions, 0 deletions
diff --git a/src/block/mod.rs b/src/block/mod.rs index 09d9cfa..e9f9a23 100644 --- a/src/block/mod.rs +++ b/src/block/mod.rs @@ -39,6 +39,7 @@ impl Block } } +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Rotation { Right, Up, Left, Down diff --git a/src/data/mod.rs b/src/data/mod.rs index 877c606..029476a 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -3,6 +3,7 @@ use std::str::Utf8Error; pub mod base64; pub mod dynamic; +pub mod schematic; pub struct DataRead<'d> { diff --git a/src/data/schematic.rs b/src/data/schematic.rs new file mode 100644 index 0000000..b52e402 --- /dev/null +++ b/src/data/schematic.rs @@ -0,0 +1,119 @@ +use std::collections::HashMap; + +use crate::block::{Block, Rotation}; + +pub const MAX_DIMENSION: u16 = 128; +pub const MAX_BLOCKS: u32 = 128 * 128; + +#[derive(Clone, Copy)] +struct Storage(&'static Block, Rotation); + +#[derive(Clone)] +pub struct Schematic +{ + width: u16, + height: u16, + tags: HashMap<String, String>, + blocks: Vec<Option<Storage>>, + block_cnt: u32, +} + +impl Schematic +{ + pub fn new(width: u16, height: u16) -> Self + { + if width > MAX_DIMENSION + { + panic!("invalid schematic width ({width})"); + } + if height > MAX_DIMENSION + { + panic!("invalid schematic width ({height})"); + } + let mut tags = HashMap::<String, String>::new(); + tags.insert("name".to_string(), String::new()); + tags.insert("description".to_string(), String::new()); + tags.insert("labels".to_string(), "[]".to_string()); + Self{width, height, tags, blocks: Vec::new(), block_cnt: 0} + } + + pub fn get_width(&self) -> u16 + { + self.width + } + + pub fn get_height(&self) -> u16 + { + self.height + } + + pub fn get_tags(&self) -> &HashMap<String, String> + { + &self.tags + } + + pub fn get_tags_mut(&mut self) -> &mut HashMap<String, String> + { + &mut self.tags + } + + pub fn get(&self, x: u16, y: u16) -> Option<(&'static Block, Rotation)> + { + if x >= self.width || y >= self.height + { + panic!("position {x} / {y} out of bounds ({} / {})", self.width, self.height); + } + if self.block_cnt == 0 {return None;} + let index = (x as usize) + (y as usize) * (self.width as usize); + match self.blocks.get(index) + { + None => None, + Some(None) => None, + Some(Some(Storage(b, r))) => Some((*b, *r)), + } + } + + pub fn set(&mut self, x: u16, y: u16, block: &'static Block, rot: Rotation) -> Option<(&'static Block, Rotation)> + { + if x >= self.width || y >= self.height + { + panic!("position {x} / {y} out of bounds ({} / {})", self.width, self.height); + } + if self.blocks.len() == 0 + { + self.blocks.resize_with((self.width as usize) * (self.height as usize), || None); + } + let index = (x as usize) + (y as usize) * (self.width as usize); + match self.blocks[index].replace(Storage(block, rot)) + { + None => + { + self.block_cnt += 1; + None + }, + Some(s) => Some((s.0, s.1)), + } + } + + pub fn take(&mut self, x: u16, y: u16) -> Option<(&'static Block, Rotation)> + { + if x >= self.width || y >= self.height + { + panic!("position {x} / {y} out of bounds ({} / {})", self.width, self.height); + } + if self.blocks.len() > 0 + { + let index = (x as usize) + (y as usize) * (self.width as usize); + match self.blocks[index].take() + { + None => None, + Some(s) => + { + self.block_cnt -= 1; + Some((s.0, s.1)) + }, + } + } + else {None} + } +} |