mindustry logic execution, map- and schematic- parsing and rendering
Implement basic Schematic transformations
| -rw-r--r-- | src/block/mod.rs | 51 | ||||
| -rw-r--r-- | src/data/schematic.rs | 77 |
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} |