mindustry logic execution, map- and schematic- parsing and rendering
-rw-r--r--Cargo.toml3
-rw-r--r--src/block/drills.rs11
-rw-r--r--src/block/mod.rs107
-rw-r--r--src/block/production.rs2
-rw-r--r--src/data/map.rs2
-rw-r--r--src/data/renderer.rs4
-rw-r--r--src/lib.rs2
7 files changed, 116 insertions, 15 deletions
diff --git a/Cargo.toml b/Cargo.toml
index f4c576c..4843f8d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "mindus"
-version = "2.0.2"
+version = "2.0.3"
edition = "2021"
description = "A library for working with mindustry data formats (eg schematics and maps) (fork of plandustry)"
authors = [
@@ -21,6 +21,7 @@ color-hex = "0.2"
thiserror = "1.0"
bobbin-bits = "0.1"
blurslice = { version = "0.1" }
+enum_dispatch = "0.3"
[features]
bin = ["image/png"]
diff --git a/src/block/drills.rs b/src/block/drills.rs
index 8e5c20e..01332b4 100644
--- a/src/block/drills.rs
+++ b/src/block/drills.rs
@@ -8,14 +8,17 @@ make_simple!(
|_, name, _, _, rot: Rotation, s| {
let mut base =
load!(from name which is ["large-plasma-bore" | "plasma-bore" | "cliff-crusher"], s);
- let mut top = load!(concat top => name which is ["large-plasma-bore" | "plasma-bore" | "cliff-crusher"], s);
- top.rotate(rot.rotated(false).count());
- base.overlay(&top);
+ base.overlay(load!(concat top => name which is ["large-plasma-bore" | "plasma-bore" | "cliff-crusher"], s).rotate(rot.rotated(false).count()));
base
},
|_, _, _, buff: &mut DataRead| read_drill(buff)
);
make_simple!(ExtractorBlock);
+make_simple!(WallDrillBlock, |_, _, _, _, rot: Rotation, scl| {
+ let mut base = load!("cliff-crusher", scl);
+ base.overlay(load!("cliff-crusher-top", scl).rotate(rot.rotated(false).count()));
+ base
+});
make_register! {
"mechanical-drill" -> DrillBlock::new(2, true, cost!(Copper: 12));
@@ -25,7 +28,7 @@ make_register! {
"water-extractor" -> ExtractorBlock::new(2, true, cost!(Copper: 30, Lead: 30, Metaglass: 30, Graphite: 30));
"oil-extractor" -> ExtractorBlock::new(3, true, cost!(Copper: 150, Lead: 115, Graphite: 175, Thorium: 115, Silicon: 75));
"vent-condenser" -> ProductionBlock::new(3, true, cost!(Graphite: 20, Beryllium: 60));
- "cliff-crusher" -> DrillBlock::new(2, false, cost!(Beryllium: 100, Graphite: 40));
+ "cliff-crusher" -> WallDrillBlock::new(2, false, cost!(Beryllium: 100, Graphite: 40));
"plasma-bore" => DrillBlock::new(2, false, cost!(Beryllium: 40));
"large-plasma-bore" => DrillBlock::new(3, false, cost!(Silicon: 100, Oxide: 25, Beryllium: 100, Tungsten: 70));
"impact-drill" -> DrillBlock::new(4, true, cost!(Silicon: 70, Beryllium: 90, Graphite: 60));
diff --git a/src/block/mod.rs b/src/block/mod.rs
index 66ea69e..efdc1ba 100644
--- a/src/block/mod.rs
+++ b/src/block/mod.rs
@@ -32,7 +32,94 @@ mods! {
mod simple;
+macro_rules! disp {
+ ($($k:ident,)+) => {
+ use all::{$($k,)+};
+ #[enum_dispatch::enum_dispatch]
+ pub(crate) enum BlockLogicEnum {
+ $($k,)+
+ }
+ #[const_trait]
+ pub trait ConstFrom<T>: Sized {
+ fn fro(value: T) -> Self;
+ }
+ $(
+ impl const ConstFrom<$k> for BlockLogicEnum {
+ fn fro(v: $k) -> Self {
+ BlockLogicEnum::$k(v)
+ }
+ }
+ )+
+
+ /*impl std::fmt::Debug for BlockLogicEnum {
+ fn fmt(&self, w: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
+ match self {
+ $(BlockLogicEnum::$k { .. } => write!(w, stringify!($k)),)+
+ }
+ }
+ }*/
+ }
+}
+
+disp! {
+ EnvironmentBlock,
+ WallBlock,
+ DuctBlock,
+ BridgeBlock,
+ ItemBlock,
+ BatteryBlock,
+ ProductionBlock,
+ StackConveyor,
+ HeatCrafter,
+ ConnectorBlock,
+ ItemTurret,
+ ExtractorBlock,
+ ControlBlock,
+ LiquidBlock,
+ ConveyorBlock,
+ WallDrillBlock,
+ DrillBlock,
+ NuclearGeneratorBlock,
+ GeneratorBlock,
+ ConduitBlock,
+ HeatedBlock,
+ PointDefenseTurret,
+ JunctionBlock,
+ DefenseBlock,
+ Turret,
+ MemoryBlock,
+ MessageLogic,
+ ConstructorBlock,
+ AssemblerBlock,
+ SimpleDuctBlock,
+ SurgeRouter,
+ UnitCargoLoader,
+ LogicBlock,
+ SimplePayloadBlock,
+ PayloadConveyor,
+ ImpactReactorBlock,
+ Neoplasia,
+ DiodeBlock,
+ HeatConduit,
+ Incinerator,
+ StorageBlock,
+ ContinousTurret,
+ TractorBeamTurret,
+ UnitRepairTower,
+ AssemblerModule,
+ RepairTurret,
+ FluidBlock,
+ CanvasBlock,
+ SwitchLogic,
+ ProcessorLogic,
+ PayloadBlock,
+ LampBlock,
+ DoorBlock,
+ CampaignBlock,
+}
+
pub type State = Box<dyn Any + Sync + Send>;
+#[enum_dispatch::enum_dispatch(BlockLogicEnum)]
pub trait BlockLogic {
/// mindustry blocks are the same width and height
fn get_size(&self) -> u8;
@@ -164,7 +251,7 @@ impl SerializeError {
pub struct Block {
image: Option<[&'static LazyLock<RgbaImage>; 3]>,
name: &'static str,
- pub(crate) logic: &'static (dyn BlockLogic + Sync),
+ pub(crate) logic: BlockLogicEnum,
}
impl PartialEq for Block {
@@ -176,9 +263,9 @@ impl PartialEq for Block {
impl Block {
#[must_use]
/// create a new block
- pub const fn new(
+ pub(crate) const fn new(
name: &'static str,
- logic: &'static (dyn BlockLogic + Sync),
+ logic: BlockLogicEnum,
image: Option<[&'static LazyLock<RgbaImage>; 3]>,
) -> Self {
Self { name, logic, image }
@@ -258,6 +345,16 @@ impl Block {
pub(crate) fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> {
self.logic.serialize_state(state)
}
+
+ pub(crate) fn read(
+ &self,
+ build: &mut Build,
+ reg: &BlockRegistry,
+ mapping: &EntityMapping,
+ buff: &mut DataRead,
+ ) -> Result<(), DataReadError> {
+ self.logic.read(build, reg, mapping, buff)
+ }
}
impl fmt::Debug for Block {
@@ -446,12 +543,12 @@ macro_rules! make_register {
}};
(impl $field: literal => $logic: expr) => {
paste::paste! { pub static [<$field:snake:upper>]: $crate::block::Block = $crate::block::Block::new(
- $field, &$logic, None
+ $field, <crate::block::BlockLogicEnum as crate::block::ConstFrom<_>>::fro($logic), None
); }
};
(impl $field: literal -> $logic: expr) => {
paste::paste! { pub static [<$field:snake:upper>]: $crate::block::Block = $crate::block::Block::new(
- $field, &$logic, Some(crate::data::renderer::load!($field))
+ $field, <crate::block::BlockLogicEnum as crate::block::ConstFrom<_>>::fro($logic), Some(crate::data::renderer::load!($field))
); }
}
}
diff --git a/src/block/production.rs b/src/block/production.rs
index 8faf359..9954669 100644
--- a/src/block/production.rs
+++ b/src/block/production.rs
@@ -24,7 +24,7 @@ make_register! {
"coal-centrifuge" -> ProductionBlock::new(2, true, cost!(Lead: 30, Graphite: 40, Titanium: 20));
"incinerator" -> Incinerator::new(1, true, cost!(Lead: 15, Graphite: 5));
"silicon-arc-furnace" -> ProductionBlock::new(3, true, cost!(Beryllium: 70, Graphite: 80));
- "electrolyzer" => ProductionBlock::new(3, true, cost!(Silicon: 50, Graphite: 40, Beryllium: 130, Tungsten: 80));
+ "electrolyzer" -> ProductionBlock::new(3, true, cost!(Silicon: 50, Graphite: 40, Beryllium: 130, Tungsten: 80));
"atmospheric-concentrator" -> ProductionBlock::new(3, true, cost!(Oxide: 60, Beryllium: 180, Silicon: 150));
"oxidation-chamber" => HeatCrafter::new(3, true, cost!(Tungsten: 120, Graphite: 80, Silicon: 100, Beryllium: 120));
"electric-heater" => HeatCrafter::new(2, false, cost!(Tungsten: 30, Oxide: 30));
diff --git a/src/data/map.rs b/src/data/map.rs
index 4bf26cf..911f522 100644
--- a/src/data/map.rs
+++ b/src/data/map.rs
@@ -295,7 +295,7 @@ impl<'l> Build<'l> {
buff.skip(4)?;
}
// "overridden by subclasses"
- self.block.logic.read(self, reg, map, buff)?;
+ self.block.read(self, reg, map, buff)?;
// implementation not complete, simply error, causing the remaining bytes in the chunk to be skipped (TODO finish impl)
Err(ReadError::Version(0x0))
// Ok(())
diff --git a/src/data/renderer.rs b/src/data/renderer.rs
index 5234b60..bd101e5 100644
--- a/src/data/renderer.rs
+++ b/src/data/renderer.rs
@@ -115,8 +115,8 @@ macro_rules! load {
($name:literal, $scale:ident) => { paste::paste! {
ImageHolder::from(std::sync::LazyLock::force(match $scale {
$crate::data::renderer::Scale::Quarter => $crate::data::renderer::quar::[<$name:snake:upper>],
- crate::data::renderer::Scale::Eigth => $crate::data::renderer::eigh::[<$name:snake:upper>],
- crate::data::renderer::Scale::Full => $crate::data::renderer::full::[<$name:snake:upper>],
+ $crate::data::renderer::Scale::Eigth => $crate::data::renderer::eigh::[<$name:snake:upper>],
+ $crate::data::renderer::Scale::Full => $crate::data::renderer::full::[<$name:snake:upper>],
}))
} };
($name: literal) => { paste::paste! {
diff --git a/src/lib.rs b/src/lib.rs
index 77b69b0..ef1c290 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,5 @@
//! crate for dealing with mindustry
-#![feature(lazy_cell, array_chunks)]
+#![feature(lazy_cell, array_chunks, const_trait_impl)]
pub mod block;
mod content;
pub mod data;