mindustry logic execution, map- and schematic- parsing and rendering
-rw-r--r--src/block/base.rs8
-rw-r--r--src/block/defense.rs8
-rw-r--r--src/block/fluid.rs8
-rw-r--r--src/block/logic.rs35
-rw-r--r--src/block/mod.rs19
-rw-r--r--src/block/payload.rs16
-rw-r--r--src/block/power.rs19
-rw-r--r--src/block/simple.rs10
-rw-r--r--src/block/transport.rs35
-rw-r--r--src/data/schematic.rs8
10 files changed, 166 insertions, 0 deletions
diff --git a/src/block/base.rs b/src/block/base.rs
index 33b4ae8..e62fd86 100644
--- a/src/block/base.rs
+++ b/src/block/base.rs
@@ -111,6 +111,14 @@ impl BlockLogic for LampBlock
Box::new(Self::create_state(*state))
}
+ fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool)
+ {
+ }
+
+ fn rotate_state(&self, _: &mut dyn Any, _: bool)
+ {
+ }
+
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>
{
let state = Self::get_state(state);
diff --git a/src/block/defense.rs b/src/block/defense.rs
index dd1f926..48de13c 100644
--- a/src/block/defense.rs
+++ b/src/block/defense.rs
@@ -97,6 +97,14 @@ impl BlockLogic for DoorBlock
Box::new(Self::create_state(*state))
}
+ fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool)
+ {
+ }
+
+ fn rotate_state(&self, _: &mut dyn Any, _: bool)
+ {
+ }
+
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>
{
let state = Self::get_state(state);
diff --git a/src/block/fluid.rs b/src/block/fluid.rs
index 9f57ff0..41a4eeb 100644
--- a/src/block/fluid.rs
+++ b/src/block/fluid.rs
@@ -103,6 +103,14 @@ impl BlockLogic for FluidBlock
Box::new(Self::create_state(*state))
}
+ fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool)
+ {
+ }
+
+ fn rotate_state(&self, _: &mut dyn Any, _: bool)
+ {
+ }
+
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>
{
match Self::get_state(state)
diff --git a/src/block/logic.rs b/src/block/logic.rs
index 4946bdb..879c8b3 100644
--- a/src/block/logic.rs
+++ b/src/block/logic.rs
@@ -92,6 +92,14 @@ impl BlockLogic for MessageLogic
Box::new(Self::get_state(state).clone())
}
+ fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool)
+ {
+ }
+
+ fn rotate_state(&self, _: &mut dyn Any, _: bool)
+ {
+ }
+
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>
{
Ok(DynData::String(Some(Self::get_state(state).clone())))
@@ -165,6 +173,14 @@ impl BlockLogic for SwitchLogic
Box::new(Self::get_state(state).clone())
}
+ fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool)
+ {
+ }
+
+ fn rotate_state(&self, _: &mut dyn Any, _: bool)
+ {
+ }
+
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>
{
Ok(DynData::Boolean(*Self::get_state(state)))
@@ -299,6 +315,25 @@ impl BlockLogic for ProcessorLogic
Box::new(Self::get_state(state).clone())
}
+ fn mirror_state(&self, state: &mut dyn Any, horizontally: bool, vertically: bool)
+ {
+ for link in Self::get_state_mut(state).links.iter_mut()
+ {
+ if horizontally {link.x = -link.x;}
+ if vertically {link.y = -link.y;}
+ }
+ }
+
+ fn rotate_state(&self, state: &mut dyn Any, clockwise: bool)
+ {
+ for link in Self::get_state_mut(state).links.iter_mut()
+ {
+ let (cdx, cdy) = link.get_pos();
+ link.x = if clockwise {cdy} else {-cdy};
+ link.y = if clockwise {-cdx} else {cdx};
+ }
+ }
+
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>
{
let state = Self::get_state(state);
diff --git a/src/block/mod.rs b/src/block/mod.rs
index 6916c3d..1ddd337 100644
--- a/src/block/mod.rs
+++ b/src/block/mod.rs
@@ -37,6 +37,10 @@ pub trait BlockLogic
fn clone_state(&self, state: &dyn Any) -> Box<dyn Any>;
+ fn mirror_state(&self, state: &mut dyn Any, horizontally: bool, vertically: bool);
+
+ fn rotate_state(&self, state: &mut dyn Any, clockwise: bool);
+
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>;
}
@@ -207,6 +211,21 @@ impl Block
self.logic.clone_state(state)
}
+ pub fn mirror_state(&self, state: &mut dyn Any, horizontally: bool, vertically: bool)
+ {
+ self.logic.mirror_state(state, horizontally, vertically);
+ }
+
+ pub fn rotate_state(&self, state: &mut dyn Any, clockwise: bool)
+ {
+ self.logic.rotate_state(state, clockwise);
+ }
+
+ pub fn rotate_180(&mut self, state: &mut dyn Any)
+ {
+ self.logic.mirror_state(state, true, true);
+ }
+
pub fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>
{
self.logic.serialize_state(state)
diff --git a/src/block/payload.rs b/src/block/payload.rs
index 164c0bb..bf6bc76 100644
--- a/src/block/payload.rs
+++ b/src/block/payload.rs
@@ -125,6 +125,14 @@ impl BlockLogic for AssemblerBlock
Box::new(Self::create_state(*state))
}
+ fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool)
+ {
+ }
+
+ fn rotate_state(&self, _: &mut dyn Any, _: bool)
+ {
+ }
+
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>
{
if let Some(state) = Self::get_state(state)
@@ -261,6 +269,14 @@ impl BlockLogic for PayloadBlock
Box::new(Self::create_state(*state))
}
+ fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool)
+ {
+ }
+
+ fn rotate_state(&self, _: &mut dyn Any, _: bool)
+ {
+ }
+
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>
{
match Self::get_state(state)
diff --git a/src/block/power.rs b/src/block/power.rs
index 55a51da..8a7576b 100644
--- a/src/block/power.rs
+++ b/src/block/power.rs
@@ -111,6 +111,25 @@ impl BlockLogic for ConnectorBlock
Box::new(Self::get_state(state).clone())
}
+ fn mirror_state(&self, state: &mut dyn Any, horizontally: bool, vertically: bool)
+ {
+ for (dx, dy) in Self::get_state_mut(state).iter_mut()
+ {
+ if horizontally {*dx = -*dx;}
+ if vertically {*dy = -*dy;}
+ }
+ }
+
+ fn rotate_state(&self, state: &mut dyn Any, clockwise: bool)
+ {
+ for (dx, dy) in Self::get_state_mut(state).iter_mut()
+ {
+ let (cdx, cdy) = (*dx, *dy);
+ *dx = if clockwise {cdy} else {-cdy};
+ *dy = if clockwise {-cdx} else {cdx};
+ }
+ }
+
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>
{
Ok(DynData::Point2Array(Self::get_state(state).clone()))
diff --git a/src/block/simple.rs b/src/block/simple.rs
index dcbe0dc..96f6b77 100644
--- a/src/block/simple.rs
+++ b/src/block/simple.rs
@@ -93,6 +93,16 @@ impl BlockLogic for SimpleBlock
panic!("{} has no custom state", type_name::<Self>())
}
+ fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool)
+ {
+ panic!("{} has no custom state", type_name::<Self>());
+ }
+
+ fn rotate_state(&self, _: &mut dyn Any, _: bool)
+ {
+ panic!("{} has no custom state", type_name::<Self>());
+ }
+
fn serialize_state(&self, _: &dyn Any) -> Result<DynData, SerializeError>
{
Ok(DynData::Empty)
diff --git a/src/block/transport.rs b/src/block/transport.rs
index f1e8dae..bba7408 100644
--- a/src/block/transport.rs
+++ b/src/block/transport.rs
@@ -104,6 +104,14 @@ impl BlockLogic for ItemBlock
Box::new(Self::create_state(*state))
}
+ fn mirror_state(&self, _: &mut dyn Any, _: bool, _: bool)
+ {
+ }
+
+ fn rotate_state(&self, _: &mut dyn Any, _: bool)
+ {
+ }
+
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>
{
match Self::get_state(state)
@@ -291,6 +299,33 @@ impl BlockLogic for BridgeBlock
Box::new(Self::create_state(*state))
}
+ fn mirror_state(&self, state: &mut dyn Any, horizontally: bool, vertically: bool)
+ {
+ match Self::get_state_mut(state)
+ {
+ None => (),
+ Some((dx, dy)) =>
+ {
+ if horizontally {*dx = -*dx;}
+ if vertically {*dy = -*dy;}
+ },
+ }
+ }
+
+ fn rotate_state(&self, state: &mut dyn Any, clockwise: bool)
+ {
+ match Self::get_state_mut(state)
+ {
+ None => (),
+ Some((dx, dy)) =>
+ {
+ let (cdx, cdy) = (*dx, *dy);
+ *dx = if clockwise {cdy} else {-cdy};
+ *dy = if clockwise {-cdx} else {cdx};
+ },
+ }
+ }
+
fn serialize_state(&self, state: &dyn Any) -> Result<DynData, SerializeError>
{
match Self::get_state(state)
diff --git a/src/data/schematic.rs b/src/data/schematic.rs
index 65f5575..d5d325f 100644
--- a/src/data/schematic.rs
+++ b/src/data/schematic.rs
@@ -386,6 +386,10 @@ impl<'l> Schematic<'l>
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);}
+ if let Some(ref mut state) = curr.state
+ {
+ curr.block.mirror_state(state.as_mut(), horizontally, vertically);
+ }
}
self.rebuild_lookup();
}
@@ -416,6 +420,10 @@ impl<'l> Schematic<'l>
curr.pos.1 = x;
}
if !curr.block.is_symmetric() {curr.rot.rotate(clockwise);}
+ if let Some(ref mut state) = curr.state
+ {
+ curr.block.rotate_state(state.as_mut(), clockwise);
+ }
}
self.rebuild_lookup();
}