mindustry logic execution, map- and schematic- parsing and rendering
remove build_registry()
also apparently my unit deser impl was flawed so uh yeah
bendn 2023-08-17
parent 736c377 · commit 12101f2
-rw-r--r--Cargo.toml5
-rw-r--r--README.md6
-rw-r--r--src/block/campaign.rs7
-rw-r--r--src/block/defense.rs25
-rw-r--r--src/block/distribution.rs54
-rw-r--r--src/block/drills.rs20
-rw-r--r--src/block/environment.rs192
-rw-r--r--src/block/liquid.rs33
-rw-r--r--src/block/logic.rs54
-rw-r--r--src/block/mod.rs518
-rw-r--r--src/block/payload.rs57
-rw-r--r--src/block/power.rs41
-rw-r--r--src/block/production.rs46
-rw-r--r--src/block/simple.rs21
-rw-r--r--src/block/storage.rs16
-rw-r--r--src/block/turrets.rs43
-rw-r--r--src/block/units.rs70
-rw-r--r--src/block/walls.rs40
-rw-r--r--src/data/autotile.rs10
-rw-r--r--src/data/dynamic.rs20
-rw-r--r--src/data/map.rs29
-rw-r--r--src/data/mod.rs13
-rw-r--r--src/data/renderer.rs12
-rw-r--r--src/data/schematic.rs97
-rw-r--r--src/exe/draw.rs8
-rw-r--r--src/exe/map.rs8
-rw-r--r--src/lib.rs12
-rw-r--r--src/registry.rs51
-rw-r--r--src/unit/mod.rs40
29 files changed, 637 insertions, 911 deletions
diff --git a/Cargo.toml b/Cargo.toml
index d40ff8e..f7badbc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "mindus"
-version = "4.0.4"
+version = "4.0.5"
edition = "2021"
description = "A library for working with mindustry data formats (eg schematics and maps) (fork of plandustry)"
authors = [
@@ -24,7 +24,8 @@ thiserror = "1.0"
bobbin-bits = "0.1"
blurslice = { version = "0.1" }
enum_dispatch = "0.3"
-fast_image_resize = "2.7.3"
+fast_image_resize = "2.7"
+phf = { version = "0.11", features = ["macros"] }
[features]
bin = ["image/png"]
diff --git a/README.md b/README.md
index de0e0fc..ee2f330 100644
--- a/README.md
+++ b/README.md
@@ -6,11 +6,9 @@ Mindus is a library for working with [Mindustry](https://github.com/Anuken/Mindu
## Usage
-```rs
+```rust
use mindus::*;
-let reg = build_registry();
-let mut ss = SchematicSerializer(&reg);
-let s = ss.deserialize_base64("bXNjaAF4nD3SQW6DMBBA0bE94wF104vkDr1H1QVtWUQioTL0/oFJ/Fl9GXiy5ZFBhiJ6n26zvE9tv7T1f5/bZbtNyyJvv/P2065/+3W9i0hdpu952SR/fiWp29qOL4/lDzkfExkiEpWPGqMKpZRRlT/8VQkv4aXwnlUopYw6vRTVvRzeGJVYy1ShlDKqezk8O8+DV/AKXgkvRSllvK2sdU/xFE/xFE/xFE/xNLzxeRlU9wzPOK9xXsMzPMOr3EcNL0VlqlBKGVWpfh+O5+zPmRdnXpx5cebFmRd/eQ9KIReL")?;
+let s = Schematic::deserialize_base64("bXNjaAF4nD3SQW6DMBBA0bE94wF104vkDr1H1QVtWUQioTL0/oFJ/Fl9GXiy5ZFBhiJ6n26zvE9tv7T1f5/bZbtNyyJvv/P2065/+3W9i0hdpu952SR/fiWp29qOL4/lDzkfExkiEpWPGqMKpZRRlT/8VQkv4aXwnlUopYw6vRTVvRzeGJVYy1ShlDKqezk8O8+DV/AKXgkvRSllvK2sdU/xFE/xFE/xFE/xNLzxeRlU9wzPOK9xXsMzPMOr3EcNL0VlqlBKGVWpfh+O5+zPmRdnXpx5cebFmRd/eQ9KIReL").unwrap();
let output = s.render();
output.save("output.png");
```
diff --git a/src/block/campaign.rs b/src/block/campaign.rs
deleted file mode 100644
index 1283f3e..0000000
--- a/src/block/campaign.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-//! campaign blocks
-use crate::block::make_register;
-use crate::block::simple::{cost, BasicBlock};
-make_register! {
- "launch-pad" -> BasicBlock::new(3, true, cost!(Copper: 350, Lead: 200, Titanium: 150, Silicon: 140));
- "interplanetary-accelerator" -> BasicBlock::new(7, true, cost!(Copper: 16000, Silicon: 11000, Thorium: 13000, Titanium: 12000, SurgeAlloy: 6000, PhaseFabric: 5000));
-}
diff --git a/src/block/defense.rs b/src/block/defense.rs
index 19d067f..3a1a4d4 100644
--- a/src/block/defense.rs
+++ b/src/block/defense.rs
@@ -1,26 +1,9 @@
//! defense
-use crate::block::simple::{cost, make_simple, BasicBlock};
+use crate::block::simple::*;
use crate::block::*;
-make_simple!(HeatedBlock => |_, _, buff: &mut DataRead| read_heated(buff));
-make_simple!(RadarBlock => |_, _, buff: &mut DataRead| buff.skip(4));
-make_simple!(ShieldBlock => |_, _, buff: &mut DataRead| read_shield(buff));
-make_register! {
- "mender" -> HeatedBlock::new(1, true, cost!(Copper: 25, Lead: 30));
- "mend-projector" -> HeatedBlock::new(2, true, cost!(Copper: 50, Lead: 100, Titanium: 25, Silicon: 40));
- "overdrive-projector" -> HeatedBlock::new(2, true, cost!(Lead: 100, Titanium: 75, Silicon: 75, Plastanium: 30));
- "overdrive-dome" -> HeatedBlock::new(3, true, cost!(Lead: 200, Titanium: 130, Silicon: 130, Plastanium: 80, SurgeAlloy: 120));
- "force-projector" -> BasicBlock::new(3, true, cost!(Lead: 100, Titanium: 75, Silicon: 125));
- "regen-projector" -> BasicBlock::new(3, true, cost!(Silicon: 80, Tungsten: 60, Oxide: 40, Beryllium: 80));
- "shock-mine" -> BasicBlock::new(1, true, cost!(Lead: 25, Silicon: 12));
- "radar" -> RadarBlock::new(1, true, cost!(Silicon: 60, Graphite: 50, Beryllium: 10));
- "build-tower" -> BasicBlock::new(3, true, cost!(Silicon: 150, Oxide: 40, Thorium: 60));
- "shockwave-tower" -> BasicBlock::new(3, true, cost!(SurgeAlloy: 50, Silicon: 150, Oxide: 30, Tungsten: 100));
- // barrier projector
- // editor only
- "barrier-projector" -> BasicBlock::new(3, true, &[]);
- "shield-projector" -> ShieldBlock::new(3, true, &[]);
- "large-shield-projector" -> ShieldBlock::new(4, true, &[]);
-}
+make_simple!(HeatedBlock => |_, buff: &mut DataRead| read_heated(buff));
+make_simple!(RadarBlock => |_, buff: &mut DataRead| buff.skip(4));
+make_simple!(ShieldBlock => |_, buff: &mut DataRead| read_shield(buff));
/// format:
/// - heat: [`f32`]
diff --git a/src/block/distribution.rs b/src/block/distribution.rs
index 6b83d90..489d230 100644
--- a/src/block/distribution.rs
+++ b/src/block/distribution.rs
@@ -9,7 +9,7 @@ use crate::item;
make_simple!(
ConveyorBlock,
|_, name, _, ctx: Option<&RenderingContext>, rot, s| tile(ctx.unwrap(), name, rot, s),
- |_, _, buff: &mut DataRead| {
+ |_, buff: &mut DataRead| {
// format:
// - amount: `i32`
// - iterate amount:
@@ -28,14 +28,14 @@ make_simple!(
make_simple!(
DuctBlock,
|_, name, _, ctx: Option<&RenderingContext>, rot, s| tile(ctx.unwrap(), name, rot, s),
- |_, _, buff: &mut DataRead| {
+ |_, buff: &mut DataRead| {
// format:
// - rec_dir: `i8`
buff.skip(1)
}
);
-make_simple!(JunctionBlock => |_, _, buff| { read_directional_item_buffer(buff) });
+make_simple!(JunctionBlock => |_, buff| { read_directional_item_buffer(buff) });
make_simple!(SimpleDuctBlock, |_, name, _, _, rot: Rotation, s| {
let mut base = load!("duct-base", s);
let mut top = load!(from name which is ["overflow-duct" "underflow-duct"], s);
@@ -118,7 +118,7 @@ make_simple!(
// format:
// - link: `i32`
// - cooldown: `f32`
- |_, _, buff: &mut DataRead| buff.skip(8)
+ |_, buff: &mut DataRead| buff.skip(8)
);
make_simple!(
SurgeRouter,
@@ -127,42 +127,10 @@ make_simple!(
unsafe { base.overlay(load!("top", s).rotate(r.rotated(false).count())) };
base
},
- |_, _, buff: &mut DataRead| buff.skip(2)
+ |_, buff: &mut DataRead| buff.skip(2)
);
// format: id: [`i32`]
-make_simple!(UnitCargoLoader => |_, _, buff: &mut DataRead| buff.skip(4));
-
-make_register! {
- "conveyor" => ConveyorBlock::new(1, false, cost!(Copper: 1));
- "titanium-conveyor" => ConveyorBlock::new(1, false, cost!(Copper: 1, Lead: 1, Titanium: 1));
- "plastanium-conveyor" => StackConveyor::new(1, false, cost!(Graphite: 1, Silicon: 1, Plastanium: 1));
- "armored-conveyor" => ConveyorBlock::new(1, false, cost!(Metaglass: 1, Thorium: 1, Plastanium: 1));
- "junction" -> JunctionBlock::new(1, true, cost!(Copper: 2));
- "bridge-conveyor" -> BridgeBlock::new(1, false, cost!(Copper: 6, Lead: 6), 4, true);
- "phase-conveyor" -> BridgeBlock::new(1, false, cost!(Lead: 10, Graphite: 10, Silicon: 7, PhaseFabric: 5), 12, true);
- "sorter" => ItemBlock::new(1, true, cost!(Copper: 2, Lead: 2));
- "inverted-sorter" => ItemBlock::new(1, true, cost!(Copper: 2, Lead: 2));
- "unloader" -> ItemBlock::new(1, true, cost!(Titanium: 25, Silicon: 30));
- "router" -> BasicBlock::new(1, true, cost!(Copper: 3));
- "distributor" -> BasicBlock::new(2, true, cost!(Copper: 4, Lead: 4));
- "overflow-gate" -> BasicBlock::new(1, true, cost!(Copper: 4, Lead: 2));
- "underflow-gate" -> BasicBlock::new(1, true, cost!(Copper: 4, Lead: 2));
- "mass-driver" => BridgeBlock::new(3, true, cost!(Lead: 125, Titanium: 125, Thorium: 50, Silicon: 75), 55, false);
- "duct" => DuctBlock::new(1, false, cost!(Beryllium: 1));
- "armored-duct" => DuctBlock::new(1, false, cost!(Beryllium: 2, Tungsten: 1));
- "duct-router" => ItemBlock::new(1, true, cost!(Beryllium: 10));
- "overflow-duct" => SimpleDuctBlock::new(1, true, cost!(Graphite: 8, Beryllium: 8));
- "underflow-duct" => SimpleDuctBlock::new(1, true, cost!(Graphite: 8, Beryllium: 8));
- "duct-bridge" => BridgeBlock::new(1, true, cost!(Beryllium: 20), 3, true);
- "duct-unloader" => ItemBlock::new(1, true, cost!(Graphite: 20, Silicon: 20, Tungsten: 10));
- "surge-conveyor" => StackConveyor::new(1, false, cost!(SurgeAlloy: 1, Tungsten: 1));
- "surge-router" => SurgeRouter::new(1, false, cost!(SurgeAlloy: 5, Tungsten: 1)); // not symmetric
- "unit-cargo-loader" -> BasicBlock::new(3, true, cost!(Silicon: 80, SurgeAlloy: 50, Oxide: 20));
- "unit-cargo-unload-point" => ItemBlock::new(2, true, cost!(Silicon: 60, Tungsten: 60));
- // sandbox only
- "item-source" -> ItemBlock::new(1, true, &[]);
- "item-void" -> BasicBlock::new(1, true, &[]);
-}
+make_simple!(UnitCargoLoader => |_, buff: &mut DataRead| buff.skip(4));
pub struct ItemBlock {
size: u8,
@@ -262,12 +230,7 @@ impl BlockLogic for ItemBlock {
/// (unit-cargo-unload-point)
/// - item: `u16` as item
/// - stale: `bool`
- fn read(
- &self,
- b: &mut Build,
- _: &BlockRegistry,
- buff: &mut DataRead,
- ) -> Result<(), DataReadError> {
+ fn read(&self, b: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
match b.block.name() {
"duct-unloader" => {
let n = buff.read_i16()?;
@@ -439,7 +402,6 @@ impl BlockLogic for BridgeBlock {
fn read(
&self,
t: &mut Build,
- r: &super::BlockRegistry,
buff: &mut crate::data::DataRead,
) -> Result<(), crate::data::ReadError> {
match t.block.name() {
@@ -447,7 +409,7 @@ impl BlockLogic for BridgeBlock {
"phase-conveyor" | "phase-conduit" | "bridge-conduit" => read_item_bridge(buff)?,
"mass-driver" => buff.skip(9)?,
"payload-mass-driver" | "large-payload-mass-driver" => {
- crate::block::payload::read_payload_block(r, buff)?;
+ crate::block::payload::read_payload_block(buff)?;
buff.skip(19)?;
}
// no state?
diff --git a/src/block/drills.rs b/src/block/drills.rs
index 3674e47..6952157 100644
--- a/src/block/drills.rs
+++ b/src/block/drills.rs
@@ -1,6 +1,5 @@
//! extraction of raw resources (mine part)
-use super::production::ProductionBlock;
-use crate::block::simple::{cost, make_simple, BasicBlock};
+use crate::block::simple::make_simple;
use crate::block::*;
make_simple!(
@@ -13,7 +12,7 @@ make_simple!(
};
base
},
- |_, _, buff: &mut DataRead| read_drill(buff)
+ |_, buff: &mut DataRead| read_drill(buff)
);
make_simple!(WallDrillBlock, |_, _, _, _, rot: Rotation, scl| {
let mut base = load!("cliff-crusher", scl);
@@ -21,21 +20,6 @@ make_simple!(WallDrillBlock, |_, _, _, _, rot: Rotation, scl| {
base
});
-make_register! {
- "mechanical-drill" -> DrillBlock::new(2, true, cost!(Copper: 12));
- "pneumatic-drill" -> DrillBlock::new(2, true, cost!(Copper: 18, Graphite: 10));
- "laser-drill" -> DrillBlock::new(3, true, cost!(Copper: 35, Graphite: 30, Titanium: 20, Silicon: 30));
- "blast-drill" -> DrillBlock::new(4, true, cost!(Copper: 65, Titanium: 50, Thorium: 75, Silicon: 60));
- "water-extractor" -> BasicBlock::new(2, true, cost!(Copper: 30, Lead: 30, Metaglass: 30, Graphite: 30));
- "oil-extractor" -> BasicBlock::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" -> 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));
- "eruption-drill" -> DrillBlock::new(5, true, cost!(Silicon: 200, Oxide: 20, Tungsten: 200, Thorium: 120));
-}
-
/// format:
/// - progress: [`f32`]
/// - warmup: [`f32`]
diff --git a/src/block/environment.rs b/src/block/environment.rs
deleted file mode 100644
index 3fff74f..0000000
--- a/src/block/environment.rs
+++ /dev/null
@@ -1,192 +0,0 @@
-//! grass
-use crate::block::make_register;
-use crate::block::simple::BasicBlock;
-
-macro_rules! register_env {
- ($($field:literal: $size:literal;)+) => {
- make_register!(
- $($field -> BasicBlock::new($size, true, &[]);)*
- );
- };
-}
-
-register_env! {
- "darksand": 1;
- "sand-floor": 1;
- "yellow-stone": 1;
- "arkyic-stone": 1;
- "carbon-stone": 1;
- "ore-beryllium": 1;
- "ore-copper": 1;
- "ore-lead": 1;
- "ore-coal": 1;
- "ore-scrap": 1;
- "ore-thorium": 1;
- "ore-titanium": 1;
- "ore-tungsten": 1;
- "ore-crystal-thorium": 1;
- "ore-wall-beryllium": 1;
- "ore-wall-thorium": 1;
- "ore-wall-tungsten": 1;
- "graphitic-wall": 1;
- "graphitic-wall-large": 2;
- "dacite": 1;
- "dirt": 1;
- "arkycite-floor": 1;
- "basalt": 1;
- "ice": 1;
- "molten-slag": 1;
- "moss": 1;
- "mud": 1;
- "magmarock": 1;
- "grass": 1;
- "ice-snow": 1;
- "hotrock": 1;
- "char": 1;
- "snow": 1;
- "salt": 1;
- "shale": 1;
- "metal-floor": 1;
- "metal-floor-2": 1;
- "metal-floor-3": 1;
- "metal-floor-4": 1;
- "metal-floor-5": 1;
- "dark-panel-1": 1;
- "dark-panel-2": 1;
- "dark-panel-3": 1;
- "dark-panel-4": 1;
- "dark-panel-5": 1;
- "dark-panel-6": 1;
- "darksand-tainted-water": 1;
- "darksand-water": 1;
- "deep-tainted-water": 1;
- "deep-water": 1;
- "sand-water": 1;
- "shallow-water": 1;
- "space": 1;
- "stone": 1;
- "build1": 1;
- "boulder": 1;
- "arkyic-vent": 1;
- "arkyic-wall-large": 2;
- "arkyic-wall": 1;
- "beryllic-stone-wall-large": 2;
- "beryllic-stone-wall": 1;
- "beryllic-stone": 1;
- "bluemat": 1;
- "carbon-vent": 1;
- "carbon-wall-large": 2;
- "carbon-wall": 1;
- "cliff": 1;
- "core-zone": 1;
- "crater-stone": 1;
- "crystal-floor": 1;
- "crystalline-stone-wall-large": 2;
- "crystalline-stone-wall": 1;
- "crystalline-stone": 1;
- "crystalline-vent": 3;
- "dacite-wall-large": 2;
- "dacite-wall": 1;
- "dark-metal-large": 2;
- "dark-metal": 1;
- "metal-floor-damaged": 1;
- "dense-red-stone": 1;
- "dirt-wall-large": 2;
- "dirt-wall": 1;
- "dune-wall-large": 2;
- "dune-wall": 1;
- "ferric-craters": 1; // ferris section
- "ferric-stone-wall-large": 2;
- "ferric-stone-wall": 1;
- "ferric-stone": 1;
- "ice-wall-large": 2;
- "ice-wall": 1;
- "pebbles": 1;
- "pine": 1;
- "pooled-cryofluid": 1;
- "red-diamond-wall": 1;
- "red-ice-wall-large": 2;
- "red-ice-wall": 1;
- "red-ice": 1;
- "red-stone-vent": 1;
- "red-stone-wall-large": 2;
- "red-stone-wall": 1;
- "red-stone": 1;
- "redmat": 1;
- "regolith-wall-large": 2;
- "regolith-wall": 1;
- "regolith": 1;
- "rhyolite-crater": 1;
- "rhyolite-vent": 1;
- "rhyolite-wall-large": 2;
- "rhyolite-wall": 1;
- "rhyolite": 1;
- "rough-rhyolite": 1;
- "salt-wall-large": 2;
- "salt-wall": 1;
- "sand-wall-large": 2;
- "sand-wall": 1;
- "shale-wall-large": 2;
- "shale-wall": 1;
- "shrubs-large": 2;
- "shrubs": 1;
- "snow-pine": 1;
- "snow-wall-large": 2;
- "snow-wall": 1;
- "spawn": 1;
- "spore-moss": 1;
- "spore-pine": 1;
- "spore-wall-large": 2;
- "spore-wall": 1;
- "stone-wall-large": 2;
- "stone-wall": 1;
- "tainted-water": 1;
- "tar": 1;
- "yellow-stone-plates": 1;
- "yellow-stone-vent": 1;
- "yellow-stone-wall-large": 2;
- "yellow-stone-wall": 1;
- // props
- "yellow-stone-boulder": 1;
- "snow-boulder": 1;
- "shale-boulder": 1;
- "arkyic-boulder": 1;
- "basalt-boulder": 1;
- "beryllic-boulder": 1;
- "carbon-boulder": 1;
- "crystalline-boulder": 1;
- "dacite-boulder": 1;
- "ferric-boulder": 1;
- "red-ice-boulder": 1;
- "red-stone-boulder": 1;
- "rhyolite-boulder": 1;
- "sand-boulder": 1;
- "pur-bush": 1;
- "tendrils": 1;
- // these are tall but uh (TODO layering)
- "white-tree-dead": 1;
- "yellowcoral": 1;
- "white-tree": 1;
- "redweed": 1;
- "spore-cluster": 1;
- "crystal-blocks": 1;
- "crystal-cluster": 1;
- "vibrant-crystal-cluster": 1;
- "crystal-orbs": 1;
- // end tall
- "build2": 1;
- "build3": 1;
- "build4": 1;
- "build5": 1;
- "build6": 1;
- "build7": 1;
- "build8": 1;
- "build9": 1;
- "build10": 1;
- "build11": 1;
- "build12": 1;
- "build13": 1;
- "build14": 1;
- "build15": 1;
- "build16": 1;
-}
diff --git a/src/block/liquid.rs b/src/block/liquid.rs
index ec6978e..59f1946 100644
--- a/src/block/liquid.rs
+++ b/src/block/liquid.rs
@@ -1,7 +1,6 @@
//! liquid related things
use thiserror::Error;
-use crate::block::distribution::BridgeBlock;
use crate::block::simple::*;
use crate::block::*;
use crate::content;
@@ -23,31 +22,6 @@ make_simple!(ConduitBlock, |_,
mask2tile(mask, rot, name, s)
});
-make_register! {
- "reinforced-pump" -> BasicBlock::new(2, true, cost!(Beryllium: 40, Tungsten: 30, Silicon: 20));
- "mechanical-pump" -> BasicBlock::new(1, true, cost!(Copper: 15, Metaglass: 10));
- "rotary-pump" -> BasicBlock::new(2, true, cost!(Copper: 70, Metaglass: 50, Titanium: 35, Silicon: 20));
- "impulse-pump" -> BasicBlock::new(3, true, cost!(Copper: 80, Metaglass: 90, Titanium: 40, Thorium: 35, Silicon: 30));
- "conduit" => ConduitBlock::new(1, false, cost!(Metaglass: 1));
- "pulse-conduit" => ConduitBlock::new(1, false, cost!(Metaglass: 1, Titanium: 2));
- "plated-conduit" => ConduitBlock::new(1, false, cost!(Metaglass: 1, Thorium: 2, Plastanium: 1));
- "liquid-router" -> BasicBlock::new(1, true, cost!(Metaglass: 2, Graphite: 4));
- "liquid-container" -> BasicBlock::new(2, true, cost!(Metaglass: 15, Titanium: 10));
- "liquid-tank" -> BasicBlock::new(3, true, cost!(Metaglass: 40, Titanium: 30));
- "liquid-junction" -> BasicBlock::new(1, true, cost!(Metaglass: 8, Graphite: 4));
- "bridge-conduit" -> BridgeBlock::new(1, true, cost!(Metaglass: 8, Graphite: 4), 4, true);
- "phase-conduit" -> BridgeBlock::new(1, true, cost!(Metaglass: 20, Titanium: 10, Silicon: 7, PhaseFabric: 5), 12, true);
- "reinforced-conduit" => ConduitBlock::new(1, false, cost!(Beryllium: 2));
- "reinforced-liquid-junction" -> BasicBlock::new(1, true, cost!(Graphite: 4, Beryllium: 8));
- "reinforced-bridge-conduit" => BridgeBlock::new(1, true, cost!(Graphite: 8, Beryllium: 20), 4, true);
- "reinforced-liquid-router" -> BasicBlock::new(1, true, cost!(Graphite: 8, Beryllium: 4));
- "reinforced-liquid-container" -> BasicBlock::new(2, true, cost!(Tungsten: 10, Beryllium: 16));
- "reinforced-liquid-tank" -> BasicBlock::new(3, true, cost!(Tungsten: 40, Beryllium: 50));
- // sandbox only
- "liquid-source" => FluidBlock::new(1, true, &[]);
- "liquid-void" -> BasicBlock::new(1, true, &[]);
-}
-
pub struct FluidBlock {
size: u8,
symmetric: bool,
@@ -123,12 +97,7 @@ impl BlockLogic for FluidBlock {
/// format:
/// - fluid: [`u16`] as [`Fluid`](fluid::Type)
- fn read(
- &self,
- b: &mut Build,
- _: &BlockRegistry,
- buff: &mut DataRead,
- ) -> Result<(), DataReadError> {
+ fn read(&self, b: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
let f = buff.read_u16()?;
b.state = Some(Self::create_state(fluid::Type::try_from(f).ok()));
Ok(())
diff --git a/src/block/logic.rs b/src/block/logic.rs
index 153f637..9bbe24e 100644
--- a/src/block/logic.rs
+++ b/src/block/logic.rs
@@ -3,14 +3,14 @@ use std::borrow::Cow;
use std::string::FromUtf8Error;
use crate::block::simple::*;
-use crate::data::dynamic::{DynSerializer, DynType};
-use crate::{block::*, Serializer};
+use crate::data::dynamic::DynType;
+use crate::{block::*, Serializable};
use crate::data::{self, CompressError, DataRead, DataWrite};
make_simple!(
MemoryBlock =>
- |_, _, buff: &mut DataRead| {
+ |_, buff: &mut DataRead| {
// format:
// - iterate [`u32`]
// - memory: [`f64`]
@@ -19,24 +19,6 @@ make_simple!(
}
);
-make_register! {
- "reinforced-message" -> MessageLogic::new(1, true, cost!(Graphite: 10, Beryllium: 5));
- "message" -> MessageLogic::new(1, true, cost!(Copper: 5, Graphite: 5));
- "switch" => SwitchLogic::new(1, true, cost!(Copper: 5, Graphite: 5));
- "micro-processor" -> ProcessorLogic::new(1, true, cost!(Copper: 90, Lead: 50, Silicon: 50));
- "logic-processor" -> ProcessorLogic::new(2, true, cost!(Lead: 320, Graphite: 60, Thorium: 50, Silicon: 80));
- "hyper-processor" -> ProcessorLogic::new(3, true, cost!(Lead: 450, Thorium: 75, Silicon: 150, SurgeAlloy: 50));
- "memory-cell" -> MemoryBlock::new(1, true, cost!(Copper: 30, Graphite: 30, Silicon: 30));
- "memory-bank" -> MemoryBlock::new(2, true, cost!(Copper: 30, Graphite: 80, Silicon: 80, PhaseFabric: 30));
- "logic-display" -> BasicBlock::new(3, true, cost!(Lead: 100, Metaglass: 50, Silicon: 50));
- "large-logic-display" -> BasicBlock::new(6, true, cost!(Lead: 200, Metaglass: 100, Silicon: 150, PhaseFabric: 75));
- "canvas" => CanvasBlock::new(2, true, cost!(Silicon: 30, Beryllium: 10), 12);
- // editor only
- "world-processor" -> BasicBlock::new(1, true, &[]);
- "world-message" -> MessageLogic::new(1, true, &[]);
- "world-cell" -> MemoryBlock::new(1, true, &[]);
-}
-
pub struct CanvasBlock {
size: u8,
symmetric: bool,
@@ -177,12 +159,7 @@ impl BlockLogic for CanvasBlock {
/// format:
/// - len: [`i32`]
/// - read(len) -> [`deser_canvas_image`]
- fn read(
- &self,
- build: &mut Build,
- _: &BlockRegistry,
- buff: &mut DataRead,
- ) -> Result<(), DataReadError> {
+ fn read(&self, build: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
let n = buff.read_i32()? as usize;
let mut b = vec![0; n];
buff.read_bytes(&mut b)?;
@@ -251,12 +228,7 @@ impl BlockLogic for MessageLogic {
Ok(DynData::String(Some(Self::get_state(state).clone())))
}
- fn read(
- &self,
- b: &mut Build,
- _: &BlockRegistry,
- buff: &mut DataRead,
- ) -> Result<(), DataReadError> {
+ fn read(&self, b: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
b.state = Some(Self::create_state(buff.read_utf()?.to_string()));
Ok(())
}
@@ -304,12 +276,7 @@ impl BlockLogic for SwitchLogic {
Ok(DynData::Boolean(*Self::get_state(state)))
}
- fn read(
- &self,
- build: &mut Build,
- _: &BlockRegistry,
- buff: &mut DataRead,
- ) -> Result<(), DataReadError> {
+ fn read(&self, build: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
build.state = Some(Self::create_state(buff.read_bool()?));
Ok(())
}
@@ -409,12 +376,7 @@ impl BlockLogic for ProcessorLogic {
}
}
- fn read(
- &self,
- b: &mut Build,
- _: &BlockRegistry,
- buff: &mut DataRead,
- ) -> Result<(), DataReadError> {
+ fn read(&self, b: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
let n = buff.read_u32()? as usize;
let mut v = vec![0; n];
buff.read_bytes(&mut v)?;
@@ -424,7 +386,7 @@ impl BlockLogic for ProcessorLogic {
));
for _ in 0..buff.read_u32()? {
let _ = buff.read_utf()?;
- let _ = DynSerializer.deserialize(buff).unwrap();
+ let _ = DynData::deserialize(buff).unwrap();
}
let memory = buff.read_u32()? as usize;
buff.skip(memory * 8)?;
diff --git a/src/block/mod.rs b/src/block/mod.rs
index daf9ad1..1652338 100644
--- a/src/block/mod.rs
+++ b/src/block/mod.rs
@@ -1,8 +1,6 @@
//! deal with blocks.
//!
-//! categorized as mindustry categorizes them in its assets folder, for easy drawing.
-//!
-//! with the exception of sandbox, that is.
+//! different block types are organized into modules
use bobbin_bits::U4::{self, B0000, B0001, B0010, B0100, B1000};
use std::error::Error;
use std::fmt;
@@ -12,13 +10,12 @@ use crate::data::map::Build;
use crate::data::{self, renderer::*, CompressError};
use crate::data::{DataRead, GridPos, ReadError as DataReadError};
use crate::item::storage::ItemStorage;
-use crate::registry::RegistryEntry;
macro_rules! mods {
($($mod:ident)*) => {
$(pub mod $mod;)*
- pub mod all {
+ mod all {
$(pub use crate::block::$mod::*;)*
pub use super::simple::BasicBlock;
}
@@ -26,10 +23,11 @@ macro_rules! mods {
}
mods! {
- campaign content defense distribution drills environment liquid logic payload power production storage turrets walls units
+ content defense distribution drills liquid logic payload power production turrets walls units
}
mod simple;
+use simple::*;
macro_rules! disp {
($($k:ident,)+) => {
@@ -210,12 +208,7 @@ pub trait BlockLogic {
}
#[allow(unused_variables)]
- fn read(
- &self,
- build: &mut Build,
- reg: &BlockRegistry,
- buff: &mut DataRead,
- ) -> Result<(), DataReadError> {
+ fn read(&self, build: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
Ok(())
}
}
@@ -324,7 +317,7 @@ impl Block {
/// this blocks name
/// ```
- /// assert!(mindus::block::distribution::DISTRIBUTOR.name() == "distributor")
+ /// assert!(mindus::block::DISTRIBUTOR.name() == "distributor")
/// ```
#[must_use]
#[inline]
@@ -408,13 +401,8 @@ impl Block {
}
#[inline]
- pub(crate) fn read(
- &self,
- build: &mut Build,
- reg: &BlockRegistry,
- buff: &mut DataRead,
- ) -> Result<(), DataReadError> {
- self.logic.read(build, reg, buff)
+ pub(crate) fn read(&self, build: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
+ self.logic.read(build, buff)
}
}
@@ -424,12 +412,6 @@ impl fmt::Debug for Block {
}
}
-impl RegistryEntry for Block {
- fn get_name(&self) -> &str {
- self.name
- }
-}
-
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
/// the possible rotation states of a object
#[repr(u8)]
@@ -588,54 +570,464 @@ impl From<Rotation> for u8 {
}
}
-pub type BlockRegistry<'l> = crate::registry::Registry<'l, Block>;
-pub type RegisterError<'l> = crate::registry::RegisterError<'l, Block>;
-
macro_rules! make_register {
($($field:literal $op:tt $logic:expr;)+) => { paste::paste! {
$(
- $crate::block::make_register!(impl $field $op $logic);
+ make_register!(impl $field $op $logic);
)+
-
- pub(crate) fn register(reg: &mut $crate::block::BlockRegistry<'_>) {
- // get the static we make
- $(assert!(reg.register(&[<$field:snake:upper>]).is_ok());)+
- }
+ pub static BLOCK_REGISTRY: phf::Map<&str, &Block> = phf::phf_map! {$(
+ $field => &[<$field:snake:upper>],
+ )+};
}};
(impl $field: literal => $logic: expr) => {
- paste::paste! { pub static [<$field:snake:upper>]: $crate::block::Block = $crate::block::Block::new(
+ paste::paste! { pub static [<$field:snake:upper>]: Block = Block::new(
$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(
+ paste::paste! { pub static [<$field:snake:upper>]: Block = Block::new(
$field, <crate::block::BlockLogicEnum as crate::block::ConstFrom<_>>::fro($logic), Some(crate::data::renderer::load!($field))
); }
- }
-}
-pub(crate) use make_register;
-
-#[must_use]
-/// create a block registry
-pub fn build_registry() -> BlockRegistry<'static> {
- let mut reg = BlockRegistry::default();
- register(&mut reg);
- reg
+ };
+ (impl $field: literal : $size: literal) => {
+ paste::paste! { pub static [<$field:snake:upper>]: Block = Block::new(
+ $field, BlockLogicEnum::BasicBlock(BasicBlock::new($size, true, &[])), Some(crate::data::renderer::load!($field))
+ ); }
+ };
}
-
-fn register(reg: &mut BlockRegistry<'_>) {
- turrets::register(reg);
- drills::register(reg);
- distribution::register(reg);
- storage::register(reg);
- liquid::register(reg);
- power::register(reg);
- defense::register(reg);
- production::register(reg);
- payload::register(reg);
- campaign::register(reg);
- logic::register(reg);
- walls::register(reg);
- environment::register(reg);
- units::register(reg);
+// pub(self) use make_register;
+make_register! {
+ "darksand": 1;
+ "sand-floor": 1;
+ "yellow-stone": 1;
+ "arkyic-stone": 1;
+ "carbon-stone": 1;
+ "ore-beryllium": 1;
+ "ore-copper": 1;
+ "ore-lead": 1;
+ "ore-coal": 1;
+ "ore-scrap": 1;
+ "ore-thorium": 1;
+ "ore-titanium": 1;
+ "ore-tungsten": 1;
+ "ore-crystal-thorium": 1;
+ "ore-wall-beryllium": 1;
+ "ore-wall-thorium": 1;
+ "ore-wall-tungsten": 1;
+ "graphitic-wall": 1;
+ "graphitic-wall-large": 2;
+ "dacite": 1;
+ "dirt": 1;
+ "arkycite-floor": 1;
+ "basalt": 1;
+ "ice": 1;
+ "molten-slag": 1;
+ "moss": 1;
+ "mud": 1;
+ "magmarock": 1;
+ "grass": 1;
+ "ice-snow": 1;
+ "hotrock": 1;
+ "char": 1;
+ "snow": 1;
+ "salt": 1;
+ "shale": 1;
+ "metal-floor": 1;
+ "metal-floor-2": 1;
+ "metal-floor-3": 1;
+ "metal-floor-4": 1;
+ "metal-floor-5": 1;
+ "dark-panel-1": 1;
+ "dark-panel-2": 1;
+ "dark-panel-3": 1;
+ "dark-panel-4": 1;
+ "dark-panel-5": 1;
+ "dark-panel-6": 1;
+ "darksand-tainted-water": 1;
+ "darksand-water": 1;
+ "deep-tainted-water": 1;
+ "deep-water": 1;
+ "sand-water": 1;
+ "shallow-water": 1;
+ "space": 1;
+ "stone": 1;
+ "build1": 1;
+ "boulder": 1;
+ "arkyic-vent": 1;
+ "arkyic-wall-large": 2;
+ "arkyic-wall": 1;
+ "beryllic-stone-wall-large": 2;
+ "beryllic-stone-wall": 1;
+ "beryllic-stone": 1;
+ "bluemat": 1;
+ "carbon-vent": 1;
+ "carbon-wall-large": 2;
+ "carbon-wall": 1;
+ "cliff": 1;
+ "core-zone": 1;
+ "crater-stone": 1;
+ "crystal-floor": 1;
+ "crystalline-stone-wall-large": 2;
+ "crystalline-stone-wall": 1;
+ "crystalline-stone": 1;
+ "crystalline-vent": 3;
+ "dacite-wall-large": 2;
+ "dacite-wall": 1;
+ "dark-metal-large": 2;
+ "dark-metal": 1;
+ "metal-floor-damaged": 1;
+ "dense-red-stone": 1;
+ "dirt-wall-large": 2;
+ "dirt-wall": 1;
+ "dune-wall-large": 2;
+ "dune-wall": 1;
+ "ferric-craters": 1; // ferris section
+ "ferric-stone-wall-large": 2;
+ "ferric-stone-wall": 1;
+ "ferric-stone": 1;
+ "ice-wall-large": 2;
+ "ice-wall": 1;
+ "pebbles": 1;
+ "pine": 1;
+ "pooled-cryofluid": 1;
+ "red-diamond-wall": 1;
+ "red-ice-wall-large": 2;
+ "red-ice-wall": 1;
+ "red-ice": 1;
+ "red-stone-vent": 1;
+ "red-stone-wall-large": 2;
+ "red-stone-wall": 1;
+ "red-stone": 1;
+ "redmat": 1;
+ "regolith-wall-large": 2;
+ "regolith-wall": 1;
+ "regolith": 1;
+ "rhyolite-crater": 1;
+ "rhyolite-vent": 1;
+ "rhyolite-wall-large": 2;
+ "rhyolite-wall": 1;
+ "rhyolite": 1;
+ "rough-rhyolite": 1;
+ "salt-wall-large": 2;
+ "salt-wall": 1;
+ "sand-wall-large": 2;
+ "sand-wall": 1;
+ "shale-wall-large": 2;
+ "shale-wall": 1;
+ "shrubs-large": 2;
+ "shrubs": 1;
+ "snow-pine": 1;
+ "snow-wall-large": 2;
+ "snow-wall": 1;
+ "spawn": 1;
+ "spore-moss": 1;
+ "spore-pine": 1;
+ "spore-wall-large": 2;
+ "spore-wall": 1;
+ "stone-wall-large": 2;
+ "stone-wall": 1;
+ "tainted-water": 1;
+ "tar": 1;
+ "yellow-stone-plates": 1;
+ "yellow-stone-vent": 1;
+ "yellow-stone-wall-large": 2;
+ "yellow-stone-wall": 1;
+ // props
+ "yellow-stone-boulder": 1;
+ "snow-boulder": 1;
+ "shale-boulder": 1;
+ "arkyic-boulder": 1;
+ "basalt-boulder": 1;
+ "beryllic-boulder": 1;
+ "carbon-boulder": 1;
+ "crystalline-boulder": 1;
+ "dacite-boulder": 1;
+ "ferric-boulder": 1;
+ "red-ice-boulder": 1;
+ "red-stone-boulder": 1;
+ "rhyolite-boulder": 1;
+ "sand-boulder": 1;
+ "pur-bush": 1;
+ "tendrils": 1;
+ // these are tall but uh (TODO layering)
+ "white-tree-dead": 1;
+ "yellowcoral": 1;
+ "white-tree": 1;
+ "redweed": 1;
+ "spore-cluster": 1;
+ "crystal-blocks": 1;
+ "crystal-cluster": 1;
+ "vibrant-crystal-cluster": 1;
+ "crystal-orbs": 1;
+ // end tall
+ "build2": 1;
+ "build3": 1;
+ "build4": 1;
+ "build5": 1;
+ "build6": 1;
+ "build7": 1;
+ "build8": 1;
+ "build9": 1;
+ "build10": 1;
+ "build11": 1;
+ "build12": 1;
+ "build13": 1;
+ "build14": 1;
+ "build15": 1;
+ "build16": 1;
+ "conveyor" => ConveyorBlock::new(1, false, cost!(Copper: 1));
+ "titanium-conveyor" => ConveyorBlock::new(1, false, cost!(Copper: 1, Lead: 1, Titanium: 1));
+ "plastanium-conveyor" => StackConveyor::new(1, false, cost!(Graphite: 1, Silicon: 1, Plastanium: 1));
+ "armored-conveyor" => ConveyorBlock::new(1, false, cost!(Metaglass: 1, Thorium: 1, Plastanium: 1));
+ "junction" -> JunctionBlock::new(1, true, cost!(Copper: 2));
+ "bridge-conveyor" -> BridgeBlock::new(1, false, cost!(Copper: 6, Lead: 6), 4, true);
+ "phase-conveyor" -> BridgeBlock::new(1, false, cost!(Lead: 10, Graphite: 10, Silicon: 7, PhaseFabric: 5), 12, true);
+ "sorter" => ItemBlock::new(1, true, cost!(Copper: 2, Lead: 2));
+ "inverted-sorter" => ItemBlock::new(1, true, cost!(Copper: 2, Lead: 2));
+ "unloader" -> ItemBlock::new(1, true, cost!(Titanium: 25, Silicon: 30));
+ "router" -> BasicBlock::new(1, true, cost!(Copper: 3));
+ "distributor" -> BasicBlock::new(2, true, cost!(Copper: 4, Lead: 4));
+ "overflow-gate" -> BasicBlock::new(1, true, cost!(Copper: 4, Lead: 2));
+ "underflow-gate" -> BasicBlock::new(1, true, cost!(Copper: 4, Lead: 2));
+ "mass-driver" => BridgeBlock::new(3, true, cost!(Lead: 125, Titanium: 125, Thorium: 50, Silicon: 75), 55, false);
+ "duct" => DuctBlock::new(1, false, cost!(Beryllium: 1));
+ "armored-duct" => DuctBlock::new(1, false, cost!(Beryllium: 2, Tungsten: 1));
+ "duct-router" => ItemBlock::new(1, true, cost!(Beryllium: 10));
+ "overflow-duct" => SimpleDuctBlock::new(1, true, cost!(Graphite: 8, Beryllium: 8));
+ "underflow-duct" => SimpleDuctBlock::new(1, true, cost!(Graphite: 8, Beryllium: 8));
+ "duct-bridge" => BridgeBlock::new(1, true, cost!(Beryllium: 20), 3, true);
+ "duct-unloader" => ItemBlock::new(1, true, cost!(Graphite: 20, Silicon: 20, Tungsten: 10));
+ "surge-conveyor" => StackConveyor::new(1, false, cost!(SurgeAlloy: 1, Tungsten: 1));
+ "surge-router" => SurgeRouter::new(1, false, cost!(SurgeAlloy: 5, Tungsten: 1)); // not symmetric
+ "unit-cargo-loader" -> BasicBlock::new(3, true, cost!(Silicon: 80, SurgeAlloy: 50, Oxide: 20));
+ "unit-cargo-unload-point" => ItemBlock::new(2, true, cost!(Silicon: 60, Tungsten: 60));
+ "cultivator" -> ProductionBlock::new(2, true, cost!(Copper: 25, Lead: 25, Silicon: 10));
+ "graphite-press" -> ProductionBlock::new(2, true, cost!(Copper: 75, Lead: 30));
+ "multi-press" -> ProductionBlock::new(3, true, cost!(Lead: 100, Graphite: 50, Titanium: 100, Silicon: 25));
+ "silicon-smelter" -> ProductionBlock::new(2, true, cost!(Copper: 30, Lead: 25));
+ "silicon-crucible" -> ProductionBlock::new(3, true, cost!(Metaglass: 80, Titanium: 120, Silicon: 60, Plastanium: 35));
+ "kiln" -> ProductionBlock::new(2, true, cost!(Copper: 60, Lead: 30, Graphite: 30));
+ "plastanium-compressor" -> ProductionBlock::new(2, true, cost!(Lead: 115, Graphite: 60, Titanium: 80, Silicon: 80));
+ "phase-weaver" -> ProductionBlock::new(2, true, cost!(Lead: 120, Thorium: 75, Silicon: 130));
+ "surge-smelter" -> ProductionBlock::new(3, true, cost!(Lead: 80, Thorium: 70, Silicon: 80));
+ "cryofluid-mixer" -> ProductionBlock::new(2, true, cost!(Lead: 65, Thorium: 60, Silicon: 40));
+ "pyratite-mixer" -> ProductionBlock::new(2, true, cost!(Copper: 50, Lead: 25));
+ "blast-mixer" -> ProductionBlock::new(2, true, cost!(Lead: 30, Thorium: 20));
+ "melter" -> ProductionBlock::new(1, true, cost!(Copper: 30, Lead: 35, Graphite: 45));
+ "separator" -> SeparatorBlock::new(2, true, cost!(Copper: 30, Titanium: 25));
+ "disassembler" -> SeparatorBlock::new(3, true, cost!(Titanium: 100, Thorium: 80, Silicon: 150, Plastanium: 40));
+ "spore-press" -> ProductionBlock::new(2, true, cost!(Lead: 35, Silicon: 30));
+ "pulverizer" -> ProductionBlock::new(1, true, cost!(Copper: 30, Lead: 25));
+ "coal-centrifuge" -> ProductionBlock::new(2, true, cost!(Lead: 30, Graphite: 40, Titanium: 20));
+ "incinerator" -> BasicBlock::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));
+ "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));
+ "slag-heater" => HeatCrafter::new(3, false, cost!(Tungsten: 50, Oxide: 20, Beryllium: 20));
+ "phase-heater" => HeatCrafter::new(2, false, cost!(Oxide: 30, Carbide: 30, Beryllium: 30));
+ "heat-redirector" => HeatConduit::new(3, false, cost!(Tungsten: 10, Graphite: 10));
+ "heat-router" => HeatConduit::new(3, false, cost!(Tungsten: 15, Graphite: 10));
+ "slag-incinerator" -> BasicBlock::new(1, true, cost!(Tungsten: 15));
+ "carbide-crucible" -> ProductionBlock::new(3, true, cost!(Tungsten: 110, Thorium: 150, Oxide: 60));
+ // slag centrifuge
+ "surge-crucible" -> ProductionBlock::new(3, true, cost!(Silicon: 100, Graphite: 80, Tungsten: 80, Oxide: 80));
+ "cyanogen-synthesizer" -> ProductionBlock::new(3, true, cost!(Carbide: 50, Silicon: 80, Beryllium: 90));
+ "phase-synthesizer" -> ProductionBlock::new(3, true, cost!(Carbide: 90, Silicon: 100, Thorium: 100, Tungsten: 200));
+ // heat reactor
+ "payload-conveyor" => PayloadConveyor::new(3, false, cost!(Copper: 10, Graphite: 10));
+ "payload-router" => PayloadRouter::new(3, false, cost!(Copper: 10, Graphite: 15));
+ "reinforced-payload-conveyor" => PayloadConveyor::new(3, false, cost!(Tungsten: 10));
+ "reinforced-payload-router" => PayloadRouter::new(3, false, cost!(Tungsten: 15));
+ "payload-mass-driver" -> BridgeBlock::new(3, true, cost!(Tungsten: 120, Silicon: 120, Graphite: 50), 700, false);
+ "large-payload-mass-driver" -> BridgeBlock::new(5, true, cost!(Thorium: 200, Tungsten: 200, Silicon: 200, Graphite: 100, Oxide: 30), 1100, false);
+ "small-deconstructor" => SimplePayloadBlock::new(3, true, cost!(Beryllium: 100, Silicon: 100, Oxide: 40, Graphite: 80));
+ "deconstructor" => SimplePayloadBlock::new(5, true, cost!(Beryllium: 250, Oxide: 100, Silicon: 250, Carbide: 250));
+ "constructor" => PayloadBlock::new(3, true, cost!(Silicon: 100, Beryllium: 150, Tungsten: 80));
+ "large-constructor" => PayloadBlock::new(5, true, cost!(Silicon: 150, Oxide: 150, Tungsten: 200, PhaseFabric: 40));
+ "payload-loader" => SimplePayloadBlock::new(3, false, cost!(Graphite: 50, Silicon: 50, Tungsten: 80));
+ "payload-unloader" => SimplePayloadBlock::new(3, false, cost!(Graphite: 50, Silicon: 50, Tungsten: 30));
+ "copper-wall" -> WallBlock::new(1, true, cost!(Copper: 6));
+ "copper-wall-large" -> WallBlock::new(2, true, cost!(Copper: 6 * 4));
+ "titanium-wall" -> WallBlock::new(1, true, cost!(Titanium: 6));
+ "titanium-wall-large" -> WallBlock::new(2, true, cost!(Titanium: 6 * 4));
+ "plastanium-wall" -> WallBlock::new(1, true, cost!(Metaglass: 2, Plastanium: 5));
+ "plastanium-wall-large" -> WallBlock::new(2, true, cost!(Metaglass: 2 * 4, Plastanium: 5 * 4));
+ "thorium-wall" -> WallBlock::new(1, true, cost!(Thorium: 6));
+ "thorium-wall-large" -> WallBlock::new(2, true, cost!(Thorium: 6 * 4));
+ "phase-wall" -> WallBlock::new(1, true, cost!(PhaseFabric: 6));
+ "phase-wall-large" -> WallBlock::new(2, true, cost!(PhaseFabric: 6 * 4));
+ "surge-wall" -> WallBlock::new(1, true, cost!(SurgeAlloy: 6));
+ "surge-wall-large" -> WallBlock::new(2, true, cost!(SurgeAlloy: 6 * 4));
+ "door" => DoorBlock::new(1, true, cost!(Titanium: 6, Silicon: 4));
+ "door-large" => DoorBlock::new(2, true, cost!(Titanium: 6 * 4, Silicon: 4 * 4));
+ "tungsten-wall" -> WallBlock::new(1, true, cost!(Tungsten: 6));
+ "tungsten-wall-large" -> WallBlock::new(2, true, cost!(Tungsten: 6 * 4));
+ "blast-door" -> DoorBlock::new(2, true, cost!(Tungsten: 24, Silicon: 24));
+ "reinforced-surge-wall" -> WallBlock::new(1, true, cost!(SurgeAlloy: 6, Tungsten: 2));
+ "reinforced-surge-wall-large" -> WallBlock::new(2, true, cost!(SurgeAlloy: 6 * 4, Tungsten: 2 * 4));
+ "carbide-wall" -> WallBlock::new(1, true, cost!(Thorium: 6, Carbide: 6));
+ "carbide-wall-large" -> WallBlock::new(2, true, cost!(Thorium: 6 * 4, Carbide: 6 * 4));
+ "shielded-wall" -> WallBlock::new(2, true, cost!(PhaseFabric: 20, SurgeAlloy: 12, Beryllium: 12));
+ "beryllium-wall" -> WallBlock::new(1, true, cost!(Beryllium: 6));
+ "beryllium-wall-large" -> WallBlock::new(2, true, cost!(Beryllium: 6 * 4));
+ "scrap-wall" -> WallBlock::new(1, true, cost!(Scrap: 6));
+ "scrap-wall-large" -> WallBlock::new(2, true, cost!(Scrap: 24));
+ "scrap-wall-huge" -> WallBlock::new(3, true, cost!(Scrap: 54));
+ "scrap-wall-gigantic" -> WallBlock::new(4, true, cost!(Scrap: 96));
+ "thruster" => WallBlock::new(4, false, cost!(Scrap: 96));
+ "mender" -> HeatedBlock::new(1, true, cost!(Copper: 25, Lead: 30));
+ "mend-projector" -> HeatedBlock::new(2, true, cost!(Copper: 50, Lead: 100, Titanium: 25, Silicon: 40));
+ "overdrive-projector" -> HeatedBlock::new(2, true, cost!(Lead: 100, Titanium: 75, Silicon: 75, Plastanium: 30));
+ "overdrive-dome" -> HeatedBlock::new(3, true, cost!(Lead: 200, Titanium: 130, Silicon: 130, Plastanium: 80, SurgeAlloy: 120));
+ "force-projector" -> BasicBlock::new(3, true, cost!(Lead: 100, Titanium: 75, Silicon: 125));
+ "regen-projector" -> BasicBlock::new(3, true, cost!(Silicon: 80, Tungsten: 60, Oxide: 40, Beryllium: 80));
+ "shock-mine" -> BasicBlock::new(1, true, cost!(Lead: 25, Silicon: 12));
+ "radar" -> RadarBlock::new(1, true, cost!(Silicon: 60, Graphite: 50, Beryllium: 10));
+ "build-tower" -> BasicBlock::new(3, true, cost!(Silicon: 150, Oxide: 40, Thorium: 60));
+ "shockwave-tower" -> BasicBlock::new(3, true, cost!(SurgeAlloy: 50, Silicon: 150, Oxide: 30, Tungsten: 100));
+ "reinforced-pump" -> BasicBlock::new(2, true, cost!(Beryllium: 40, Tungsten: 30, Silicon: 20));
+ "mechanical-pump" -> BasicBlock::new(1, true, cost!(Copper: 15, Metaglass: 10));
+ "rotary-pump" -> BasicBlock::new(2, true, cost!(Copper: 70, Metaglass: 50, Titanium: 35, Silicon: 20));
+ "impulse-pump" -> BasicBlock::new(3, true, cost!(Copper: 80, Metaglass: 90, Titanium: 40, Thorium: 35, Silicon: 30));
+ "conduit" => ConduitBlock::new(1, false, cost!(Metaglass: 1));
+ "pulse-conduit" => ConduitBlock::new(1, false, cost!(Metaglass: 1, Titanium: 2));
+ "plated-conduit" => ConduitBlock::new(1, false, cost!(Metaglass: 1, Thorium: 2, Plastanium: 1));
+ "liquid-router" -> BasicBlock::new(1, true, cost!(Metaglass: 2, Graphite: 4));
+ "liquid-container" -> BasicBlock::new(2, true, cost!(Metaglass: 15, Titanium: 10));
+ "liquid-tank" -> BasicBlock::new(3, true, cost!(Metaglass: 40, Titanium: 30));
+ "liquid-junction" -> BasicBlock::new(1, true, cost!(Metaglass: 8, Graphite: 4));
+ "bridge-conduit" -> BridgeBlock::new(1, true, cost!(Metaglass: 8, Graphite: 4), 4, true);
+ "phase-conduit" -> BridgeBlock::new(1, true, cost!(Metaglass: 20, Titanium: 10, Silicon: 7, PhaseFabric: 5), 12, true);
+ "reinforced-conduit" => ConduitBlock::new(1, false, cost!(Beryllium: 2));
+ "reinforced-liquid-junction" -> BasicBlock::new(1, true, cost!(Graphite: 4, Beryllium: 8));
+ "reinforced-bridge-conduit" => BridgeBlock::new(1, true, cost!(Graphite: 8, Beryllium: 20), 4, true);
+ "reinforced-liquid-router" -> BasicBlock::new(1, true, cost!(Graphite: 8, Beryllium: 4));
+ "reinforced-liquid-container" -> BasicBlock::new(2, true, cost!(Tungsten: 10, Beryllium: 16));
+ "reinforced-liquid-tank" -> BasicBlock::new(3, true, cost!(Tungsten: 40, Beryllium: 50));
+ "ground-factory" => UnitFactory::new(3, false, cost!(Copper: 50, Lead: 120, Silicon: 80), units::GROUND_UNITS);
+ "air-factory" => UnitFactory::new(3, false, cost!(Copper: 60, Lead: 70), units::AIR_UNITS);
+ "naval-factory" => UnitFactory::new(3, false, cost!(Copper: 150, Lead: 130, Metaglass: 120), units::NAVAL_UNITS);
+ "additive-reconstructor" => ConstructorBlock::new(3, false, cost!(Copper: 200, Lead: 120, Silicon: 90));
+ "multiplicative-reconstructor" => ConstructorBlock::new(5, false, cost!(Lead: 650, Titanium: 350, Thorium: 650, Silicon: 450));
+ "exponential-reconstructor" => ConstructorBlock::new(7, false, cost!(Lead: 2000, Titanium: 2000, Thorium: 750, Silicon: 1000, Plastanium: 450, PhaseFabric: 600));
+ "tetrative-reconstructor" => ConstructorBlock::new(9, false, cost!(Lead: 4000, Thorium: 1000, Silicon: 3000, Plastanium: 600, PhaseFabric: 600, SurgeAlloy: 800));
+ "repair-point" -> RepairTurret::new(1, true, cost!(Copper: 30, Lead: 30, Silicon: 20));
+ "repair-turret" -> RepairTurret::new(2, true, cost!(Thorium: 80, Silicon: 90, Plastanium: 60));
+ "tank-fabricator" => UnitFactory::new(3, true, cost!(Silicon: 200, Beryllium: 150), &[crate::unit::Type::Stell]);
+ "ship-fabricator" => UnitFactory::new(3, true, cost!(Silicon: 250, Beryllium: 200), &[crate::unit::Type::Elude]);
+ "mech-fabricator" => UnitFactory::new(3, true, cost!(Silicon: 200, Graphite: 300, Tungsten: 60), &[crate::unit::Type::Merui]);
+ "tank-refabricator" => ConstructorBlock::new(3, true, cost!(Beryllium: 200, Tungsten: 80, Silicon: 100));
+ "mech-refabricator" => ConstructorBlock::new(3, true, cost!(Beryllium: 250, Tungsten: 120, Silicon: 150));
+ "ship-refabricator" => ConstructorBlock::new(3, true, cost!(Beryllium: 200, Tungsten: 100, Silicon: 150, Oxide: 40));
+ "prime-refabricator" => ConstructorBlock::new(5, true, cost!(Thorium: 250, Oxide: 200, Tungsten: 200, Silicon: 400));
+ "tank-assembler" => AssemblerBlock::new(5, true, cost!(Thorium: 500, Oxide: 150, Carbide: 80, Silicon: 500));
+ "ship-assembler" => AssemblerBlock::new(5, true, cost!(Carbide: 100, Oxide: 200, Tungsten: 500, Silicon: 800, Thorium: 400));
+ "mech-assembler" => AssemblerBlock::new(5, true, cost!(Carbide: 200, Thorium: 600, Oxide: 200, Tungsten: 500, Silicon: 900)); // smh collaris
+ "basic-assembler-module" => AssemblerModule::new(5, true, cost!(Carbide: 300, Thorium: 500, Oxide: 200, PhaseFabric: 400)); // the dummy block
+ "unit-repair-tower" -> BasicBlock::new(2, true, cost!(Graphite: 90, Silicon: 90, Tungsten: 80));
+ "launch-pad" -> BasicBlock::new(3, true, cost!(Copper: 350, Lead: 200, Titanium: 150, Silicon: 140));
+ "interplanetary-accelerator" -> BasicBlock::new(7, true, cost!(Copper: 16000, Silicon: 11000, Thorium: 13000, Titanium: 12000, SurgeAlloy: 6000, PhaseFabric: 5000));
+ "mechanical-drill" -> DrillBlock::new(2, true, cost!(Copper: 12));
+ "pneumatic-drill" -> DrillBlock::new(2, true, cost!(Copper: 18, Graphite: 10));
+ "laser-drill" -> DrillBlock::new(3, true, cost!(Copper: 35, Graphite: 30, Titanium: 20, Silicon: 30));
+ "blast-drill" -> DrillBlock::new(4, true, cost!(Copper: 65, Titanium: 50, Thorium: 75, Silicon: 60));
+ "water-extractor" -> BasicBlock::new(2, true, cost!(Copper: 30, Lead: 30, Metaglass: 30, Graphite: 30));
+ "oil-extractor" -> BasicBlock::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" -> 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));
+ "eruption-drill" -> DrillBlock::new(5, true, cost!(Silicon: 200, Oxide: 20, Tungsten: 200, Thorium: 120));
+ "reinforced-message" -> MessageLogic::new(1, true, cost!(Graphite: 10, Beryllium: 5));
+ "message" -> MessageLogic::new(1, true, cost!(Copper: 5, Graphite: 5));
+ "switch" => SwitchLogic::new(1, true, cost!(Copper: 5, Graphite: 5));
+ "micro-processor" -> ProcessorLogic::new(1, true, cost!(Copper: 90, Lead: 50, Silicon: 50));
+ "logic-processor" -> ProcessorLogic::new(2, true, cost!(Lead: 320, Graphite: 60, Thorium: 50, Silicon: 80));
+ "hyper-processor" -> ProcessorLogic::new(3, true, cost!(Lead: 450, Thorium: 75, Silicon: 150, SurgeAlloy: 50));
+ "memory-cell" -> MemoryBlock::new(1, true, cost!(Copper: 30, Graphite: 30, Silicon: 30));
+ "memory-bank" -> MemoryBlock::new(2, true, cost!(Copper: 30, Graphite: 80, Silicon: 80, PhaseFabric: 30));
+ "logic-display" -> BasicBlock::new(3, true, cost!(Lead: 100, Metaglass: 50, Silicon: 50));
+ "large-logic-display" -> BasicBlock::new(6, true, cost!(Lead: 200, Metaglass: 100, Silicon: 150, PhaseFabric: 75));
+ "canvas" => CanvasBlock::new(2, true, cost!(Silicon: 30, Beryllium: 10), 12);
+ "illuminator" -> LampBlock::new(1, true, cost!(Lead: 8, Graphite: 12, Silicon: 8));
+ "power-node" -> ConnectorBlock::new(1, true, cost!(Copper: 1, Lead: 3), 10);
+ "power-node-large" -> ConnectorBlock::new(2, true, cost!(Lead: 10, Titanium: 5, Silicon: 3), 15);
+ "surge-tower" -> ConnectorBlock::new(2, true, cost!(Lead: 10, Titanium: 7, Silicon: 15, SurgeAlloy: 15), 2);
+ "diode" => DiodeBlock::new(1, false, cost!(Metaglass: 10, Silicon: 10, Plastanium: 5));
+ "battery" -> BasicBlock::new(1, true, cost!(Copper: 5, Lead: 20));
+ "battery-large" -> BasicBlock::new(3, true, cost!(Lead: 50, Titanium: 20, Silicon: 30));
+ "combustion-generator" -> GeneratorBlock::new(1, true, cost!(Copper: 25, Lead: 15));
+ "thermal-generator" -> GeneratorBlock::new(2, true, cost!(Copper: 40, Lead: 50, Metaglass: 40, Graphite: 35, Silicon: 35));
+ "steam-generator" -> GeneratorBlock::new(2, true, cost!(Copper: 35, Lead: 40, Graphite: 25, Silicon: 30));
+ "differential-generator" -> GeneratorBlock::new(3, true, cost!(Copper: 70, Lead: 100, Metaglass: 50, Titanium: 50, Silicon: 65));
+ "rtg-generator" -> GeneratorBlock::new(2, true, cost!(Lead: 100, Thorium: 50, Silicon: 75, Plastanium: 75, PhaseFabric: 25));
+ "solar-panel" -> GeneratorBlock::new(1, true, cost!(Lead: 10, Silicon: 15));
+ "solar-panel-large" -> GeneratorBlock::new(3, true, cost!(Lead: 80, Silicon: 110, PhaseFabric: 15));
+ "thorium-reactor" -> NuclearGeneratorBlock::new(3, true, cost!(Lead: 300, Metaglass: 50, Graphite: 150, Thorium: 150, Silicon: 200));
+ "impact-reactor" -> ImpactReactorBlock::new(4, true, cost!(Lead: 500, Metaglass: 250, Graphite: 400, Thorium: 100, Silicon: 300, SurgeAlloy: 250));
+ "beam-node" -> ConnectorBlock::new(1, true, cost!(Beryllium: 8), 4);
+ "beam-tower" -> ConnectorBlock::new(3, true, cost!(Beryllium: 30, Oxide: 10, Silicon: 10), 12);
+ "turbine-condenser" -> GeneratorBlock::new(3, true, cost!(Beryllium: 60));
+ "chemical-combustion-chamber" -> GeneratorBlock::new(3, true, cost!(Graphite: 40, Tungsten: 40, Oxide: 40, Silicon: 30));
+ "pyrolysis-generator" -> GeneratorBlock::new(3, true, cost!(Graphite: 50, Carbide: 50, Oxide: 60, Silicon: 50));
+ "flux-reactor" -> GeneratorBlock::new(5, true, cost!(Graphite: 300, Carbide: 200, Oxide: 100, Silicon: 600, SurgeAlloy: 300));
+ "neoplasia-reactor" => Neoplasia::new(5, true, cost!(Tungsten: 1000, Carbide: 300, Oxide: 150, Silicon: 500, PhaseFabric: 300, SurgeAlloy: 200));
+ "core-shard" -> BasicBlock::new(3, true, cost!(Copper: 1000, Lead: 800));
+ "core-foundation" -> BasicBlock::new(4, true, cost!(Copper: 3000, Lead: 3000, Silicon: 2000));
+ "core-nucleus" -> BasicBlock::new(5, true, cost!(Copper: 8000, Lead: 8000, Thorium: 4000, Silicon: 5000));
+ "core-bastion" -> BasicBlock::new(4, true, cost!(Graphite: 1000, Silicon: 1000, Beryllium: 800));
+ "core-citadel" -> BasicBlock::new(5, true, cost!(Silicon: 4000, Beryllium: 4000, Tungsten: 3000, Oxide: 1000));
+ "core-acropolis" -> BasicBlock::new(6, true, cost!(Beryllium: 6000, Silicon: 5000, Tungsten: 5000, Carbide: 3000, Oxide: 3000));
+ "container" -> BasicBlock::new(2, true, cost!(Titanium: 100));
+ "vault" -> BasicBlock::new(3, true, cost!(Titanium: 250, Thorium: 125));
+ "reinforced-container" -> BasicBlock::new(2, true, cost!(Tungsten: 30, Graphite: 40));
+ "reinforced-vault" -> BasicBlock::new(3, true, cost!(Tungsten: 125, Thorium: 70, Beryllium: 100));
+ "duo" -> ItemTurret::new(1, true, cost!(Copper: 35));
+ "scatter" -> ItemTurret::new(2, true, cost!(Copper: 85, Lead: 45));
+ "scorch" -> ItemTurret::new(1, true, cost!(Copper: 25, Graphite: 22));
+ "hail" -> ItemTurret::new(1, true, cost!(Copper: 40, Graphite: 17));
+ "wave" -> Turret::new(2, true, cost!(Copper: 25, Lead: 75, Metaglass: 45));
+ "tsunami" -> Turret::new(3, true, cost!(Lead: 400, Metaglass: 100, Titanium: 250, Thorium: 100));
+ "lancer" -> Turret::new(2, true, cost!(Copper: 60, Lead: 70, Titanium: 30, Silicon: 60));
+ "arc" -> Turret::new(1, true, cost!(Copper: 50, Lead: 50));
+ "parallax" -> TractorBeamTurret::new(2, true, cost!(Graphite: 30, Titanium: 90, Silicon: 120));
+ "swarmer" -> ItemTurret::new(2, true, cost!(Graphite: 35, Titanium: 35, Silicon: 30, Plastanium: 45));
+ "salvo" -> ItemTurret::new(2, true, cost!(Copper: 100, Graphite: 80, Titanium: 50));
+ "segment" -> PointDefenseTurret::new(2, true, cost!(Titanium: 40, Thorium: 80, Silicon: 130, PhaseFabric: 40));
+ "fuse" -> ItemTurret::new(3, true, cost!(Copper: 225, Graphite: 225, Thorium: 100));
+ "ripple" -> ItemTurret::new(3, true, cost!(Copper: 150, Graphite: 135, Titanium: 60));
+ "cyclone" -> ItemTurret::new(3, true, cost!(Copper: 200, Titanium: 125, Plastanium: 80));
+ "foreshadow" -> ItemTurret::new(4, true, cost!(Copper: 1000, Metaglass: 600, Silicon: 600, Plastanium: 200, SurgeAlloy: 300));
+ "spectre" -> ItemTurret::new(4, true, cost!(Copper: 900, Graphite: 300, Thorium: 250, Plastanium: 175, SurgeAlloy: 250));
+ "meltdown" -> Turret::new(4, true, cost!(Copper: 1200, Lead: 350, Graphite: 300, Silicon: 325, SurgeAlloy: 325));
+ "breach" -> ItemTurret::new(3, true, cost!(Beryllium: 150, Silicon: 150, Graphite: 250));
+ "diffuse" -> ItemTurret::new(3, true, cost!(Beryllium: 150, Silicon: 200, Graphite: 200, Tungsten: 50));
+ "sublimate" -> ContinousTurret::new(3, true, cost!(Tungsten: 150, Silicon: 200, Oxide: 40, Beryllium: 400));
+ "titan" -> ItemTurret::new(4, true, cost!(Tungsten: 250, Silicon: 300, Thorium: 400));
+ "disperse" -> ItemTurret::new(4, true, cost!(Thorium: 50, Oxide: 150, Silicon: 200, Beryllium: 350));
+ "afflict" -> Turret::new(4, true, cost!(SurgeAlloy: 100, Silicon: 200, Graphite: 250, Oxide: 40));
+ "lustre" -> ContinousTurret::new(4, true, cost!(Silicon: 250, Graphite: 200, Oxide: 50, Carbide: 90));
+ "scathe" -> ItemTurret::new(4, true, cost!(Oxide: 200, SurgeAlloy: 400, Silicon: 800, Carbide: 500, PhaseFabric: 300));
+ "malign" -> Turret::new(5, true, cost!(Carbide: 400, Beryllium: 2000, Silicon: 800, Graphite: 800, PhaseFabric: 300));
+ "smite" -> ItemTurret::new(5, true, cost!(Oxide: 200, SurgeAlloy: 400, Silicon: 800, Carbide: 500, PhaseFabric: 300));
+ // sandbox only
+ "beam-link" -> ConnectorBlock::new(3, true, &[], 12);
+ "power-source" -> ConnectorBlock::new(1, true, &[], 100);
+ "power-void" -> GeneratorBlock::new(1, true, &[]);
+ "world-processor" -> BasicBlock::new(1, true, &[]);
+ "world-message" -> MessageLogic::new(1, true, &[]);
+ "world-cell" -> MemoryBlock::new(1, true, &[]);
+ "liquid-source" => FluidBlock::new(1, true, &[]);
+ "liquid-void" -> BasicBlock::new(1, true, &[]);
+ "barrier-projector" -> BasicBlock::new(3, true, &[]);
+ "shield-projector" -> ShieldBlock::new(3, true, &[]);
+ "large-shield-projector" -> ShieldBlock::new(4, true, &[]);
+ "payload-source" => PayloadBlock::new(5, false, &[]);
+ "payload-void" => SimplePayloadBlock::new(5, true, &[]);
+ "item-source" -> ItemBlock::new(1, true, &[]);
+ "item-void" -> BasicBlock::new(1, true, &[]);
+ "heat-source" => HeatCrafter::new(1, false, &[]);
}
diff --git a/src/block/payload.rs b/src/block/payload.rs
index fef2246..300e366 100644
--- a/src/block/payload.rs
+++ b/src/block/payload.rs
@@ -2,7 +2,6 @@
use thiserror::Error;
use crate::block::content::Type as BlockEnum;
-use crate::block::distribution::BridgeBlock;
use crate::block::simple::*;
use crate::block::{self, *};
use crate::content::{self, Content};
@@ -11,8 +10,6 @@ use crate::data::entity_mapping;
use crate::data::ReadError;
use crate::unit;
-use super::BlockRegistry;
-
make_simple!(SimplePayloadBlock, |_, n, _, _, r: Rotation, scl| {
match n {
"deconstructor" | "small-deconstructor" | "payload-void" => {
@@ -70,24 +67,6 @@ make_simple!(
} // read_payload_router
);
-make_register! {
- "payload-conveyor" => PayloadConveyor::new(3, false, cost!(Copper: 10, Graphite: 10));
- "payload-router" => PayloadRouter::new(3, false, cost!(Copper: 10, Graphite: 15));
- "reinforced-payload-conveyor" => PayloadConveyor::new(3, false, cost!(Tungsten: 10));
- "reinforced-payload-router" => PayloadRouter::new(3, false, cost!(Tungsten: 15));
- "payload-mass-driver" -> BridgeBlock::new(3, true, cost!(Tungsten: 120, Silicon: 120, Graphite: 50), 700, false);
- "large-payload-mass-driver" -> BridgeBlock::new(5, true, cost!(Thorium: 200, Tungsten: 200, Silicon: 200, Graphite: 100, Oxide: 30), 1100, false);
- "small-deconstructor" => SimplePayloadBlock::new(3, true, cost!(Beryllium: 100, Silicon: 100, Oxide: 40, Graphite: 80));
- "deconstructor" => SimplePayloadBlock::new(5, true, cost!(Beryllium: 250, Oxide: 100, Silicon: 250, Carbide: 250));
- "constructor" => PayloadBlock::new(3, true, cost!(Silicon: 100, Beryllium: 150, Tungsten: 80));
- "large-constructor" => PayloadBlock::new(5, true, cost!(Silicon: 150, Oxide: 150, Tungsten: 200, PhaseFabric: 40));
- "payload-loader" => SimplePayloadBlock::new(3, false, cost!(Graphite: 50, Silicon: 50, Tungsten: 80));
- "payload-unloader" => SimplePayloadBlock::new(3, false, cost!(Graphite: 50, Silicon: 50, Tungsten: 30));
- // sandbox only
- "payload-source" => PayloadBlock::new(5, false, &[]);
- "payload-void" => SimplePayloadBlock::new(5, true, &[]);
-}
-
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
/// payload item cfg
pub enum Payload {
@@ -182,12 +161,8 @@ impl BlockLogic for PayloadBlock {
/// - t: [`u8`]
/// - sort: [`u16`]
/// - recdir: [`u8`]
-fn read_payload_router(
- b: &mut Build,
- reg: &BlockRegistry,
- buff: &mut DataRead,
-) -> Result<(), DataReadError> {
- read_payload_conveyor(b, reg, buff)?;
+fn read_payload_router(b: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
+ read_payload_conveyor(b, buff)?;
buff.skip(4)
}
@@ -195,13 +170,9 @@ fn read_payload_router(
/// - [`skip(4)`](`DataRead::skip`)
/// - rot: [`f32`]
/// - become [`read_payload`]
-fn read_payload_conveyor(
- _: &mut Build,
- reg: &BlockRegistry,
- buff: &mut DataRead,
-) -> Result<(), DataReadError> {
+fn read_payload_conveyor(_: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
buff.skip(8)?;
- read_payload(reg, buff)
+ read_payload(buff)
}
/// format:
@@ -216,12 +187,9 @@ pub(crate) fn read_payload_seq(buff: &mut DataRead) -> Result<(), DataReadError>
/// - vector: ([`f32`], [`f32`])
/// - rotation: [`f32`]
/// - become [`read_payload`]
-pub(crate) fn read_payload_block(
- reg: &BlockRegistry,
- buff: &mut DataRead,
-) -> Result<(), DataReadError> {
+pub(crate) fn read_payload_block(buff: &mut DataRead) -> Result<(), DataReadError> {
buff.skip(12)?;
- read_payload(reg, buff)
+ read_payload(buff)
}
/// format:
@@ -235,7 +203,7 @@ pub(crate) fn read_payload_block(
/// - if type == 2 (paylood unit):
/// - id: [`u8`]
/// - call [`UnitClass::read`](crate::data::entity_mapping::UnitClass::read)
-fn read_payload(reg: &BlockRegistry, buff: &mut DataRead) -> Result<(), DataReadError> {
+fn read_payload(buff: &mut DataRead) -> Result<(), DataReadError> {
if !buff.read_bool()? {
return Ok(());
}
@@ -246,8 +214,8 @@ fn read_payload(reg: &BlockRegistry, buff: &mut DataRead) -> Result<(), DataRead
BLOCK => {
let b = buff.read_u16()?;
let b = BlockEnum::try_from(b).unwrap_or(BlockEnum::Router);
- let block = reg.get(b.get_name()).unwrap();
- block.logic.read(&mut Build::new(block), reg, buff)?;
+ let block = BLOCK_REGISTRY.get(b.get_name()).unwrap();
+ block.logic.read(&mut Build::new(block), buff)?;
}
UNIT => {
let u = buff.read_u8()? as usize;
@@ -263,20 +231,17 @@ fn read_payload(reg: &BlockRegistry, buff: &mut DataRead) -> Result<(), DataRead
#[cfg(test)]
mod tests {
- use crate::registry::Registry;
use super::*;
#[test]
fn payload_conv() {
- let mut reg = Registry::default();
- register(&mut reg);
let mut r = DataRead::new(&[0, 0, 0, 0, 0, 0, 0, 0, 0]);
- read_payload_conveyor(&mut Build::new(&PAYLOAD_CONVEYOR), &reg, &mut r).unwrap();
+ read_payload_conveyor(&mut Build::new(&PAYLOAD_CONVEYOR), &mut r).unwrap();
assert!(r.read_bool().is_err());
let mut r = DataRead::new(&[
65, 198, 232, 0, 67, 51, 255, 249, 1, 1, 0, 157, 0, 67, 197, 128, 0, 128, 1, 3,
]);
- read_payload_conveyor(&mut Build::new(&PAYLOAD_CONVEYOR), &reg, &mut r).unwrap();
+ read_payload_conveyor(&mut Build::new(&PAYLOAD_CONVEYOR), &mut r).unwrap();
assert!(r.read_bool().is_err());
}
}
diff --git a/src/block/power.rs b/src/block/power.rs
index b316afb..7b04135 100644
--- a/src/block/power.rs
+++ b/src/block/power.rs
@@ -5,9 +5,9 @@ use crate::block::simple::*;
use crate::block::*;
use crate::data::dynamic::DynType;
-make_simple!(GeneratorBlock => |_, _, buff: &mut DataRead| read_generator(buff));
-make_simple!(NuclearGeneratorBlock => |_, _, buff: &mut DataRead| read_nuclear(buff));
-make_simple!(ImpactReactorBlock => |_, _, buff: &mut DataRead| read_impact(buff));
+make_simple!(GeneratorBlock => |_, buff: &mut DataRead| read_generator(buff));
+make_simple!(NuclearGeneratorBlock => |_, buff: &mut DataRead| read_nuclear(buff));
+make_simple!(ImpactReactorBlock => |_, buff: &mut DataRead| read_impact(buff));
make_simple!(
Neoplasia,
|_, _, _, _, rot: Rotation, scl| {
@@ -23,7 +23,7 @@ make_simple!(
};
base
},
- |_, _, buff: &mut DataRead| read_heater(buff)
+ |_, buff: &mut DataRead| read_heater(buff)
);
make_simple!(DiodeBlock, |_, _, _, _, rot: Rotation, s| {
let mut base = load!("diode", s);
@@ -38,39 +38,6 @@ make_simple!(DiodeBlock, |_, _, _, _, rot: Rotation, s| {
base
});
-make_register! {
- // illuminator == power ?????
- "illuminator" -> LampBlock::new(1, true, cost!(Lead: 8, Graphite: 12, Silicon: 8));
- "power-node" -> ConnectorBlock::new(1, true, cost!(Copper: 1, Lead: 3), 10);
- "power-node-large" -> ConnectorBlock::new(2, true, cost!(Lead: 10, Titanium: 5, Silicon: 3), 15);
- "surge-tower" -> ConnectorBlock::new(2, true, cost!(Lead: 10, Titanium: 7, Silicon: 15, SurgeAlloy: 15), 2);
- "diode" => DiodeBlock::new(1, false, cost!(Metaglass: 10, Silicon: 10, Plastanium: 5));
- "battery" -> BasicBlock::new(1, true, cost!(Copper: 5, Lead: 20));
- "battery-large" -> BasicBlock::new(3, true, cost!(Lead: 50, Titanium: 20, Silicon: 30));
- "combustion-generator" -> GeneratorBlock::new(1, true, cost!(Copper: 25, Lead: 15));
- "thermal-generator" -> GeneratorBlock::new(2, true, cost!(Copper: 40, Lead: 50, Metaglass: 40, Graphite: 35, Silicon: 35));
- "steam-generator" -> GeneratorBlock::new(2, true, cost!(Copper: 35, Lead: 40, Graphite: 25, Silicon: 30));
- "differential-generator" -> GeneratorBlock::new(3, true, cost!(Copper: 70, Lead: 100, Metaglass: 50, Titanium: 50, Silicon: 65));
- "rtg-generator" -> GeneratorBlock::new(2, true, cost!(Lead: 100, Thorium: 50, Silicon: 75, Plastanium: 75, PhaseFabric: 25));
- "solar-panel" -> GeneratorBlock::new(1, true, cost!(Lead: 10, Silicon: 15));
- "solar-panel-large" -> GeneratorBlock::new(3, true, cost!(Lead: 80, Silicon: 110, PhaseFabric: 15));
- "thorium-reactor" -> NuclearGeneratorBlock::new(3, true, cost!(Lead: 300, Metaglass: 50, Graphite: 150, Thorium: 150, Silicon: 200));
- "impact-reactor" -> ImpactReactorBlock::new(4, true,
- cost!(Lead: 500, Metaglass: 250, Graphite: 400, Thorium: 100, Silicon: 300, SurgeAlloy: 250));
- "beam-node" -> ConnectorBlock::new(1, true, cost!(Beryllium: 8), 4);
- "beam-tower" -> ConnectorBlock::new(3, true, cost!(Beryllium: 30, Oxide: 10, Silicon: 10), 12);
- "turbine-condenser" -> GeneratorBlock::new(3, true, cost!(Beryllium: 60));
- "chemical-combustion-chamber" -> GeneratorBlock::new(3, true, cost!(Graphite: 40, Tungsten: 40, Oxide: 40, Silicon: 30));
- "pyrolysis-generator" -> GeneratorBlock::new(3, true, cost!(Graphite: 50, Carbide: 50, Oxide: 60, Silicon: 50));
- "flux-reactor" -> GeneratorBlock::new(5, true, cost!(Graphite: 300, Carbide: 200, Oxide: 100, Silicon: 600, SurgeAlloy: 300));
- "neoplasia-reactor" => Neoplasia::new(5, true, cost!(Tungsten: 1000, Carbide: 300, Oxide: 150, Silicon: 500, PhaseFabric: 300, SurgeAlloy: 200));
- // editor only
- "beam-link" -> ConnectorBlock::new(3, true, &[], 12);
- // sandbox only
- "power-source" -> ConnectorBlock::new(1, true, &[], 100);
- "power-void" -> GeneratorBlock::new(1, true, &[]);
-}
-
pub struct ConnectorBlock {
size: u8,
symmetric: bool,
diff --git a/src/block/production.rs b/src/block/production.rs
index ee435a6..bd44518 100644
--- a/src/block/production.rs
+++ b/src/block/production.rs
@@ -3,48 +3,8 @@ use crate::block::simple::*;
use crate::block::*;
use crate::data::DataRead;
-make_register! {
- "cultivator" -> ProductionBlock::new(2, true, cost!(Copper: 25, Lead: 25, Silicon: 10));
- "graphite-press" -> ProductionBlock::new(2, true, cost!(Copper: 75, Lead: 30));
- "multi-press" -> ProductionBlock::new(3, true, cost!(Lead: 100, Graphite: 50, Titanium: 100, Silicon: 25));
- "silicon-smelter" -> ProductionBlock::new(2, true, cost!(Copper: 30, Lead: 25));
- "silicon-crucible" -> ProductionBlock::new(3, true, cost!(Metaglass: 80, Titanium: 120, Silicon: 60, Plastanium: 35));
- "kiln" -> ProductionBlock::new(2, true, cost!(Copper: 60, Lead: 30, Graphite: 30));
- "plastanium-compressor" -> ProductionBlock::new(2, true, cost!(Lead: 115, Graphite: 60, Titanium: 80, Silicon: 80));
- "phase-weaver" -> ProductionBlock::new(2, true, cost!(Lead: 120, Thorium: 75, Silicon: 130));
- "surge-smelter" -> ProductionBlock::new(3, true, cost!(Lead: 80, Thorium: 70, Silicon: 80));
- "cryofluid-mixer" -> ProductionBlock::new(2, true, cost!(Lead: 65, Thorium: 60, Silicon: 40));
- "pyratite-mixer" -> ProductionBlock::new(2, true, cost!(Copper: 50, Lead: 25));
- "blast-mixer" -> ProductionBlock::new(2, true, cost!(Lead: 30, Thorium: 20));
- "melter" -> ProductionBlock::new(1, true, cost!(Copper: 30, Lead: 35, Graphite: 45));
- "separator" -> SeparatorBlock::new(2, true, cost!(Copper: 30, Titanium: 25));
- "disassembler" -> SeparatorBlock::new(3, true, cost!(Titanium: 100, Thorium: 80, Silicon: 150, Plastanium: 40));
- "spore-press" -> ProductionBlock::new(2, true, cost!(Lead: 35, Silicon: 30));
- "pulverizer" -> ProductionBlock::new(1, true, cost!(Copper: 30, Lead: 25));
- "coal-centrifuge" -> ProductionBlock::new(2, true, cost!(Lead: 30, Graphite: 40, Titanium: 20));
- "incinerator" -> BasicBlock::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));
- "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));
- "slag-heater" => HeatCrafter::new(3, false, cost!(Tungsten: 50, Oxide: 20, Beryllium: 20));
- "phase-heater" => HeatCrafter::new(2, false, cost!(Oxide: 30, Carbide: 30, Beryllium: 30));
- "heat-redirector" => HeatConduit::new(3, false, cost!(Tungsten: 10, Graphite: 10));
- "heat-router" => HeatConduit::new(3, false, cost!(Tungsten: 15, Graphite: 10));
- "slag-incinerator" -> BasicBlock::new(1, true, cost!(Tungsten: 15));
- "carbide-crucible" -> ProductionBlock::new(3, true, cost!(Tungsten: 110, Thorium: 150, Oxide: 60));
- // slag centrifuge
- "surge-crucible" -> ProductionBlock::new(3, true, cost!(Silicon: 100, Graphite: 80, Tungsten: 80, Oxide: 80));
- "cyanogen-synthesizer" -> ProductionBlock::new(3, true, cost!(Carbide: 50, Silicon: 80, Beryllium: 90));
- "phase-synthesizer" -> ProductionBlock::new(3, true, cost!(Carbide: 90, Silicon: 100, Thorium: 100, Tungsten: 200));
- // heat reactor
- // sandbox only
- "heat-source" => HeatCrafter::new(1, false, &[]);
-}
-
// format: call [`read_production_block`], seed: [`i32`]
-make_simple!(SeparatorBlock => |_, _, buff: &mut DataRead| buff.skip(12));
+make_simple!(SeparatorBlock => |_, buff: &mut DataRead| buff.skip(12));
make_simple!(
ProductionBlock,
@@ -70,7 +30,7 @@ make_simple!(
}
base
},
- |b: &mut Build<'_>, _, buff: &mut DataRead| {
+ |b: &mut Build<'_>, buff: &mut DataRead| {
// format:
// - progress: `f32`
// - warmup: `f32`
@@ -92,7 +52,7 @@ make_simple!(
};
base
},
- |_, _, buff: &mut DataRead| {
+ |_, buff: &mut DataRead| {
// format:
// - progress: `f32`
// - warmup: `f32`
diff --git a/src/block/simple.rs b/src/block/simple.rs
index b100b15..76c7591 100644
--- a/src/block/simple.rs
+++ b/src/block/simple.rs
@@ -54,13 +54,13 @@ macro_rules! make_simple {
&self,
_: i32,
_: crate::data::GridPos,
- ) -> Result<crate::DynData, crate::block::DataConvertError> {
- Ok(crate::DynData::Empty)
+ ) -> Result<crate::data::dynamic::DynData, crate::block::DataConvertError> {
+ Ok(crate::data::dynamic::DynData::Empty)
}
fn deserialize_state(
&self,
- _: crate::DynData,
+ _: crate::data::dynamic::DynData,
) -> Result<Option<crate::block::State>, crate::block::DeserializeError> {
Ok(None)
}
@@ -76,8 +76,8 @@ macro_rules! make_simple {
fn serialize_state(
&self,
_: &crate::block::State,
- ) -> Result<crate::DynData, crate::block::SerializeError> {
- Ok(crate::DynData::Empty)
+ ) -> Result<crate::data::dynamic::DynData, crate::block::SerializeError> {
+ Ok(crate::data::dynamic::DynData::Empty)
}
fn draw(
@@ -95,16 +95,15 @@ macro_rules! make_simple {
fn read(
&self,
build: &mut crate::data::map::Build,
- reg: &crate::block::BlockRegistry,
buff: &mut crate::data::DataRead,
) -> Result<(), crate::data::ReadError> {
#[allow(clippy::redundant_closure_call)]
- $read(build, reg, buff)
+ $read(build, buff)
}
}
};
($name: ident, $draw: expr) => {
- crate::block::simple::make_simple!($name, $draw, |_, _, _| Ok(()));
+ crate::block::simple::make_simple!($name, $draw, |_, _| Ok(()));
};
($name: ident, $draw: expr, $read: expr) => {
crate::block::simple::make_simple!($name, $draw, $read);
@@ -116,11 +115,7 @@ macro_rules! make_simple {
crate::block::simple::make_simple!($name, |_, _, _, _, _, scl| $draw(scl), $read);
};
($name: ident / $draw: expr) => {
- crate::block::simple::make_simple!(
- $name,
- |_, _, _, _, _, scl| $draw(scl),
- |_, _, _| Ok(())
- );
+ crate::block::simple::make_simple!($name, |_, _, _, _, _, scl| $draw(scl), |_, _| Ok(()));
};
($name: ident) => {
crate::block::simple::make_simple!($name, |_, n, _, _, _, _| unimplemented!("{n}"));
diff --git a/src/block/storage.rs b/src/block/storage.rs
deleted file mode 100644
index c28b7bd..0000000
--- a/src/block/storage.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//! cores, vaults, containers
-use crate::block::make_register;
-use crate::block::simple::*;
-
-make_register! {
- "core-shard" -> BasicBlock::new(3, true, cost!(Copper: 1000, Lead: 800));
- "core-foundation" -> BasicBlock::new(4, true, cost!(Copper: 3000, Lead: 3000, Silicon: 2000));
- "core-nucleus" -> BasicBlock::new(5, true, cost!(Copper: 8000, Lead: 8000, Thorium: 4000, Silicon: 5000));
- "core-bastion" -> BasicBlock::new(4, true, cost!(Graphite: 1000, Silicon: 1000, Beryllium: 800));
- "core-citadel" -> BasicBlock::new(5, true, cost!(Silicon: 4000, Beryllium: 4000, Tungsten: 3000, Oxide: 1000));
- "core-acropolis" -> BasicBlock::new(6, true, cost!(Beryllium: 6000, Silicon: 5000, Tungsten: 5000, Carbide: 3000, Oxide: 3000));
- "container" -> BasicBlock::new(2, true, cost!(Titanium: 100));
- "vault" -> BasicBlock::new(3, true, cost!(Titanium: 250, Thorium: 125));
- "reinforced-container" -> BasicBlock::new(2, true, cost!(Tungsten: 30, Graphite: 40));
- "reinforced-vault" -> BasicBlock::new(3, true, cost!(Tungsten: 125, Thorium: 70, Beryllium: 100));
-}
diff --git a/src/block/turrets.rs b/src/block/turrets.rs
index 3759c90..d9c83d1 100644
--- a/src/block/turrets.rs
+++ b/src/block/turrets.rs
@@ -1,45 +1,12 @@
//! idk why its not in the [`crate::block::defense`] module
use super::simple::make_simple;
-use crate::block::make_register;
-use crate::block::simple::cost;
use crate::data::{DataRead, ReadError};
-make_register! {
- "duo" -> ItemTurret::new(1, true, cost!(Copper: 35));
- "scatter" -> ItemTurret::new(2, true, cost!(Copper: 85, Lead: 45));
- "scorch" -> ItemTurret::new(1, true, cost!(Copper: 25, Graphite: 22));
- "hail" -> ItemTurret::new(1, true, cost!(Copper: 40, Graphite: 17));
- "wave" -> Turret::new(2, true, cost!(Copper: 25, Lead: 75, Metaglass: 45));
- "tsunami" -> Turret::new(3, true, cost!(Lead: 400, Metaglass: 100, Titanium: 250, Thorium: 100));
- "lancer" -> Turret::new(2, true, cost!(Copper: 60, Lead: 70, Titanium: 30, Silicon: 60));
- "arc" -> Turret::new(1, true, cost!(Copper: 50, Lead: 50));
- "parallax" -> TractorBeamTurret::new(2, true, cost!(Graphite: 30, Titanium: 90, Silicon: 120));
- "swarmer" -> ItemTurret::new(2, true, cost!(Graphite: 35, Titanium: 35, Silicon: 30, Plastanium: 45));
- "salvo" -> ItemTurret::new(2, true, cost!(Copper: 100, Graphite: 80, Titanium: 50));
- "segment" -> PointDefenseTurret::new(2, true, cost!(Titanium: 40, Thorium: 80, Silicon: 130, PhaseFabric: 40));
- "fuse" -> ItemTurret::new(3, true, cost!(Copper: 225, Graphite: 225, Thorium: 100));
- "ripple" -> ItemTurret::new(3, true, cost!(Copper: 150, Graphite: 135, Titanium: 60));
- "cyclone" -> ItemTurret::new(3, true, cost!(Copper: 200, Titanium: 125, Plastanium: 80));
- "foreshadow" -> ItemTurret::new(4, true, cost!(Copper: 1000, Metaglass: 600, Silicon: 600, Plastanium: 200, SurgeAlloy: 300));
- "spectre" -> ItemTurret::new(4, true, cost!(Copper: 900, Graphite: 300, Thorium: 250, Plastanium: 175, SurgeAlloy: 250));
- "meltdown" -> Turret::new(4, true, cost!(Copper: 1200, Lead: 350, Graphite: 300, Silicon: 325, SurgeAlloy: 325));
- "breach" -> ItemTurret::new(3, true, cost!(Beryllium: 150, Silicon: 150, Graphite: 250));
- "diffuse" -> ItemTurret::new(3, true, cost!(Beryllium: 150, Silicon: 200, Graphite: 200, Tungsten: 50));
- "sublimate" -> ContinousTurret::new(3, true, cost!(Tungsten: 150, Silicon: 200, Oxide: 40, Beryllium: 400));
- "titan" -> ItemTurret::new(4, true, cost!(Tungsten: 250, Silicon: 300, Thorium: 400));
- "disperse" -> ItemTurret::new(4, true, cost!(Thorium: 50, Oxide: 150, Silicon: 200, Beryllium: 350));
- "afflict" -> Turret::new(4, true, cost!(SurgeAlloy: 100, Silicon: 200, Graphite: 250, Oxide: 40));
- "lustre" -> ContinousTurret::new(4, true, cost!(Silicon: 250, Graphite: 200, Oxide: 50, Carbide: 90));
- "scathe" -> ItemTurret::new(4, true, cost!(Oxide: 200, SurgeAlloy: 400, Silicon: 800, Carbide: 500, PhaseFabric: 300));
- "malign" -> Turret::new(5, true, cost!(Carbide: 400, Beryllium: 2000, Silicon: 800, Graphite: 800, PhaseFabric: 300));
- "smite" -> ItemTurret::new(5, true, cost!(Oxide: 200, SurgeAlloy: 400, Silicon: 800, Carbide: 500, PhaseFabric: 300));
-}
-
-make_simple!(Turret => |_, _, buff: &mut DataRead| read_turret(buff));
-make_simple!(PointDefenseTurret => |_, _, buff: &mut DataRead| read_point_defense_turret(buff));
-make_simple!(ContinousTurret => |_, _, buff: &mut DataRead| read_continous_turret(buff));
-make_simple!(TractorBeamTurret => |_, _, buff: &mut DataRead| read_tractor_beam_turret(buff));
-make_simple!(ItemTurret => |_, _, buff: &mut DataRead| read_item_turret(buff));
+make_simple!(Turret => |_, buff: &mut DataRead| read_turret(buff));
+make_simple!(PointDefenseTurret => |_, buff: &mut DataRead| read_point_defense_turret(buff));
+make_simple!(ContinousTurret => |_, buff: &mut DataRead| read_continous_turret(buff));
+make_simple!(TractorBeamTurret => |_, buff: &mut DataRead| read_tractor_beam_turret(buff));
+make_simple!(ItemTurret => |_, buff: &mut DataRead| read_item_turret(buff));
/// format:
/// - call [`read_turret`]
diff --git a/src/block/units.rs b/src/block/units.rs
index d482a2c..4af1a64 100644
--- a/src/block/units.rs
+++ b/src/block/units.rs
@@ -4,9 +4,9 @@ use thiserror::Error;
use super::payload::{read_payload_block, read_payload_seq};
use crate::block::simple::*;
use crate::data::command::UnitCommand;
-use crate::data::dynamic::{DynSerializer, DynType};
+use crate::data::dynamic::DynType;
use crate::unit;
-use crate::{block::*, Serializer};
+use crate::{block::*, Serializable};
// fn is_pay(b: &str) -> bool {
// matches!(
@@ -51,7 +51,7 @@ make_simple!(
};
base
},
- |_, reg, buff| read_assembler(reg, buff)
+ |_, buff| read_assembler(buff)
);
/// format:
@@ -61,8 +61,8 @@ make_simple!(
/// - read: [`i32`]
/// - call [`read_payload_seq`]
/// - point: ([`f32`], [`f32`]) (maybe [`NaN`](f32::NAN))
-fn read_assembler(reg: &BlockRegistry, buff: &mut DataRead) -> Result<(), DataReadError> {
- read_payload_block(reg, buff)?;
+fn read_assembler(buff: &mut DataRead) -> Result<(), DataReadError> {
+ read_payload_block(buff)?;
buff.skip(4)?;
let n = buff.read_u8()? as usize;
buff.skip(n * 4)?;
@@ -85,45 +85,19 @@ make_simple!(
};
base
},
- |_, reg, buff| read_payload_block(reg, buff)
+ |_, buff| read_payload_block(buff)
);
make_simple!(
- RepairTurret => |_, _, buff: &mut DataRead| {
+ RepairTurret => |_, buff: &mut DataRead| {
buff.skip(4) // rotation: [`f32`]
}
);
-const GROUND_UNITS: &[unit::Type] = &[unit::Type::Dagger, unit::Type::Crawler, unit::Type::Nova];
-const AIR_UNITS: &[unit::Type] = &[unit::Type::Flare, unit::Type::Mono];
-const NAVAL_UNITS: &[unit::Type] = &[unit::Type::Risso, unit::Type::Retusa];
-
-make_register! {
- "ground-factory" => UnitFactory::new(3, false, cost!(Copper: 50, Lead: 120, Silicon: 80), GROUND_UNITS);
- "air-factory" => UnitFactory::new(3, false, cost!(Copper: 60, Lead: 70), AIR_UNITS);
- "naval-factory" => UnitFactory::new(3, false, cost!(Copper: 150, Lead: 130, Metaglass: 120), NAVAL_UNITS);
- "additive-reconstructor" => ConstructorBlock::new(3, false, cost!(Copper: 200, Lead: 120, Silicon: 90));
- "multiplicative-reconstructor" => ConstructorBlock::new(5, false, cost!(Lead: 650, Titanium: 350, Thorium: 650, Silicon: 450));
- "exponential-reconstructor" => ConstructorBlock::new(7, false,
- cost!(Lead: 2000, Titanium: 2000, Thorium: 750, Silicon: 1000, Plastanium: 450, PhaseFabric: 600));
- "tetrative-reconstructor" => ConstructorBlock::new(9, false,
- cost!(Lead: 4000, Thorium: 1000, Silicon: 3000, Plastanium: 600, PhaseFabric: 600, SurgeAlloy: 800));
- "repair-point" -> RepairTurret::new(1, true, cost!(Copper: 30, Lead: 30, Silicon: 20));
- "repair-turret" -> RepairTurret::new(2, true, cost!(Thorium: 80, Silicon: 90, Plastanium: 60));
- "tank-fabricator" => UnitFactory::new(3, true, cost!(Silicon: 200, Beryllium: 150), &[unit::Type::Stell]);
- "ship-fabricator" => UnitFactory::new(3, true, cost!(Silicon: 250, Beryllium: 200), &[unit::Type::Elude]);
- "mech-fabricator" => UnitFactory::new(3, true, cost!(Silicon: 200, Graphite: 300, Tungsten: 60), &[unit::Type::Merui]);
- "tank-refabricator" => ConstructorBlock::new(3, true, cost!(Beryllium: 200, Tungsten: 80, Silicon: 100));
- "mech-refabricator" => ConstructorBlock::new(3, true, cost!(Beryllium: 250, Tungsten: 120, Silicon: 150));
- "ship-refabricator" => ConstructorBlock::new(3, true, cost!(Beryllium: 200, Tungsten: 100, Silicon: 150, Oxide: 40));
- "prime-refabricator" => ConstructorBlock::new(5, true, cost!(Thorium: 250, Oxide: 200, Tungsten: 200, Silicon: 400));
- "tank-assembler" => AssemblerBlock::new(5, true, cost!(Thorium: 500, Oxide: 150, Carbide: 80, Silicon: 500));
- "ship-assembler" => AssemblerBlock::new(5, true, cost!(Carbide: 100, Oxide: 200, Tungsten: 500, Silicon: 800, Thorium: 400));
- "mech-assembler" => AssemblerBlock::new(5, true, cost!(Carbide: 200, Thorium: 600, Oxide: 200, Tungsten: 500, Silicon: 900)); // smh collaris
- "basic-assembler-module" => AssemblerModule::new(5, true, cost!(Carbide: 300, Thorium: 500, Oxide: 200, PhaseFabric: 400)); // the dummy block
- "unit-repair-tower" -> BasicBlock::new(2, true, cost!(Graphite: 90, Silicon: 90, Tungsten: 80));
-
-}
+pub const GROUND_UNITS: &[unit::Type] =
+ &[unit::Type::Dagger, unit::Type::Crawler, unit::Type::Nova];
+pub const AIR_UNITS: &[unit::Type] = &[unit::Type::Flare, unit::Type::Mono];
+pub const NAVAL_UNITS: &[unit::Type] = &[unit::Type::Risso, unit::Type::Retusa];
pub struct ConstructorBlock {
size: u8,
@@ -230,16 +204,11 @@ impl BlockLogic for ConstructorBlock {
/// - progress: [`f32`]
/// - point: ([`f32`], [`f32`]) (maybe [`NaN`](f32::NAN))
/// - command: [`DynData::UnitCommand`]
- fn read(
- &self,
- _: &mut Build,
- reg: &BlockRegistry,
- buff: &mut DataRead,
- ) -> Result<(), DataReadError> {
- read_payload_block(reg, buff)?;
+ fn read(&self, _: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
+ read_payload_block(buff)?;
buff.skip(12)?;
- self.deserialize_state(DynSerializer.deserialize(buff).unwrap())
- .unwrap();
+ // self.deserialize_state(DynData::deserialize(buff).unwrap())
+ // .unwrap();
Ok(())
}
}
@@ -351,13 +320,8 @@ impl BlockLogic for UnitFactory {
/// - progress: [`f32`]
/// - plan: [`u16`]
/// - point: ([`f32`], [`f32`]) (maybe [`NaN`](f32::NAN))
- fn read(
- &self,
- _: &mut Build,
- reg: &BlockRegistry,
- buff: &mut DataRead,
- ) -> Result<(), DataReadError> {
- read_payload_block(reg, buff)?;
+ fn read(&self, _: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
+ read_payload_block(buff)?;
buff.skip(14)
}
}
diff --git a/src/block/walls.rs b/src/block/walls.rs
index 6b14cda..018d7d8 100644
--- a/src/block/walls.rs
+++ b/src/block/walls.rs
@@ -10,39 +10,6 @@ make_simple!(WallBlock, |_, _, _, _, _, s| {
base
});
-make_register! {
- "copper-wall" -> WallBlock::new(1, true, cost!(Copper: 6));
- "copper-wall-large" -> WallBlock::new(2, true, cost!(Copper: 6 * 4));
- "titanium-wall" -> WallBlock::new(1, true, cost!(Titanium: 6));
- "titanium-wall-large" -> WallBlock::new(2, true, cost!(Titanium: 6 * 4));
- "plastanium-wall" -> WallBlock::new(1, true, cost!(Metaglass: 2, Plastanium: 5));
- "plastanium-wall-large" -> WallBlock::new(2, true, cost!(Metaglass: 2 * 4, Plastanium: 5 * 4));
- "thorium-wall" -> WallBlock::new(1, true, cost!(Thorium: 6));
- "thorium-wall-large" -> WallBlock::new(2, true, cost!(Thorium: 6 * 4));
- "phase-wall" -> WallBlock::new(1, true, cost!(PhaseFabric: 6));
- "phase-wall-large" -> WallBlock::new(2, true, cost!(PhaseFabric: 6 * 4));
- "surge-wall" -> WallBlock::new(1, true, cost!(SurgeAlloy: 6));
- "surge-wall-large" -> WallBlock::new(2, true, cost!(SurgeAlloy: 6 * 4));
- "door" => DoorBlock::new(1, true, cost!(Titanium: 6, Silicon: 4));
- "door-large" => DoorBlock::new(2, true, cost!(Titanium: 6 * 4, Silicon: 4 * 4));
- "tungsten-wall" -> WallBlock::new(1, true, cost!(Tungsten: 6));
- "tungsten-wall-large" -> WallBlock::new(2, true, cost!(Tungsten: 6 * 4));
- "blast-door" -> DoorBlock::new(2, true, cost!(Tungsten: 24, Silicon: 24));
- "reinforced-surge-wall" -> WallBlock::new(1, true, cost!(SurgeAlloy: 6, Tungsten: 2));
- "reinforced-surge-wall-large" -> WallBlock::new(2, true, cost!(SurgeAlloy: 6 * 4, Tungsten: 2 * 4));
- "carbide-wall" -> WallBlock::new(1, true, cost!(Thorium: 6, Carbide: 6));
- "carbide-wall-large" -> WallBlock::new(2, true, cost!(Thorium: 6 * 4, Carbide: 6 * 4));
- "shielded-wall" -> WallBlock::new(2, true, cost!(PhaseFabric: 20, SurgeAlloy: 12, Beryllium: 12));
- "beryllium-wall" -> WallBlock::new(1, true, cost!(Beryllium: 6));
- "beryllium-wall-large" -> WallBlock::new(2, true, cost!(Beryllium: 6 * 4));
- // sandbox only
- "scrap-wall" -> WallBlock::new(1, true, cost!(Scrap: 6));
- "scrap-wall-large" -> WallBlock::new(2, true, cost!(Scrap: 24));
- "scrap-wall-huge" -> WallBlock::new(3, true, cost!(Scrap: 54));
- "scrap-wall-gigantic" -> WallBlock::new(4, true, cost!(Scrap: 96));
- "thruster" => WallBlock::new(4, false, cost!(Scrap: 96));
-}
-
pub struct DoorBlock {
size: u8,
symmetric: bool,
@@ -105,12 +72,7 @@ impl BlockLogic for DoorBlock {
Ok(DynData::Boolean(*state))
}
- fn read(
- &self,
- build: &mut Build,
- _: &BlockRegistry,
- buff: &mut DataRead,
- ) -> Result<(), DataReadError> {
+ fn read(&self, build: &mut Build, buff: &mut DataRead) -> Result<(), DataReadError> {
build.state = Some(Self::create_state(buff.read_bool()?));
Ok(())
}
diff --git a/src/data/autotile.rs b/src/data/autotile.rs
index 92ef1b4..59a6010 100644
--- a/src/data/autotile.rs
+++ b/src/data/autotile.rs
@@ -24,10 +24,7 @@ macro_rules! conv {
None
};
($dir:tt) => {
- Some((
- &crate::block::distribution::CONVEYOR,
- crate::data::autotile::dir!($dir),
- ))
+ Some((&crate::block::CONVEYOR, crate::data::autotile::dir!($dir)))
};
}
#[cfg(test)]
@@ -236,12 +233,9 @@ pub trait Crossable {
#[test]
fn test_cross() {
- let mut reg = crate::block::BlockRegistry::default();
- crate::block::distribution::register(&mut reg);
- let mut ss = super::schematic::SchematicSerializer(&reg);
macro_rules! test {
($schem: literal => $($a:tt,$b:tt,$c:tt,$d:tt)*) => {
- let s = ss.deserialize_base64($schem).unwrap();
+ let s = crate::Schematic::deserialize_base64($schem).unwrap();
let mut c = vec![];
println!("{:#?}", s.blocks);
for (position, _) in s.block_iter() {
diff --git a/src/data/dynamic.rs b/src/data/dynamic.rs
index 344144b..8fd5e80 100644
--- a/src/data/dynamic.rs
+++ b/src/data/dynamic.rs
@@ -3,7 +3,7 @@ use thiserror::Error;
use crate::content;
use crate::data::command::{self, UnitCommand};
-use crate::data::{self, DataRead, DataWrite, GridPos, Serializer};
+use crate::data::{self, DataRead, DataWrite, GridPos, Serializable};
use crate::logic::LogicField;
use crate::team::Team;
@@ -106,13 +106,11 @@ pub enum DynType {
Team,
}
-pub struct DynSerializer;
-
-impl Serializer<DynData> for DynSerializer {
+impl Serializable for DynData {
type ReadError = ReadError;
type WriteError = WriteError;
- fn deserialize(&mut self, buff: &mut DataRead<'_>) -> Result<DynData, Self::ReadError> {
+ fn deserialize(buff: &mut DataRead<'_>) -> Result<DynData, Self::ReadError> {
match buff.read_u8()? {
0 => Ok(DynData::Empty),
1 => Ok(DynData::from(buff.read_i32()?)),
@@ -203,12 +201,8 @@ impl Serializer<DynData> for DynSerializer {
}
}
- fn serialize(
- &mut self,
- buff: &mut DataWrite<'_>,
- data: &DynData,
- ) -> Result<(), Self::WriteError> {
- match data {
+ fn serialize(&self, buff: &mut DataWrite<'_>) -> Result<(), Self::WriteError> {
+ match self {
DynData::Empty => {
buff.write_u8(0)?;
Ok(())
@@ -416,7 +410,7 @@ mod test {
let mut writer = DataWrite::default();
for (i, d) in input.iter().enumerate()
{
- assert_eq!(DynSerializer.serialize(&mut writer, d), Ok(()));
+ assert_eq!(d.serialize(&mut writer), Ok(()));
positions[i] = writer.get_written().len();
}
let written = writer.get_written();
@@ -424,7 +418,7 @@ mod test {
let mut reader = DataRead::new(written);
for (i, original) in input.iter().enumerate()
{
- match DynSerializer.deserialize(&mut reader)
+ match DynData::deserialize(&mut reader)
{
Ok(read) => assert_eq!(*original, read, "serialization of {original:?} became {read:?}"),
e => assert!(false, "could not re-read {original:?} (at {i}), got {e:?}"),
diff --git a/src/data/map.rs b/src/data/map.rs
index f515687..edb3cb2 100644
--- a/src/data/map.rs
+++ b/src/data/map.rs
@@ -74,8 +74,8 @@ use std::ops::{Index, IndexMut};
use thiserror::Error;
use crate::block::content::Type as BlockEnum;
-use crate::block::{Block, BlockRegistry, Rotation, State};
-use crate::data::dynamic::DynSerializer;
+use crate::block::{Block, Rotation, State, BLOCK_REGISTRY};
+use crate::data::dynamic::DynData;
use crate::data::renderer::*;
use crate::data::DataRead;
use crate::fluid::Type as Fluid;
@@ -84,7 +84,7 @@ use crate::team::{self, Team};
#[cfg(doc)]
use crate::{block::content, data::*, fluid, item, modifier, unit};
-use super::Serializer;
+use super::Serializable;
use crate::content::Content;
use crate::utils::image::ImageUtils;
@@ -304,7 +304,7 @@ impl<'l> Build<'l> {
self.block.name()
}
- pub fn read(&mut self, buff: &mut DataRead<'_>, reg: &BlockRegistry) -> Result<(), ReadError> {
+ pub fn read(&mut self, buff: &mut DataRead<'_>) -> Result<(), ReadError> {
// health
let _ = buff.read_f32()?;
let rot = buff.read_i8()? as i16;
@@ -338,7 +338,7 @@ impl<'l> Build<'l> {
buff.skip(4)?;
}
// "overridden by subclasses"
- self.block.read(self, reg, buff)?;
+ self.block.read(self, buff)?;
// implementation not complete, simply error, causing the remaining bytes in the chunk to be skipped (TODO finish impl)
Err(ReadError::Version(0x0))
// Ok(())
@@ -526,8 +526,7 @@ pub enum ReadError {
}
/// serde map
-pub struct MapSerializer<'l>(pub &'l BlockRegistry<'l>);
-impl<'l> Serializer<Map<'l>> for MapSerializer<'l> {
+impl<'l> Serializable for Map<'l> {
type ReadError = ReadError;
type WriteError = ();
/// deserialize a map
@@ -535,7 +534,7 @@ impl<'l> Serializer<Map<'l>> for MapSerializer<'l> {
/// notes:
/// - does not deserialize data
/// - does not deserialize entities
- fn deserialize(&mut self, buff: &mut DataRead<'_>) -> Result<Map<'l>, Self::ReadError> {
+ fn deserialize(buff: &mut DataRead<'_>) -> Result<Map<'l>, Self::ReadError> {
let buff = buff.deflate()?;
let mut buff = DataRead::new(&buff);
{
@@ -599,7 +598,7 @@ impl<'l> Serializer<Map<'l>> for MapSerializer<'l> {
None
} else {
Some(
- self.0
+ BLOCK_REGISTRY
.get(block.get_name())
.ok_or_else(|| ReadError::NoSuchBlock(block.to_string()))?,
)
@@ -616,7 +615,7 @@ impl<'l> Serializer<Map<'l>> for MapSerializer<'l> {
println!("reading {:?}", map[i].build.as_ref().unwrap());
let _ = buff.read_i8()?;
- map[i].build.as_mut().unwrap().read(buff, self.0)?;
+ map[i].build.as_mut().unwrap().read(buff)?;
Ok::<(), ReadError>(())
});
}
@@ -650,7 +649,7 @@ impl<'l> Serializer<Map<'l>> for MapSerializer<'l> {
buff.skip(4)?;
for _ in 0..buff.read_u32()? {
buff.skip(8usize)?;
- let _ = DynSerializer::deserialize(&mut DynSerializer, buff)?;
+ let _ = DynData::deserialize(buff)?;
}
}
// read world entities (#412). eg units
@@ -667,11 +666,7 @@ impl<'l> Serializer<Map<'l>> for MapSerializer<'l> {
/// serialize a map (todo)
/// panics: always
- fn serialize(
- &mut self,
- _: &mut super::DataWrite<'_>,
- _: &Map<'_>,
- ) -> Result<(), Self::WriteError> {
- todo!()
+ fn serialize(&self, _: &mut super::DataWrite<'_>) -> Result<(), Self::WriteError> {
+ unimplemented!()
}
}
diff --git a/src/data/mod.rs b/src/data/mod.rs
index 3eccbd1..85cbbd6 100644
--- a/src/data/mod.rs
+++ b/src/data/mod.rs
@@ -455,13 +455,16 @@ impl<'d> TryFrom<DataWrite<'d>> for Vec<u8> {
}
}
/// basic serialization/deserialization functions
-pub trait Serializer<D> {
+pub trait Serializable
+where
+ Self: Sized,
+{
type ReadError;
type WriteError;
-
- fn deserialize(&mut self, buff: &mut DataRead<'_>) -> Result<D, Self::ReadError>;
-
- fn serialize(&mut self, buff: &mut DataWrite<'_>, data: &D) -> Result<(), Self::WriteError>;
+ /// deserialize self from a binary buffer
+ fn deserialize(buff: &mut DataRead<'_>) -> Result<Self, Self::ReadError>;
+ /// transform self into a binary buffer
+ fn serialize(&self, buff: &mut DataWrite<'_>) -> Result<(), Self::WriteError>;
}
#[derive(Clone, Copy, Eq, PartialEq)]
diff --git a/src/data/renderer.rs b/src/data/renderer.rs
index ba578b1..5625212 100644
--- a/src/data/renderer.rs
+++ b/src/data/renderer.rs
@@ -94,11 +94,12 @@ pub trait Renderable {
impl Renderable for Schematic<'_> {
/// creates a picture of a schematic. Bridges and node connections are not drawn.
/// ```
- /// use mindus::*;
+ /// # use mindus::*;
+ /// # use mindus::block::*;
/// let mut s = Schematic::new(2, 3);
- /// s.put(0, 0, &block::distribution::DISTRIBUTOR);
- /// s.put(0, 2, &block::distribution::ROUTER);
- /// s.put(1, 2, &block::walls::COPPER_WALL);
+ /// s.put(0, 0, &DISTRIBUTOR);
+ /// s.put(0, 2, &ROUTER);
+ /// s.put(1, 2, &COPPER_WALL);
/// let output /*: Image */ = s.render();
/// ```
fn render(&self) -> Image<Vec<u8>, 3> {
@@ -245,7 +246,6 @@ impl Renderable for Map<'_> {
fn all_blocks() {
use crate::block::content::Type;
use crate::content::Content;
- let reg = crate::block::build_registry();
for t in 19..Type::WorldMessage as u16 {
let t = Type::try_from(t).unwrap();
if matches!(t, |Type::Empty| Type::SlagCentrifuge
@@ -259,7 +259,7 @@ fn all_blocks() {
continue;
}
let name = dbg!(t.get_name());
- let t = reg.get(name).unwrap();
+ let t = crate::block::BLOCK_REGISTRY.get(name).unwrap();
let _ = t.image(
None,
Some(&RenderingContext {
diff --git a/src/data/schematic.rs b/src/data/schematic.rs
index 7ad2a67..d324d7f 100644
--- a/src/data/schematic.rs
+++ b/src/data/schematic.rs
@@ -4,13 +4,12 @@ use std::collections::HashMap;
use std::fmt::{self, Write};
use thiserror::Error;
-use crate::block::{self, Block, BlockRegistry, Rotation, State};
+use crate::block::{self, Block, Rotation, State, BLOCK_REGISTRY};
use crate::data::base64;
-use crate::data::dynamic::{self, DynData, DynSerializer};
+use crate::data::dynamic::{self, DynData};
use crate::data::renderer::*;
-use crate::data::{self, DataRead, DataWrite, GridPos, Serializer};
+use crate::data::{self, DataRead, DataWrite, GridPos, Serializable};
use crate::item::storage::ItemStorage;
-use crate::registry::RegistryEntry;
use crate::utils::array::Array2D;
/// biggest schematic
@@ -232,10 +231,11 @@ impl<'l> Schematic<'l> {
/// ```
/// # use mindus::Schematic;
/// # use mindus::block::Rotation;
+ /// # use mindus::block::DUO;
///
/// let mut s = Schematic::new(5, 5);
/// assert!(s.get(0, 0).unwrap().is_none());
- /// s.put(0, 0, &mindus::block::turrets::DUO);
+ /// s.put(0, 0, &DUO);
/// assert!(s.get(0, 0).unwrap().is_some());
/// ```
pub fn get(&self, x: usize, y: usize) -> Result<Option<&Placement<'l>>, PosError> {
@@ -266,9 +266,10 @@ impl<'l> Schematic<'l> {
/// put a block in (same as [`Schematic::set`], but less arguments and builder-ness). panics!!!
/// ```
/// # use mindus::Schematic;
+ /// # use mindus::block::ROUTER;
///
/// let mut s = Schematic::new(5, 5);
- /// s.put(0, 0, &mindus::block::distribution::ROUTER);
+ /// s.put(0, 0, &ROUTER);
/// assert!(s.get(0, 0).unwrap().is_some() == true);
/// ```
pub fn put(&mut self, x: usize, y: usize, block: &'l Block) -> &mut Self {
@@ -279,11 +280,12 @@ impl<'l> Schematic<'l> {
/// set a block
/// ```
/// # use mindus::Schematic;
- /// # use mindus::DynData;
+ /// # use mindus::data::dynamic::DynData;
/// # use mindus::block::Rotation;
+ /// # use mindus::block::ROUTER;
///
/// let mut s = Schematic::new(5, 5);
- /// s.set(0, 0, &mindus::block::distribution::ROUTER, DynData::Empty, Rotation::Right);
+ /// s.set(0, 0, &ROUTER, DynData::Empty, Rotation::Right);
/// assert!(s.get(0, 0).unwrap().is_some() == true);
/// ```
pub fn set(
@@ -323,12 +325,11 @@ impl<'l> Schematic<'l> {
/// take out a block
/// ```
/// # use mindus::Schematic;
- /// # use mindus::DynData;
-
+ /// # use mindus::block::DUO;
/// # use mindus::block::Rotation;
///
/// let mut s = Schematic::new(5, 5);
- /// s.put(0, 0, &mindus::block::turrets::DUO);
+ /// s.put(0, 0, &DUO);
/// assert!(s.get(0, 0).unwrap().is_some() == true);
/// assert!(s.take(0, 0).unwrap().is_some() == true);
/// assert!(s.get(0, 0).unwrap().is_none() == true);
@@ -361,11 +362,11 @@ impl<'l> Schematic<'l> {
/// returns (cost, `is_sandbox`)
/// ```
/// # use mindus::Schematic;
- /// # use mindus::DynData;
/// # use mindus::block::Rotation;
+ /// # use mindus::block::CYCLONE;
///
/// let mut s = Schematic::new(5, 5);
- /// s.put(1, 1, &mindus::block::turrets::CYCLONE);
+ /// s.put(1, 1, &CYCLONE);
/// assert_eq!(s.compute_total_cost().0.get_total(), 405);
/// ```
pub fn compute_total_cost(&self) -> (ItemStorage, bool) {
@@ -470,13 +471,10 @@ impl fmt::Display for TruncatedError {
const SCHEMATIC_HEADER: u32 =
((b'm' as u32) << 24) | ((b's' as u32) << 16) | ((b'c' as u32) << 8) | (b'h' as u32);
-/// `serde_schematic`
-pub struct SchematicSerializer<'l>(pub &'l BlockRegistry<'l>);
-
-impl<'l> Serializer<Schematic<'l>> for SchematicSerializer<'l> {
+impl<'l> Serializable for Schematic<'l> {
type ReadError = ReadError;
type WriteError = WriteError;
- fn deserialize(&mut self, buff: &mut DataRead<'_>) -> Result<Schematic<'l>, Self::ReadError> {
+ fn deserialize(buff: &mut DataRead<'_>) -> Result<Schematic<'l>, Self::ReadError> {
let hdr = buff.read_u32()?;
if hdr != SCHEMATIC_HEADER {
return Err(ReadError::Header(hdr));
@@ -502,7 +500,7 @@ impl<'l> Serializer<Schematic<'l>> for SchematicSerializer<'l> {
block_table.reserve(num_table as usize);
for _ in 0..num_table {
let name = buff.read_utf()?;
- match self.0.get(name) {
+ match BLOCK_REGISTRY.get(name) {
None => return Err(ReadError::NoSuchBlock(name.to_owned())),
Some(b) => block_table.push(b),
}
@@ -521,7 +519,7 @@ impl<'l> Serializer<Schematic<'l>> for SchematicSerializer<'l> {
let config = if version < 1 {
block.data_from_i32(buff.read_i32()?, pos)?
} else {
- DynSerializer.deserialize(&mut buff)?
+ DynData::deserialize(&mut buff)?
};
let rot = Rotation::from(buff.read_u8()?);
schematic.set(pos.0, pos.1, block, config, rot)?;
@@ -529,24 +527,20 @@ impl<'l> Serializer<Schematic<'l>> for SchematicSerializer<'l> {
Ok(schematic)
}
- fn serialize(
- &mut self,
- buff: &mut DataWrite<'_>,
- data: &Schematic,
- ) -> Result<(), Self::WriteError> {
+ fn serialize(&self, buff: &mut DataWrite<'_>) -> Result<(), Self::WriteError> {
// write the header first just in case
buff.write_u32(SCHEMATIC_HEADER)?;
buff.write_u8(1)?;
let mut rbuff = DataWrite::default();
// don't have to check dimensions because they're already limited to MAX_DIMENSION
- rbuff.write_i16(data.width as i16)?;
- rbuff.write_i16(data.height as i16)?;
- if data.tags.len() > u8::MAX as usize {
- return Err(WriteError::TagCount(data.tags.len()));
+ rbuff.write_i16(self.width as i16)?;
+ rbuff.write_i16(self.height as i16)?;
+ if self.tags.len() > u8::MAX as usize {
+ return Err(WriteError::TagCount(self.tags.len()));
}
- rbuff.write_u8(data.tags.len() as u8)?;
- for (k, v) in &data.tags {
+ rbuff.write_u8(self.tags.len() as u8)?;
+ for (k, v) in &self.tags {
rbuff.write_utf(k)?;
rbuff.write_utf(v)?;
}
@@ -554,11 +548,11 @@ impl<'l> Serializer<Schematic<'l>> for SchematicSerializer<'l> {
let mut block_map = HashMap::new();
let mut block_table = Vec::new();
let mut block_count = 0i32;
- for curr in data.blocks.iter().filter_map(|b| b.as_ref()) {
+ for curr in self.blocks.iter().filter_map(|b| b.as_ref()) {
block_count += 1;
- if let Entry::Vacant(e) = block_map.entry(curr.block.get_name()) {
+ if let Entry::Vacant(e) = block_map.entry(curr.block.name()) {
e.insert(block_table.len() as u32);
- block_table.push(curr.block.get_name());
+ block_table.push(curr.block.name());
}
}
if block_table.len() > i8::MAX as usize {
@@ -571,14 +565,14 @@ impl<'l> Serializer<Schematic<'l>> for SchematicSerializer<'l> {
}
// don't have to check data.blocks.len() because dimensions don't allow exceeding MAX_BLOCKS
rbuff.write_i32(block_count)?;
- for (pos, curr) in data.block_iter() {
- rbuff.write_i8(block_map[curr.block.get_name()] as i8)?;
+ for (pos, curr) in self.block_iter() {
+ rbuff.write_i8(block_map[curr.block.name()] as i8)?;
rbuff.write_u32(pos.into())?;
let data = match curr.state {
None => DynData::Empty,
Some(ref s) => curr.block.serialize_state(s)?,
};
- DynSerializer.serialize(&mut rbuff, &data)?;
+ data.serialize(&mut rbuff)?;
rbuff.write_u8(curr.rot.into())?;
}
rbuff.inflate(buff)?;
@@ -630,26 +624,24 @@ pub enum WriteError {
Compress(#[from] super::CompressError),
}
-impl<'l> SchematicSerializer<'l> {
+impl<'l> Schematic<'l> {
/// deserializes a schematic from base64
/// ```
/// # use mindus::*;
/// let string = "bXNjaAF4nGNgZmBmZmDJS8xNZeBOyslPzlYAkwzcKanFyUWZBSWZ+XkMDAxsOYlJqTnFDEzRsYwMfAWJlTn5iSm6RfmlJalFQGlGEGJkZWSYxQAAcBkUPA==";
- /// let reg = build_registry();
- /// let mut ss = SchematicSerializer(&reg);
- /// let s = ss.deserialize_base64(string).unwrap();
+ /// let s = Schematic::deserialize_base64(string).unwrap();
/// assert!(s.get(1, 1).unwrap().unwrap().block.name() == "payload-router");
/// ```
- pub fn deserialize_base64(&mut self, data: &str) -> Result<Schematic<'l>, R64Error> {
+ pub fn deserialize_base64(data: &str) -> Result<Schematic<'l>, R64Error> {
let mut buff = vec![0; data.len() / 4 * 3 + 1];
let n_out = base64::decode(data.as_bytes(), buff.as_mut())?;
- Ok(self.deserialize(&mut DataRead::new(&buff[..n_out]))?)
+ Ok(Self::deserialize(&mut DataRead::new(&buff[..n_out]))?)
}
/// serialize a schematic to base64
- pub fn serialize_base64(&mut self, data: &Schematic<'l>) -> Result<String, W64Error> {
+ pub fn serialize_base64(&self) -> Result<String, W64Error> {
let mut buff = DataWrite::default();
- self.serialize(&mut buff, data)?;
+ self.serialize(&mut buff)?;
let buff = buff.get_written();
// round up because of padding
let mut text = vec![0; 4 * (buff.len() / 3 + usize::from(buff.len() % 3 != 0))];
@@ -703,14 +695,12 @@ mod test {
($name:ident, $($val:expr);+;) => {
#[test]
fn $name() {
- let reg = crate::block::build_registry();
- let mut ser = SchematicSerializer(&reg);
$(
- let parsed = unwrap_pretty(ser.deserialize_base64($val));
+ let parsed = unwrap_pretty(Schematic::deserialize_base64($val));
println!("\x1b[38;5;2mdeserialized\x1b[0m {}", parsed.tags.get("name").unwrap());
- let unparsed = unwrap_pretty(ser.serialize_base64(&parsed));
+ let unparsed = unwrap_pretty(parsed.serialize_base64());
println!("\x1b[38;5;2mserialized\x1b[0m {}", parsed.tags.get("name").unwrap());
- let parsed2 = unwrap_pretty(ser.deserialize_base64(&unparsed));
+ let parsed2 = unwrap_pretty(Schematic::deserialize_base64(&unparsed));
println!("\x1b[38;5;2mredeserialized\x1b[0m {}", parsed.tags.get("name").unwrap());
if parsed != parsed2 {
#[cfg(feature = "bin")]
@@ -752,7 +742,7 @@ mod test {
None
};
}
- use crate::block::all::*;
+ use crate::block::*;
let mut s = Schematic::new(3, 3);
s.put(0, 0, &DISTRIBUTOR)
.put(0, 1, &JUNCTION)
@@ -768,10 +758,7 @@ mod test {
pair!(2, 0, ROUTER);
pair!( );
];
- let reg = crate::block::build_registry();
- let mut s = SchematicSerializer(&reg);
-
- let s = s.deserialize_base64("bXNjaAF4nDXKywqAIBQA0fFRBH1itDC7C8E01IT+vgia1VkMFmOwyR3C0N0VG/Mu1ZdwtpATMEa3SazoZdVMPqcudy7/DJovpV4peAAt0xF6").unwrap();
+ let s = Schematic::deserialize_base64("bXNjaAF4nDXKywqAIBQA0fFRBH1itDC7C8E01IT+vgia1VkMFmOwyR3C0N0VG/Mu1ZdwtpATMEa3SazoZdVMPqcudy7/DJovpV4peAAt0xF6").unwrap();
let mut it = s.block_iter();
test_iter![it,
pair!(0, 0, CONVEYOR);
diff --git a/src/exe/draw.rs b/src/exe/draw.rs
index 964bcac..c23703f 100644
--- a/src/exe/draw.rs
+++ b/src/exe/draw.rs
@@ -1,17 +1,13 @@
-use mindus::build_registry;
use mindus::Renderable;
-use mindus::SchematicSerializer;
+use mindus::Schematic;
use std::env::Args;
use crate::print_err;
pub fn main(args: Args) {
- let reg = build_registry();
- let mut ss = SchematicSerializer(&reg);
-
// process schematics from command line
for curr in args {
- match ss.deserialize_base64(&curr) {
+ match Schematic::deserialize_base64(&curr) {
Ok(s) => {
s.render().save("x.png");
}
diff --git a/src/exe/map.rs b/src/exe/map.rs
index cbb6477..9c879ee 100644
--- a/src/exe/map.rs
+++ b/src/exe/map.rs
@@ -1,13 +1,11 @@
use mindus::data::DataRead;
-use mindus::{build_registry, Renderable};
-use mindus::{MapSerializer, Serializer};
+use mindus::Renderable;
+use mindus::{Map, Serializable};
use std::env::Args;
use std::time::Instant;
use super::print_err;
pub fn main(args: Args) {
- let reg = build_registry();
- let mut ms = MapSerializer(&reg);
let runs = std::env::var("RUNS").map_or(10u8, |x| x.parse().unwrap_or(10u8));
// process schematics from command line
@@ -18,7 +16,7 @@ pub fn main(args: Args) {
continue;
};
let starting_deser = Instant::now();
- match ms.deserialize(&mut DataRead::new(&s)) {
+ match Map::deserialize(&mut DataRead::new(&s)) {
Err(e) => print_err!(e, "fail"),
Ok(m) => {
let deser_took = starting_deser.elapsed();
diff --git a/src/lib.rs b/src/lib.rs
index 1a8c302..c68b69a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -15,18 +15,8 @@ pub mod fluid;
pub mod item;
mod logic;
pub mod modifier;
-mod registry;
mod team;
pub mod unit;
mod utils;
#[doc(inline)]
-pub use {
- block::build_registry,
- data::{
- dynamic::DynData,
- map::{Map, MapSerializer},
- renderer::Renderable,
- schematic::{Schematic, SchematicSerializer},
- Serializer,
- },
-};
+pub use data::{map::Map, renderer::Renderable, schematic::Schematic, Serializable};
diff --git a/src/registry.rs b/src/registry.rs
deleted file mode 100644
index 9603f59..0000000
--- a/src/registry.rs
+++ /dev/null
@@ -1,51 +0,0 @@
-use std::any::type_name;
-use std::collections::hash_map::Entry;
-use std::collections::HashMap;
-use std::error::Error;
-use std::fmt;
-
-pub trait RegistryEntry {
- fn get_name(&self) -> &str;
-}
-
-pub struct Registry<'l, E: RegistryEntry + fmt::Debug + 'static> {
- by_name: HashMap<&'l str, &'l E>,
-}
-
-impl<'l, E: RegistryEntry + fmt::Debug + 'static> Default for Registry<'l, E> {
- fn default() -> Self {
- Self {
- by_name: HashMap::new(),
- }
- }
-}
-
-impl<'l, E: RegistryEntry + fmt::Debug + 'static> Registry<'l, E> {
- pub fn register(&mut self, val: &'l E) -> Result<&'l E, RegisterError<'l, E>> {
- match self.by_name.entry(val.get_name()) {
- Entry::Occupied(e) => Err(RegisterError(e.get())),
- Entry::Vacant(e) => Ok(e.insert(val)),
- }
- }
-
- #[must_use]
- pub fn get(&self, name: &str) -> Option<&'l E> {
- self.by_name.get(name).copied()
- }
-}
-
-#[derive(Clone, Copy, Debug)]
-pub struct RegisterError<'l, E: RegistryEntry + fmt::Debug + 'static>(pub &'l E);
-
-impl<'l, E: RegistryEntry + fmt::Debug + 'static> fmt::Display for RegisterError<'l, E> {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "{} {:?} already exists",
- type_name::<E>(),
- self.0.get_name()
- )
- }
-}
-
-impl<'l, E: RegistryEntry + fmt::Debug + 'static> Error for RegisterError<'l, E> {}
diff --git a/src/unit/mod.rs b/src/unit/mod.rs
index f96f5a3..b6db959 100644
--- a/src/unit/mod.rs
+++ b/src/unit/mod.rs
@@ -3,13 +3,13 @@
//! [source](https://github.com/Anuken/Mindustry/blob/master/core/src/mindustry/content/UnitTypes.java)
use crate::content::content_enum;
use crate::data::command::UnitCommand;
-use crate::data::dynamic::DynSerializer;
+use crate::data::dynamic::DynData;
use crate::data::entity_mapping::UnitClass;
use crate::data::{DataRead, ReadError};
use crate::item::Type as Item;
use crate::modifier::Type as Status;
use crate::team::Team;
-use crate::Serializer;
+use crate::Serializable;
content_enum! {
pub enum Type / Unit for u16 | TryFromU16Error {
@@ -182,22 +182,26 @@ impl UnitClass {
state.flag = buff.read_i64()?;
state.health = buff.read_f32()?;
state.is_shooting = buff.read_bool()?;
- dbg!(&state);
- read_tile(buff)?;
- read_mounts(buff)?;
- read_plans(buff)?;
- state.rotation = buff.read_f32()?;
- state.shield = buff.read_f32()?;
- buff.skip(1)?; // spawned_by_core
- state.stack = read_stack(buff)?;
- state.status = read_status(buff)?;
- state.team = Team::of(buff.read_u8()?);
- let ty = Type::try_from(buff.read_u16()?).unwrap();
- buff.skip(1)?; // update_building
- state.velocity = (buff.read_f32()?, buff.read_f32()?);
- state.position = (buff.read_f32()?, buff.read_f32()?);
+ // TODO apparently i fucked up my impl
+ // dbg!(&state);
+ // read_tile(buff)?;
+ // read_mounts(buff)?;
+ // read_plans(buff)?;
+ // state.rotation = buff.read_f32()?;
+ // state.shield = buff.read_f32()?;
+ // buff.skip(1)?; // spawned_by_core
+ // state.stack = read_stack(buff)?;
+ // state.status = read_status(buff)?;
+ // state.team = Team::of(buff.read_u8()?);
+ // let ty = Type::try_from(buff.read_u16()?).unwrap();
+ // buff.skip(1)?; // update_building
+ // state.velocity = (buff.read_f32()?, buff.read_f32()?);
+ // state.position = (buff.read_f32()?, buff.read_f32()?);
- Ok(Unit { state, ty })
+ Ok(Unit {
+ state,
+ ty: Type::Alpha,
+ })
}
}
@@ -254,7 +258,7 @@ fn read_plan(buff: &mut DataRead) -> Result<(), ReadError> {
buff.skip(4)?;
if ty != 1 {
buff.skip(4)?;
- let _ = DynSerializer.deserialize(buff).unwrap();
+ let _ = DynData::deserialize(buff).unwrap();
}
Ok(())
}