mindustry logic execution, map- and schematic- parsing and rendering
Implement basic Schematic transformations
KosmosPrime 2023-01-01
parent 46c76b4 · commit 5298963
-rw-r--r--src/block/mod.rs51
-rw-r--r--src/data/schematic.rs77
2 files changed, 128 insertions, 0 deletions
diff --git a/src/block/mod.rs b/src/block/mod.rs
index 5a8ff22..f3b3e82 100644
--- a/src/block/mod.rs
+++ b/src/block/mod.rs
@@ -59,6 +59,57 @@ pub enum Rotation
Right, Up, Left, Down
}
+impl Rotation
+{
+ pub fn mirrored(self, horizontally: bool, vertically: bool) -> Self
+ {
+ match self
+ {
+ Rotation::Right => if horizontally {Rotation::Left} else {Rotation::Right},
+ Rotation::Up => if vertically {Rotation::Down} else {Rotation::Up},
+ Rotation::Left => if horizontally {Rotation::Right} else {Rotation::Left},
+ Rotation::Down => if vertically {Rotation::Up} else {Rotation::Down},
+ }
+ }
+
+ pub fn mirror(&mut self, horizontally: bool, vertically: bool)
+ {
+ *self = self.mirrored(horizontally, vertically);
+ }
+
+ pub fn rotated(self, clockwise: bool) -> Self
+ {
+ match self
+ {
+ Rotation::Right => if clockwise {Rotation::Up} else {Rotation::Down},
+ Rotation::Up => if clockwise {Rotation::Left} else {Rotation::Right},
+ Rotation::Left => if clockwise {Rotation::Down} else {Rotation::Up},
+ Rotation::Down => if clockwise {Rotation::Right} else {Rotation::Left},
+ }
+ }
+
+ pub fn rotate(&mut self, clockwise: bool)
+ {
+ *self = self.rotated(clockwise);
+ }
+
+ pub fn rotated_180(self) -> Self
+ {
+ match self
+ {
+ Rotation::Right => Rotation::Left,
+ Rotation::Up => Rotation::Down,
+ Rotation::Left => Rotation::Right,
+ Rotation::Down => Rotation::Up,
+ }
+ }
+
+ pub fn rotate_180(&mut self)
+ {
+ *self = self.rotated_180();
+ }
+}
+
impl From<u8> for Rotation
{
fn from(val: u8) -> Self
diff --git a/src/data/schematic.rs b/src/data/schematic.rs
index cd257ca..fe146aa 100644
--- a/src/data/schematic.rs
+++ b/src/data/schematic.rs
@@ -304,6 +304,83 @@ impl Schematic
else {Ok(None)}
}
+ fn rebuild_lookup(&mut self)
+ {
+ self.lookup.clear();
+ if self.blocks.len() > 0
+ {
+ self.lookup.resize((self.width as usize) * (self.height as usize), None);
+ for (i, curr) in self.blocks.iter().enumerate()
+ {
+ let x = curr.pos.0 as usize;
+ let y = curr.pos.1 as usize;
+ let sz = curr.block.get_size() as usize;
+ if sz > 1
+ {
+ for dy in 0..sz
+ {
+ for dx in 0..sz
+ {
+ self.lookup[(x + dx) + (y + dy) * (self.width as usize)] = Some(i);
+ }
+ }
+ }
+ else {self.lookup[x + y * (self.width as usize)] = Some(i);}
+ }
+ }
+ }
+
+ pub fn mirror(&mut self, horizontally: bool, vertically: bool)
+ {
+ if !self.blocks.is_empty() && (horizontally || vertically)
+ {
+ for curr in self.blocks.iter_mut()
+ {
+ // because position is the bottom left corner (which changes during mirroring)
+ let shift = curr.block.get_size() as u16 - 1;
+ if horizontally {curr.pos.0 = self.width - 1 - curr.pos.0 - shift;}
+ if vertically {curr.pos.1 = self.height - 1 - curr.pos.1 - shift;}
+ if !curr.block.is_symmetric() {curr.rot.mirror(horizontally, vertically);}
+ }
+ self.rebuild_lookup();
+ }
+ }
+
+ pub fn rotate(&mut self, clockwise: bool)
+ {
+ let w = self.width;
+ let h = self.height;
+ self.width = h;
+ self.height = w;
+ if !self.blocks.is_empty()
+ {
+ for curr in self.blocks.iter_mut()
+ {
+ let x = curr.pos.0;
+ let y = curr.pos.1;
+ // because position is the bottom left corner (which changes during rotation)
+ let shift = curr.block.get_size() as u16 - 1;
+ if clockwise
+ {
+ curr.pos.0 = y;
+ curr.pos.1 = w - 1 - x - shift;
+ }
+ else
+ {
+ curr.pos.0 = h - 1 - y - shift;
+ curr.pos.1 = x;
+ }
+ if !curr.block.is_symmetric() {curr.rot.rotate(clockwise);}
+ }
+ self.rebuild_lookup();
+ }
+ }
+
+ pub fn rotate_180(&mut self)
+ {
+ self.mirror(true, true);
+ }
+
pub fn pos_iter(&self) -> PosIter
{
PosIter{x: 0, y: 0, w: self.width, h: self.height}