mindustry logic execution, map- and schematic- parsing and rendering
-rw-r--r--Cargo.toml3
-rw-r--r--assets/blocks/environment/empty.pngbin81 -> 0 bytes
-rw-r--r--assets/blocks/liquid/conduits/conduit-0.png (renamed from assets/blocks/liquid/conduits/conduit-top-0.png)bin185 -> 185 bytes
-rw-r--r--assets/blocks/liquid/conduits/conduit-1.png (renamed from assets/blocks/liquid/conduits/conduit-top-1.png)bin243 -> 243 bytes
-rw-r--r--assets/blocks/liquid/conduits/conduit-2.png (renamed from assets/blocks/liquid/conduits/conduit-top-2.png)bin215 -> 215 bytes
-rw-r--r--assets/blocks/liquid/conduits/conduit-3.png (renamed from assets/blocks/liquid/conduits/conduit-top-3.png)bin219 -> 219 bytes
-rw-r--r--assets/blocks/liquid/conduits/conduit-4.png (renamed from assets/blocks/liquid/conduits/conduit-top-4.png)bin202 -> 202 bytes
-rw-r--r--assets/blocks/liquid/conduits/plated-conduit-0.png (renamed from assets/blocks/liquid/conduits/plated-conduit-top-0.png)bin210 -> 210 bytes
-rw-r--r--assets/blocks/liquid/conduits/plated-conduit-1.png (renamed from assets/blocks/liquid/conduits/plated-conduit-top-1.png)bin272 -> 272 bytes
-rw-r--r--assets/blocks/liquid/conduits/plated-conduit-2.png (renamed from assets/blocks/liquid/conduits/plated-conduit-top-2.png)bin227 -> 227 bytes
-rw-r--r--assets/blocks/liquid/conduits/plated-conduit-3.png (renamed from assets/blocks/liquid/conduits/plated-conduit-top-3.png)bin215 -> 215 bytes
-rw-r--r--assets/blocks/liquid/conduits/plated-conduit-4.png (renamed from assets/blocks/liquid/conduits/plated-conduit-top-4.png)bin228 -> 228 bytes
-rw-r--r--assets/blocks/liquid/conduits/pulse-conduit-0.png (renamed from assets/blocks/liquid/conduits/pulse-conduit-top-0.png)bin223 -> 223 bytes
-rw-r--r--assets/blocks/liquid/conduits/pulse-conduit-1.png (renamed from assets/blocks/liquid/conduits/pulse-conduit-top-1.png)bin297 -> 297 bytes
-rw-r--r--assets/blocks/liquid/conduits/pulse-conduit-2.png (renamed from assets/blocks/liquid/conduits/pulse-conduit-top-2.png)bin253 -> 253 bytes
-rw-r--r--assets/blocks/liquid/conduits/pulse-conduit-3.png (renamed from assets/blocks/liquid/conduits/pulse-conduit-top-3.png)bin263 -> 263 bytes
-rw-r--r--assets/blocks/liquid/conduits/pulse-conduit-4.png (renamed from assets/blocks/liquid/conduits/pulse-conduit-top-4.png)bin235 -> 235 bytes
-rw-r--r--assets/blocks/liquid/conduits/reinforced-conduit-0.png (renamed from assets/blocks/liquid/conduits/reinforced-conduit-top-0.png)bin219 -> 219 bytes
-rw-r--r--assets/blocks/liquid/conduits/reinforced-conduit-1.png (renamed from assets/blocks/liquid/conduits/reinforced-conduit-top-1.png)bin257 -> 257 bytes
-rw-r--r--assets/blocks/liquid/conduits/reinforced-conduit-2.png (renamed from assets/blocks/liquid/conduits/reinforced-conduit-top-2.png)bin219 -> 219 bytes
-rw-r--r--assets/blocks/liquid/conduits/reinforced-conduit-3.png (renamed from assets/blocks/liquid/conduits/reinforced-conduit-top-3.png)bin198 -> 198 bytes
-rw-r--r--assets/blocks/liquid/conduits/reinforced-conduit-4.png (renamed from assets/blocks/liquid/conduits/reinforced-conduit-top-4.png)bin244 -> 244 bytes
-rw-r--r--assets/blocks/production/heat-router-top1.pngbin0 -> 307 bytes
-rw-r--r--assets/blocks/production/heat-router-top2.pngbin0 -> 317 bytes
-rw-r--r--assets/blocks/production/heat-router.pngbin961 -> 959 bytes
-rw-r--r--build.rs55
-rw-r--r--src/block/campaign.rs4
-rw-r--r--src/block/defense.rs26
-rw-r--r--src/block/distribution.rs75
-rw-r--r--src/block/drills.rs34
-rw-r--r--src/block/environment.rs6
-rw-r--r--src/block/liquid.rs40
-rw-r--r--src/block/logic.rs49
-rw-r--r--src/block/mod.rs34
-rw-r--r--src/block/payload.rs94
-rw-r--r--src/block/power.rs83
-rw-r--r--src/block/production.rs89
-rw-r--r--src/block/simple.rs17
-rw-r--r--src/block/storage.rs22
-rw-r--r--src/block/turrets.rs20
-rw-r--r--src/block/units.rs134
-rw-r--r--src/block/walls.rs85
-rw-r--r--src/data/autotile.rs18
-rw-r--r--src/data/renderer.rs98
-rw-r--r--src/utils/image.rs4
45 files changed, 489 insertions, 501 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 8221619..371068c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "mindus"
-version = "2.0.0"
+version = "2.0.1"
edition = "2021"
description = "A library for working with mindustry data formats (eg schematics and maps) (fork of plandustry)"
authors = [
@@ -21,7 +21,6 @@ color-hex = "0.2"
thiserror = "1.0"
bobbin-bits = "0.1"
blurslice = { version = "0.1" }
-phf = { version = "0.11", features = ["macros"] }
[features]
bin = ["image/png"]
diff --git a/assets/blocks/environment/empty.png b/assets/blocks/environment/empty.png
deleted file mode 100644
index a994bf2..0000000
--- a/assets/blocks/environment/empty.png
+++ /dev/null
Binary files differ
diff --git a/assets/blocks/liquid/conduits/conduit-top-0.png b/assets/blocks/liquid/conduits/conduit-0.png
index 89e0a19..89e0a19 100644
--- a/assets/blocks/liquid/conduits/conduit-top-0.png
+++ b/assets/blocks/liquid/conduits/conduit-0.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/conduit-top-1.png b/assets/blocks/liquid/conduits/conduit-1.png
index dc86dd4..dc86dd4 100644
--- a/assets/blocks/liquid/conduits/conduit-top-1.png
+++ b/assets/blocks/liquid/conduits/conduit-1.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/conduit-top-2.png b/assets/blocks/liquid/conduits/conduit-2.png
index e8a7bb0..e8a7bb0 100644
--- a/assets/blocks/liquid/conduits/conduit-top-2.png
+++ b/assets/blocks/liquid/conduits/conduit-2.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/conduit-top-3.png b/assets/blocks/liquid/conduits/conduit-3.png
index 15b8dc2..15b8dc2 100644
--- a/assets/blocks/liquid/conduits/conduit-top-3.png
+++ b/assets/blocks/liquid/conduits/conduit-3.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/conduit-top-4.png b/assets/blocks/liquid/conduits/conduit-4.png
index 3d0f869..3d0f869 100644
--- a/assets/blocks/liquid/conduits/conduit-top-4.png
+++ b/assets/blocks/liquid/conduits/conduit-4.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/plated-conduit-top-0.png b/assets/blocks/liquid/conduits/plated-conduit-0.png
index 9b1dcd0..9b1dcd0 100644
--- a/assets/blocks/liquid/conduits/plated-conduit-top-0.png
+++ b/assets/blocks/liquid/conduits/plated-conduit-0.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/plated-conduit-top-1.png b/assets/blocks/liquid/conduits/plated-conduit-1.png
index 201ffa2..201ffa2 100644
--- a/assets/blocks/liquid/conduits/plated-conduit-top-1.png
+++ b/assets/blocks/liquid/conduits/plated-conduit-1.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/plated-conduit-top-2.png b/assets/blocks/liquid/conduits/plated-conduit-2.png
index 4a32d66..4a32d66 100644
--- a/assets/blocks/liquid/conduits/plated-conduit-top-2.png
+++ b/assets/blocks/liquid/conduits/plated-conduit-2.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/plated-conduit-top-3.png b/assets/blocks/liquid/conduits/plated-conduit-3.png
index ea24f9a..ea24f9a 100644
--- a/assets/blocks/liquid/conduits/plated-conduit-top-3.png
+++ b/assets/blocks/liquid/conduits/plated-conduit-3.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/plated-conduit-top-4.png b/assets/blocks/liquid/conduits/plated-conduit-4.png
index 5fd7ae2..5fd7ae2 100644
--- a/assets/blocks/liquid/conduits/plated-conduit-top-4.png
+++ b/assets/blocks/liquid/conduits/plated-conduit-4.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/pulse-conduit-top-0.png b/assets/blocks/liquid/conduits/pulse-conduit-0.png
index 09ee3e3..09ee3e3 100644
--- a/assets/blocks/liquid/conduits/pulse-conduit-top-0.png
+++ b/assets/blocks/liquid/conduits/pulse-conduit-0.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/pulse-conduit-top-1.png b/assets/blocks/liquid/conduits/pulse-conduit-1.png
index 170ffc9..170ffc9 100644
--- a/assets/blocks/liquid/conduits/pulse-conduit-top-1.png
+++ b/assets/blocks/liquid/conduits/pulse-conduit-1.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/pulse-conduit-top-2.png b/assets/blocks/liquid/conduits/pulse-conduit-2.png
index 35d1735..35d1735 100644
--- a/assets/blocks/liquid/conduits/pulse-conduit-top-2.png
+++ b/assets/blocks/liquid/conduits/pulse-conduit-2.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/pulse-conduit-top-3.png b/assets/blocks/liquid/conduits/pulse-conduit-3.png
index b7a411b..b7a411b 100644
--- a/assets/blocks/liquid/conduits/pulse-conduit-top-3.png
+++ b/assets/blocks/liquid/conduits/pulse-conduit-3.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/pulse-conduit-top-4.png b/assets/blocks/liquid/conduits/pulse-conduit-4.png
index 7958647..7958647 100644
--- a/assets/blocks/liquid/conduits/pulse-conduit-top-4.png
+++ b/assets/blocks/liquid/conduits/pulse-conduit-4.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/reinforced-conduit-top-0.png b/assets/blocks/liquid/conduits/reinforced-conduit-0.png
index 45bcdc2..45bcdc2 100644
--- a/assets/blocks/liquid/conduits/reinforced-conduit-top-0.png
+++ b/assets/blocks/liquid/conduits/reinforced-conduit-0.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/reinforced-conduit-top-1.png b/assets/blocks/liquid/conduits/reinforced-conduit-1.png
index e393c9c..e393c9c 100644
--- a/assets/blocks/liquid/conduits/reinforced-conduit-top-1.png
+++ b/assets/blocks/liquid/conduits/reinforced-conduit-1.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/reinforced-conduit-top-2.png b/assets/blocks/liquid/conduits/reinforced-conduit-2.png
index 5099798..5099798 100644
--- a/assets/blocks/liquid/conduits/reinforced-conduit-top-2.png
+++ b/assets/blocks/liquid/conduits/reinforced-conduit-2.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/reinforced-conduit-top-3.png b/assets/blocks/liquid/conduits/reinforced-conduit-3.png
index 297d720..297d720 100644
--- a/assets/blocks/liquid/conduits/reinforced-conduit-top-3.png
+++ b/assets/blocks/liquid/conduits/reinforced-conduit-3.png
Binary files differ
diff --git a/assets/blocks/liquid/conduits/reinforced-conduit-top-4.png b/assets/blocks/liquid/conduits/reinforced-conduit-4.png
index 46deb70..46deb70 100644
--- a/assets/blocks/liquid/conduits/reinforced-conduit-top-4.png
+++ b/assets/blocks/liquid/conduits/reinforced-conduit-4.png
Binary files differ
diff --git a/assets/blocks/production/heat-router-top1.png b/assets/blocks/production/heat-router-top1.png
new file mode 100644
index 0000000..75a62a4
--- /dev/null
+++ b/assets/blocks/production/heat-router-top1.png
Binary files differ
diff --git a/assets/blocks/production/heat-router-top2.png b/assets/blocks/production/heat-router-top2.png
new file mode 100644
index 0000000..c592618
--- /dev/null
+++ b/assets/blocks/production/heat-router-top2.png
Binary files differ
diff --git a/assets/blocks/production/heat-router.png b/assets/blocks/production/heat-router.png
index 7306dca..7f71e4d 100644
--- a/assets/blocks/production/heat-router.png
+++ b/assets/blocks/production/heat-router.png
Binary files differ
diff --git a/build.rs b/build.rs
index 6f5b184..20a6663 100644
--- a/build.rs
+++ b/build.rs
@@ -7,6 +7,23 @@ use std::iter::Iterator;
use std::path::Path;
use walkdir::WalkDir;
+macro_rules! wr {
+ ($dst:expr => $($arg:tt)*) => { writeln!($dst, $($arg)*).unwrap() };
+}
+
+fn kebab2bigsnek(kebab: &str) -> String {
+ let mut n = String::new();
+ n.reserve(kebab.len());
+ for c in kebab.chars() {
+ if c == '-' {
+ n.push('_');
+ } else {
+ n.push(c.to_ascii_uppercase());
+ }
+ }
+ n
+}
+
fn main() {
let _ = std::fs::remove_dir_all("target/out");
let walkdir = WalkDir::new("assets");
@@ -18,17 +35,30 @@ fn main() {
// let mut half = File::create(o.join("half.rs")).unwrap();
let mut quar = File::create(o.join("quar.rs")).unwrap();
let mut eigh = File::create(o.join("eigh.rs")).unwrap();
- let mut n = 2usize;
- for mut f in [&full, &eigh, &quar] {
- f.write_all(b"phf::phf_map! {\n").unwrap();
+ let mut n = 4usize;
+
+ wr!(full => "pub mod full {{");
+ wr!(full => "pub static EMPTY: LazyLock<RgbaImage> = LazyLock::new(|| RgbaImage::new(32, 32));");
+
+ wr!(quar => "pub mod quar {{");
+ wr!(quar => "pub static EMPTY: LazyLock<RgbaImage> = LazyLock::new(|| RgbaImage::new(8, 8));");
+
+ wr!(eigh => "pub mod eigh {{");
+ wr!(eigh => "pub static EMPTY: LazyLock<RgbaImage> = LazyLock::new(|| RgbaImage::new(4, 4));");
+
+ for mut file in [&full, &quar, &eigh] {
+ file.write_all(b"macro_rules!img{($v:expr)=>{{static TMP:LazyLock<RgbaImage>=LazyLock::new(||$v);&TMP}};}\n").unwrap();
+ wr!(file => "use ::{{image::RgbaImage, std::sync::LazyLock}};");
}
for i in 1..=16 {
n += 1;
- writeln!(full, r#" "build{}" => &EMPTY_FULL,"#, i).unwrap();
- writeln!(quar, r#" "build{}" => &EMPTY_QUAR,"#, i).unwrap();
- writeln!(eigh, r#" "build{}" => &EMPTY_EIGH,"#, i).unwrap();
+ wr!(full => "pub static BUILD{}: &LazyLock<RgbaImage> = &EMPTY;", i);
+ wr!(quar => "pub static BUILD{}: &LazyLock<RgbaImage> = &EMPTY;", i);
+ wr!(eigh => "pub static BUILD{}: &LazyLock<RgbaImage> = &EMPTY;", i);
}
+ let mut warmup = File::create(o.join("warmup.rs")).unwrap();
+ wr!(warmup => "pub fn warmup() {{");
for e in walkdir.into_iter().filter_map(|e| e.ok()) {
let path = e.path();
if path.is_file() && let Some(e) = path.extension() && e == "png" {
@@ -38,7 +68,7 @@ fn main() {
continue;
}
let path = path.with_extension("");
- let path = path.file_name().unwrap().to_str().unwrap();
+ let path = kebab2bigsnek(path.file_name().unwrap().to_str().unwrap());
macro_rules! writ {
($ext:ident / $scale:literal) => {
let mut buf = File::create(o.join(n.to_string() + "-" + stringify!($ext))).unwrap();
@@ -64,20 +94,25 @@ fn main() {
let x = new.width();
let y = new.height();
buf.write_all(&new.into_raw()).unwrap();
- writeln!($ext,
- r#" "{path}" => r!(unsafe {{ RgbaImage::from_vec({x}, {y}, include_bytes!(concat!(env!("OUT_DIR"), "/{n}-{}")).to_vec()).unwrap_unchecked() }}),"#,
+ wr!($ext =>
+ r#"pub static {path}: &LazyLock<RgbaImage> = img!(unsafe {{ RgbaImage::from_vec({x}, {y}, include_bytes!(concat!(env!("OUT_DIR"), "/{n}-{}")).to_vec()).unwrap_unchecked() }});"#,
stringify!($ext)
- ).unwrap();
+ );
};
}
writ!(full / 1);
// writ!(half + 0.5);
writ!(quar / 4);
writ!(eigh / 8);
+ wr!(warmup => "LazyLock::force({path});");
n += 1;
}
}
+ warmup.write_all(b"}").unwrap();
for mut f in [full, eigh, quar] {
+ // brazillian literal
+ f.write_all(br#"include!(concat!(env!("OUT_DIR"), "/warmup.rs"));"#)
+ .unwrap();
f.write_all(b"}").unwrap();
}
}
diff --git a/src/block/campaign.rs b/src/block/campaign.rs
index 9869eeb..46ff605 100644
--- a/src/block/campaign.rs
+++ b/src/block/campaign.rs
@@ -3,6 +3,6 @@ use crate::block::make_register;
use crate::block::simple::{cost, make_simple};
make_simple!(CampaignBlock);
make_register! {
- "launch-pad" => CampaignBlock::new(3, true, cost!(Copper: 350, Lead: 200, Titanium: 150, Silicon: 140));
- "interplanetary-accelerator" => CampaignBlock::new(7, true, cost!(Copper: 16000, Silicon: 11000, Thorium: 13000, Titanium: 12000, SurgeAlloy: 6000, PhaseFabric: 5000));
+ "launch-pad" -> CampaignBlock::new(3, true, cost!(Copper: 350, Lead: 200, Titanium: 150, Silicon: 140));
+ "interplanetary-accelerator" -> CampaignBlock::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 38a003f..73c290b 100644
--- a/src/block/defense.rs
+++ b/src/block/defense.rs
@@ -4,21 +4,21 @@ use crate::block::*;
make_simple!(DefenseBlock);
make_simple!(HeatedBlock => |_, _, _, buff: &mut DataRead| read_heated(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" => DefenseBlock::new(3, true, cost!(Lead: 100, Titanium: 75, Silicon: 125));
- "regen-projector" => DefenseBlock::new(3, true, cost!(Silicon: 80, Tungsten: 60, Oxide: 40, Beryllium: 80));
- "shock-mine" => DefenseBlock::new(1, true, cost!(Lead: 25, Silicon: 12));
- "radar" => DefenseBlock::new(1, true, cost!(Silicon: 60, Graphite: 50, Beryllium: 10));
- "build-tower" => DefenseBlock::new(3, true, cost!(Silicon: 150, Oxide: 40, Thorium: 60));
- "shockwave-tower" => DefenseBlock::new(3, true, cost!(SurgeAlloy: 50, Silicon: 150, Oxide: 30, Tungsten: 100));
+ "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" -> DefenseBlock::new(3, true, cost!(Lead: 100, Titanium: 75, Silicon: 125));
+ "regen-projector" -> DefenseBlock::new(3, true, cost!(Silicon: 80, Tungsten: 60, Oxide: 40, Beryllium: 80));
+ "shock-mine" -> DefenseBlock::new(1, true, cost!(Lead: 25, Silicon: 12));
+ "radar" -> DefenseBlock::new(1, true, cost!(Silicon: 60, Graphite: 50, Beryllium: 10));
+ "build-tower" -> DefenseBlock::new(3, true, cost!(Silicon: 150, Oxide: 40, Thorium: 60));
+ "shockwave-tower" -> DefenseBlock::new(3, true, cost!(SurgeAlloy: 50, Silicon: 150, Oxide: 30, Tungsten: 100));
// barrier projector
// editor only
- "barrier-projector" => DefenseBlock::new(3, true, &[]);
- "shield-projector" => DefenseBlock::new(3, true, &[]);
- "large-shield-projector" => DefenseBlock::new(4, true, &[]);
+ "barrier-projector" -> DefenseBlock::new(3, true, &[]);
+ "shield-projector" -> DefenseBlock::new(3, true, &[]);
+ "large-shield-projector" -> DefenseBlock::new(4, true, &[]);
}
/// format:
diff --git a/src/block/distribution.rs b/src/block/distribution.rs
index c69a503..abf6433 100644
--- a/src/block/distribution.rs
+++ b/src/block/distribution.rs
@@ -39,8 +39,8 @@ make_simple!(
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(name, s);
+ let mut base = load!("duct-base", s);
+ let mut top = load!(from name which is ["overflow-duct" "underflow-duct"], s);
top.rotate(rot.rotated(false).count());
base.overlay(&top);
base
@@ -56,7 +56,7 @@ fn draw_stack(
) -> ImageHolder {
let ctx = ctx.unwrap();
let mask = mask(ctx, rot, name);
- let edge = load(&format!("{name}-edge"), s);
+ let edge = load!(concat edge => name which is ["surge-conveyor" | "plastanium-conveyor"], s);
let edgify = |skip, to: &mut RgbaImage| {
for i in 0..4 {
if i == skip {
@@ -67,7 +67,11 @@ fn draw_stack(
to.overlay(&edge);
}
};
- let gimme = |n: u8| load(&format!("{name}-{n}"), s);
+ let gimme = |n: u8| match n {
+ 0 => load!(concat 0 => name which is ["surge-conveyor" | "plastanium-conveyor"], s),
+ 1 => load!(concat 1 => name which is ["surge-conveyor" | "plastanium-conveyor"], s),
+ _ => load!("plastanium-conveyor-2", s),
+ };
let empty = ctx.cross[rot.count() as usize].map_or(true, |(v, _)| v.name != name);
// mindustry says fuck this and just draws the arrow convs in schems but im better than that
if rot.mirrored(true, true).mask() == mask && empty && name != "surge-conveyor" {
@@ -115,8 +119,8 @@ make_simple!(ControlBlock);
make_simple!(
SurgeRouter
/ |s| {
- let mut base = load("surge-router", s);
- base.overlay(&load("top", s));
+ let mut base = load!("surge-router", s);
+ base.overlay(&load!("top", s));
base
}
);
@@ -128,15 +132,15 @@ make_register! {
"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);
+ "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));
- "router" => ControlBlock::new(1, true, cost!(Copper: 3));
- "distributor" => ControlBlock::new(2, true, cost!(Copper: 4, Lead: 4));
- "overflow-gate" => ControlBlock::new(1, true, cost!(Copper: 4, Lead: 2));
- "underflow-gate" => ControlBlock::new(1, true, cost!(Copper: 4, Lead: 2));
+ "router" -> ControlBlock::new(1, true, cost!(Copper: 3));
+ "distributor" -> ControlBlock::new(2, true, cost!(Copper: 4, Lead: 4));
+ "overflow-gate" -> ControlBlock::new(1, true, cost!(Copper: 4, Lead: 2));
+ "underflow-gate" -> ControlBlock::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));
@@ -147,11 +151,11 @@ make_register! {
"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" => UnitCargoLoader::new(3, true, cost!(Silicon: 80, SurgeAlloy: 50, Oxide: 20));
+ "unit-cargo-loader" -> UnitCargoLoader::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" => ControlBlock::new(1, true, &[]);
+ "item-source" -> ItemBlock::new(1, true, &[]);
+ "item-void" -> ControlBlock::new(1, true, &[]);
}
pub struct ItemBlock {
@@ -224,17 +228,14 @@ impl BlockLogic for ItemBlock {
rot: Rotation,
s: Scale,
) -> ImageHolder {
- let mut p = load(name, s);
+ let mut p = load!(from name which is ["sorter" | "inverted-sorter" | "duct-router" | "duct-unloader" | "unit-cargo-unload-point" | "unloader" | "item-source"], s);
if let Some(state) = state {
if let Some(item) = Self::get_state(state) {
- let mut top = load(
- match name {
- "unit-cargo-unload-point" => "unit-cargo-unload-point-top",
- "unloader" => "unloader-center",
- _ => "center",
- },
- s,
- );
+ let mut top = load!(s -> match name {
+ "unit-cargo-unload-point" => "unit-cargo-unload-point-top",
+ "unloader" => "unloader-center",
+ _ => "center",
+ });
p.overlay(top.tint(item.color()));
return p;
}
@@ -243,20 +244,20 @@ impl BlockLogic for ItemBlock {
return p;
}
if name == "duct-router" {
- let mut arrow = load("top", s);
+ let mut arrow = load!("top", s);
arrow.rotate(rot.rotated(false).count());
p.overlay(&arrow);
p
} else if name == "duct-unloader" {
- let mut top = load("duct-unloader-top", s);
+ let mut top = load!("duct-unloader-top", s);
top.rotate(rot.rotated(false).count());
p.overlay(&top);
- let mut arrow = load("top", s);
+ let mut arrow = load!("top", s);
arrow.rotate(rot.rotated(false).count());
p.overlay(&arrow);
p
} else {
- let mut null = load("cross-full", s);
+ let mut null = load!("cross-full", s);
null.overlay(&p);
null
}
@@ -484,25 +485,25 @@ impl BlockLogic for BridgeBlock {
) -> ImageHolder {
match name {
"mass-driver" => {
- let mut base = load("mass-driver-base", s);
- base.overlay(&load("mass-driver", s));
+ let mut base = load!("mass-driver-base", s);
+ base.overlay(&load!("mass-driver", s));
base
}
"duct-bridge" | "reinforced-bridge-conduit" => {
- let mut base = load(name, s);
- let mut arrow = load(
- match name {
+ let mut base =
+ load!(from name which is ["duct-bridge" | "reinforced-bridge-conduit"], s);
+ let mut arrow = load!(
+ s -> match name {
"duct-bridge" => "duct-bridge-dir",
_ => "reinforced-bridge-conduit-dir",
- },
- s,
+ }
);
arrow.rotate(r.rotated(false).count());
base.overlay(&arrow);
base
}
// "bridge-conveyor" | "phase-conveyor" | "bridge-conduit" | "phase-conduit" | "payload-mass-driver" | "large-payload-mass-driver"
- _ => load(name, s),
+ _ => unreachable!(),
}
}
}
diff --git a/src/block/drills.rs b/src/block/drills.rs
index a06c1e4..7d09941 100644
--- a/src/block/drills.rs
+++ b/src/block/drills.rs
@@ -6,32 +6,30 @@ use crate::block::*;
make_simple!(
DrillBlock,
|_, name, _, _, rot: Rotation, s| {
- if matches!(name, "large-plasma-bore" | "plasma-bore" | "cliff-crusher") {
- let mut base = load(name, s);
- let mut top = load(&format!("{name}-top"), s);
- top.rotate(rot.rotated(false).count());
- base.overlay(&top);
- return base;
- }
- load(name, s)
+ let mut base =
+ load!(from name which is ["large-plasma-bore" | "plasma-bore" | "cliff-crusher"], s);
+ let mut top = load!(concat top => name which is ["large-plasma-bore" | "plasma-bore" | "cliff-crusher"], s);
+ top.rotate(rot.rotated(false).count());
+ base.overlay(&top);
+ return base;
},
|_, _, _, buff: &mut DataRead| read_drill(buff)
);
make_simple!(ExtractorBlock);
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" => ExtractorBlock::new(2, true, cost!(Copper: 30, Lead: 30, Metaglass: 30, Graphite: 30));
- "oil-extractor" => ExtractorBlock::new(3, true, cost!(Copper: 150, Lead: 115, Graphite: 175, Thorium: 115, Silicon: 75));
- "vent-condenser" => ProductionBlock::new(3, true, cost!(Graphite: 20, Beryllium: 60));
- "cliff-crusher" => DrillBlock::new(2, false, cost!(Beryllium: 100, Graphite: 40));
+ "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" -> ExtractorBlock::new(2, true, cost!(Copper: 30, Lead: 30, Metaglass: 30, Graphite: 30));
+ "oil-extractor" -> ExtractorBlock::new(3, true, cost!(Copper: 150, Lead: 115, Graphite: 175, Thorium: 115, Silicon: 75));
+ "vent-condenser" -> ProductionBlock::new(3, true, cost!(Graphite: 20, Beryllium: 60));
+ "cliff-crusher" -> DrillBlock::new(2, false, cost!(Beryllium: 100, Graphite: 40));
"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));
+ "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:
diff --git a/src/block/environment.rs b/src/block/environment.rs
index 7b0b250..efa7803 100644
--- a/src/block/environment.rs
+++ b/src/block/environment.rs
@@ -1,17 +1,16 @@
//! grass
use crate::block::make_register;
use crate::block::simple::make_simple;
-use crate::data::renderer::*;
macro_rules! register_env {
($($field:literal: $size:literal;)+) => {
make_register!(
- $($field => EnvironmentBlock::new($size, true, &[]);)*
+ $($field -> EnvironmentBlock::new($size, true, &[]);)*
);
};
}
-make_simple!(EnvironmentBlock, |_, name, _, _, _, s| load(name, s));
+make_simple!(EnvironmentBlock);
register_env! {
"darksand": 1;
@@ -164,7 +163,6 @@ register_env! {
"red-stone-boulder": 1;
"rhyolite-boulder": 1;
"sand-boulder": 1;
- "yellow-sand-boulder": 1;
"pur-bush": 1;
"tendrils": 1;
// these are tall but uh (TODO layering)
diff --git a/src/block/liquid.rs b/src/block/liquid.rs
index de2917b..3869971 100644
--- a/src/block/liquid.rs
+++ b/src/block/liquid.rs
@@ -17,7 +17,7 @@ make_simple!(
let ctx = ctx.unwrap();
let mask = mask(ctx, rot, name);
let (index, rot, flip) = mask2rotations(mask, rot);
- let tile = rotations2tile((index, rot, flip), &format!("{name}-top"), s);
+ let tile = rotations2tile((index, rot, flip), "conduit", s);
// TODO caps. stopped trying bcz too complex
tile
},
@@ -25,28 +25,28 @@ make_simple!(
);
make_register! {
- "reinforced-pump" => LiquidBlock::new(2, true, cost!(Beryllium: 40, Tungsten: 30, Silicon: 20));
- "mechanical-pump" => LiquidBlock::new(1, true, cost!(Copper: 15, Metaglass: 10));
- "rotary-pump" => LiquidBlock::new(2, true, cost!(Copper: 70, Metaglass: 50, Titanium: 35, Silicon: 20));
- "impulse-pump" => LiquidBlock::new(3, true, cost!(Copper: 80, Metaglass: 90, Titanium: 40, Thorium: 35, Silicon: 30));
+ "reinforced-pump" -> LiquidBlock::new(2, true, cost!(Beryllium: 40, Tungsten: 30, Silicon: 20));
+ "mechanical-pump" -> LiquidBlock::new(1, true, cost!(Copper: 15, Metaglass: 10));
+ "rotary-pump" -> LiquidBlock::new(2, true, cost!(Copper: 70, Metaglass: 50, Titanium: 35, Silicon: 20));
+ "impulse-pump" -> LiquidBlock::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" => LiquidBlock::new(1, true, cost!(Metaglass: 2, Graphite: 4));
- "liquid-container" => LiquidBlock::new(2, true, cost!(Metaglass: 15, Titanium: 10));
- "liquid-tank" => LiquidBlock::new(3, true, cost!(Metaglass: 40, Titanium: 30));
- "liquid-junction" => LiquidBlock::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);
+ "liquid-router" -> LiquidBlock::new(1, true, cost!(Metaglass: 2, Graphite: 4));
+ "liquid-container" -> LiquidBlock::new(2, true, cost!(Metaglass: 15, Titanium: 10));
+ "liquid-tank" -> LiquidBlock::new(3, true, cost!(Metaglass: 40, Titanium: 30));
+ "liquid-junction" -> LiquidBlock::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" => LiquidBlock::new(1, true, cost!(Graphite: 4, Beryllium: 8));
+ "reinforced-liquid-junction" -> LiquidBlock::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" => LiquidBlock::new(1, true, cost!(Graphite: 8, Beryllium: 4));
- "reinforced-liquid-container" => LiquidBlock::new(2, true, cost!(Tungsten: 10, Beryllium: 16));
- "reinforced-liquid-tank" => LiquidBlock::new(3, true, cost!(Tungsten: 40, Beryllium: 50));
+ "reinforced-liquid-router" -> LiquidBlock::new(1, true, cost!(Graphite: 8, Beryllium: 4));
+ "reinforced-liquid-container" -> LiquidBlock::new(2, true, cost!(Tungsten: 10, Beryllium: 16));
+ "reinforced-liquid-tank" -> LiquidBlock::new(3, true, cost!(Tungsten: 40, Beryllium: 50));
// sandbox only
"liquid-source" => FluidBlock::new(1, true, &[]);
- "liquid-void" => LiquidBlock::new(1, true, &[]);
+ "liquid-void" -> LiquidBlock::new(1, true, &[]);
}
pub struct FluidBlock {
@@ -111,21 +111,21 @@ impl BlockLogic for FluidBlock {
fn draw(
&self,
- name: &str,
+ _: &str,
state: Option<&State>,
_: Option<&RenderingContext>,
_: Rotation,
s: Scale,
) -> ImageHolder {
- let mut p = load(name, s);
+ let mut p = load!("liquid-source", s);
if let Some(state) = state {
if let Some(liq) = Self::get_state(state) {
- let mut top = load("center", s);
+ let mut top = load!("center", s);
p.overlay(top.tint(liq.color()));
return p;
}
}
- let mut null = load("cross-full", s);
+ let mut null = load!("cross-full", s);
null.overlay(&p);
null
}
diff --git a/src/block/logic.rs b/src/block/logic.rs
index afaa947..0320fb6 100644
--- a/src/block/logic.rs
+++ b/src/block/logic.rs
@@ -23,21 +23,21 @@ 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));
+ "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" => LogicBlock::new(3, true, cost!(Lead: 100, Metaglass: 50, Silicon: 50));
- "large-logic-display" => LogicBlock::new(6, true, cost!(Lead: 200, Metaglass: 100, Silicon: 150, PhaseFabric: 75));
+ "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" -> LogicBlock::new(3, true, cost!(Lead: 100, Metaglass: 50, Silicon: 50));
+ "large-logic-display" -> LogicBlock::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" => LogicBlock::new(1, true, &[]);
- "world-message" => MessageLogic::new(1, true, &[]);
- "world-cell" => MemoryBlock::new(1, true, &[]);
+ "world-processor" -> LogicBlock::new(1, true, &[]);
+ "world-message" -> MessageLogic::new(1, true, &[]);
+ "world-cell" -> MemoryBlock::new(1, true, &[]);
}
pub struct CanvasBlock {
@@ -146,7 +146,7 @@ impl BlockLogic for CanvasBlock {
/// i thought about drawing the borders and stuff but it felt like too much work
fn draw(
&self,
- n: &str,
+ _: &str,
state: Option<&State>,
_: Option<&RenderingContext>,
_: Rotation,
@@ -171,7 +171,7 @@ impl BlockLogic for CanvasBlock {
)
.into_rgba8()
.scale((s * self.size as u32) - offset * 2);
- let mut borders = load(n, s);
+ let mut borders = load!("canvas", s);
borders.overlay_at(&p, offset, offset);
return borders;
}
@@ -235,13 +235,13 @@ impl BlockLogic for MessageLogic {
fn draw(
&self,
- name: &str,
+ _: &str,
_: Option<&State>,
_: Option<&RenderingContext>,
_: Rotation,
- s: Scale,
+ _: Scale,
) -> ImageHolder {
- load(name, s)
+ unreachable!()
}
fn deserialize_state(&self, data: DynData) -> Result<Option<State>, DeserializeError> {
@@ -344,10 +344,10 @@ impl BlockLogic for SwitchLogic {
_: Rotation,
s: Scale,
) -> ImageHolder {
- let mut base = load("switch", s);
+ let mut base = load!("switch", s);
if let Some(state) = state {
if *Self::get_state(state) {
- let on = load("switch-on", s);
+ let on = load!("switch-on", s);
base.overlay(&on);
return base;
}
@@ -408,17 +408,6 @@ fn read_decompressed(buff: &mut DataRead) -> Result<ProcessorState, ProcessorDes
impl BlockLogic for ProcessorLogic {
impl_block!();
- fn draw(
- &self,
- name: &str,
- _: Option<&State>,
- _: Option<&RenderingContext>,
- _: Rotation,
- s: Scale,
- ) -> ImageHolder {
- load(name, s)
- }
-
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
Ok(DynData::Empty)
}
diff --git a/src/block/mod.rs b/src/block/mod.rs
index c1440c5..49d095d 100644
--- a/src/block/mod.rs
+++ b/src/block/mod.rs
@@ -8,6 +8,7 @@ use std::any::Any;
use std::borrow::Cow;
use std::error::Error;
use std::fmt;
+use std::sync::LazyLock;
use crate::access::BoxAccess;
use crate::data::dynamic::{DynData, DynType};
@@ -64,7 +65,9 @@ pub trait BlockLogic {
context: Option<&RenderingContext>,
rot: Rotation,
scale: Scale,
- ) -> ImageHolder;
+ ) -> ImageHolder {
+ unimplemented!("{name}")
+ }
fn want_context(&self) -> bool {
false
@@ -161,6 +164,7 @@ impl SerializeError {
/// a block. put it in stuff!
pub struct Block {
+ image: Option<[&'static LazyLock<RgbaImage>; 3]>,
name: Cow<'static, str>,
pub(crate) logic: BoxAccess<'static, dyn BlockLogic + Sync>,
}
@@ -177,8 +181,9 @@ impl Block {
pub const fn new(
name: Cow<'static, str>,
logic: BoxAccess<'static, dyn BlockLogic + Sync>,
+ image: Option<[&'static LazyLock<RgbaImage>; 3]>,
) -> Self {
- Self { name, logic }
+ Self { name, logic, image }
}
/// this blocks name
@@ -202,6 +207,11 @@ impl Block {
rot: Rotation,
scale: Scale,
) -> ImageHolder {
+ if let Some(imgs) = self.image {
+ return ImageHolder::from(LazyLock::force(unsafe {
+ imgs.get_unchecked(scale as usize)
+ }));
+ }
self.logic
.as_ref()
.draw(&self.name, state, context, rot, scale)
@@ -429,16 +439,26 @@ pub type BlockRegistry<'l> = crate::registry::Registry<'l, Block>;
pub type RegisterError<'l> = crate::registry::RegisterError<'l, Block>;
macro_rules! make_register {
- ($($field:literal => $logic:expr;)+) => { paste::paste! {
+ ($($field:literal $op:tt $logic:expr;)+) => { paste::paste! {
$(
- pub static [<$field:snake:upper>]: $crate::block::Block = $crate::block::Block::new(
- std::borrow::Cow::Borrowed($field), $crate::access::Access::Borrowed(&$logic));
- )+
+ $crate::block::make_register!(impl $field $op $logic);
+ )+
pub(crate) fn register(reg: &mut $crate::block::BlockRegistry<'_>) {
- $(assert!(reg.register(&[<$field:snake:upper>]).is_ok(), "duplicate block {:?}", $field);)+
+ // get the static we make
+ $(assert!(reg.register(&[<$field:snake:upper>]).is_ok());)+
}
}};
+ (impl $field: literal => $logic: expr) => {
+ paste::paste! { pub static [<$field:snake:upper>]: $crate::block::Block = $crate::block::Block::new(
+ std::borrow::Cow::Borrowed($field), $crate::access::Access::Borrowed(&$logic), None
+ ); }
+ };
+ (impl $field: literal -> $logic: expr) => {
+ paste::paste! { pub static [<$field:snake:upper>]: $crate::block::Block = $crate::block::Block::new(
+ std::borrow::Cow::Borrowed($field), $crate::access::Access::Borrowed(&$logic), Some(crate::data::renderer::load!($field))
+ ); }
+ }
}
pub(crate) use make_register;
diff --git a/src/block/payload.rs b/src/block/payload.rs
index e20aae9..070efe0 100644
--- a/src/block/payload.rs
+++ b/src/block/payload.rs
@@ -15,39 +15,32 @@ use super::BlockRegistry;
make_simple!(SimplePayloadBlock, |_, n, _, _, r: Rotation, scl| {
match n {
"deconstructor" | "small-deconstructor" | "payload-void" => {
- let mut base = load(n, scl);
- let mut r#in = load(
- match n {
- "small-deconstructor" => "factory-in-3",
- _ => "factory-in-5",
- },
- scl,
+ let mut base = load!(from n which is ["deconstructor" | "small-deconstructor" | "payload-void"], scl);
+ let mut r#in = load!(scl -> match n {
+ "small-deconstructor" => "factory-in-3",
+ _ => "factory-in-5",
+ });
+ base.overlay(r#in.rotate(r.rotated(false).count())).overlay(
+ load!(scl -> match n {
+ "small-deconstructor" => "small-deconstructor-top",
+ "deconstructor" => "deconstructor-top",
+ _ => "payload-void-top",
+ })
+ .borrow(),
);
- base.overlay(r#in.rotate(r.rotated(false).count()))
- .overlay(&load(
- match n {
- "small-deconstructor" => "small-deconstructor-top",
- "deconstructor" => "deconstructor-top",
- _ => "payload-void-top",
- },
- scl,
- ));
base
}
// "payload-loader" | "payload-unloader"
_ => {
- let mut base = load(n, scl);
- let mut input = load("factory-in-3-dark", scl);
- let mut output = load("factory-out-3-dark", scl);
+ let mut base = load!(from n which is ["payload-loader" | "payload-unloader"], scl);
+ let mut input = load!("factory-in-3-dark", scl);
+ let mut output = load!("factory-out-3-dark", scl);
base.overlay(input.rotate(r.rotated(false).count()))
.overlay(output.rotate(r.rotated(false).count()))
- .overlay(&load(
- match n {
- "payload-loader" => "payload-loader-top",
- _ => "payload-unloader-top",
- },
- scl,
- ));
+ .overlay(
+ load!(concat top => n which is ["payload-loader" | "payload-unloader"], scl)
+ .borrow(),
+ );
base
}
}
@@ -55,7 +48,8 @@ make_simple!(SimplePayloadBlock, |_, n, _, _, r: Rotation, scl| {
make_simple!(
PayloadConveyor,
|_, n, _, _, r: Rotation, s| {
- let mut base = load(n, s);
+ let mut base =
+ load!(from n which is ["payload-conveyor" | "reinforced-payload-conveyor"], s);
base.rotate(r.rotated(false).count());
base
},
@@ -68,8 +62,8 @@ make_register! {
"payload-router" => PayloadBlock::new(3, false, cost!(Copper: 10, Graphite: 15));
"reinforced-payload-conveyor" => PayloadConveyor::new(3, false, cost!(Tungsten: 10));
"reinforced-payload-router" => PayloadBlock::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);
+ "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));
@@ -123,41 +117,23 @@ impl BlockLogic for PayloadBlock {
) -> ImageHolder {
match name {
"payload-router" | "reinforced-payload-router" => {
- let mut base = load(name, s);
+ let mut base =
+ load!(from name which is ["payload-router" | "reinforced-payload-router"], s);
base.rotate(r.rotated(false).count());
- let over = load(
- match name {
- "payload-router" => "payload-router-over",
- _ => "reinforced-payload-router-over",
- },
- s,
- );
+ let over = load!(concat over => name which is ["payload-router" | "reinforced-payload-router"], s);
base.overlay(&over);
base
}
- // "constructor" | "large-constructor" | "payload-source"
_ => {
- let mut base = load(name, s);
- let mut out = load(
- match name {
- "constructor" => "factory-out-3",
- "large-constructor" => "factory-out-5-dark",
- _ => "factory-out-5",
- },
- s,
- );
+ let mut base = load!(from name which is ["constructor" | "large-constructor" | "payload-source"], s);
+ let mut out = load!(s -> match name {
+ "constructor" => "factory-out-3",
+ "large-constructor" => "factory-out-5-dark",
+ _ => "factory-out-5",
+ });
out.rotate(r.rotated(false).count());
base.overlay(&out);
-
- base.overlay(&load(
- match name {
- "constructor" => "constructor-top",
- "large-constructor" => "large-constructor-top",
- _ => "payload-source-top",
- },
- s,
- ));
-
+ base.overlay(load!(concat top => name which is ["constructor" | "large-constructor" | "payload-source"], s).borrow());
base
}
}
@@ -193,10 +169,6 @@ impl BlockLogic for PayloadBlock {
Box::new(Self::create_state(*state))
}
- fn mirror_state(&self, _: &mut State, _: bool, _: bool) {}
-
- fn rotate_state(&self, _: &mut State, _: bool) {}
-
fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> {
match Self::get_state(state) {
Payload::Empty => Ok(DynData::Empty),
diff --git a/src/block/power.rs b/src/block/power.rs
index 1d853e8..a46a0ab 100644
--- a/src/block/power.rs
+++ b/src/block/power.rs
@@ -11,19 +11,20 @@ make_simple!(ImpactReactorBlock => |_, _, _, buff: &mut DataRead| read_impact(bu
make_simple!(
Neoplasia,
|_, _, _, _, rot: Rotation, scl| {
- let mut base = load("neoplasia-reactor", scl);
- base.overlay(load("neoplasia-reactor-top", scl).rotate(rot.rotated(false).count()));
+ let mut base = load!("neoplasia-reactor", scl);
+ // TODO 2 tops
+ base.overlay(load!("neoplasia-reactor-top", scl).rotate(rot.rotated(false).count()));
base
},
|_, _, _, buff: &mut DataRead| read_heater(buff)
);
make_simple!(BatteryBlock);
make_simple!(DiodeBlock, |_, _, _, _, rot: Rotation, s| {
- let mut base = load("diode", s);
+ let mut base = load!("diode", s);
if rot == Rotation::Right {
return base;
}
- let mut top = load("diode-arrow", s);
+ let mut top = load!("diode-arrow", s);
top.rotate(rot.rotated(false).count());
base.overlay(&top);
base
@@ -31,35 +32,35 @@ make_simple!(DiodeBlock, |_, _, _, _, rot: Rotation, s| {
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);
+ "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" => BatteryBlock::new(1, true, cost!(Copper: 5, Lead: 20));
- "battery-large" => BatteryBlock::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,
+ "battery" -> BatteryBlock::new(1, true, cost!(Copper: 5, Lead: 20));
+ "battery-large" -> BatteryBlock::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));
+ "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);
+ "beam-link" -> ConnectorBlock::new(3, true, &[], 12);
// sandbox only
- "power-source" => ConnectorBlock::new(1, true, &[], 100);
- "power-void" => GeneratorBlock::new(1, true, &[]);
+ "power-source" -> ConnectorBlock::new(1, true, &[], 100);
+ "power-void" -> GeneratorBlock::new(1, true, &[]);
}
pub struct ConnectorBlock {
@@ -137,17 +138,6 @@ impl BlockLogic for ConnectorBlock {
fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> {
Ok(DynData::Point2Array(Self::get_state(state).clone()))
}
-
- fn draw(
- &self,
- name: &str,
- _: Option<&State>,
- _: Option<&RenderingContext>,
- _: Rotation,
- s: Scale,
- ) -> ImageHolder {
- load(name, s)
- }
}
#[derive(Debug, Error)]
@@ -225,26 +215,11 @@ impl BlockLogic for LampBlock {
}
}
- fn draw(
- &self,
- name: &str,
- _: Option<&State>,
- _: Option<&RenderingContext>,
- _: Rotation,
- s: Scale,
- ) -> ImageHolder {
- load(name, s)
- }
-
fn clone_state(&self, state: &State) -> State {
let state = Self::get_state(state);
Box::new(Self::create_state(*state))
}
- fn mirror_state(&self, _: &mut State, _: bool, _: bool) {}
-
- fn rotate_state(&self, _: &mut State, _: bool) {}
-
fn serialize_state(&self, state: &State) -> Result<DynData, SerializeError> {
let state = Self::get_state(state);
Ok(DynData::Int(u32::from(*state) as i32))
diff --git a/src/block/production.rs b/src/block/production.rs
index af4c547..8faf359 100644
--- a/src/block/production.rs
+++ b/src/block/production.rs
@@ -4,43 +4,43 @@ 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" => ProductionBlock::new(2, true, cost!(Copper: 30, Titanium: 25));
- "disassembler" => ProductionBlock::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" => Incinerator::new(1, true, cost!(Lead: 15, Graphite: 5));
- "silicon-arc-furnace" => ProductionBlock::new(3, true, cost!(Beryllium: 70, Graphite: 80));
+ "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" -> ProductionBlock::new(2, true, cost!(Copper: 30, Titanium: 25));
+ "disassembler" -> ProductionBlock::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" -> Incinerator::new(1, true, cost!(Lead: 15, Graphite: 5));
+ "silicon-arc-furnace" -> ProductionBlock::new(3, true, cost!(Beryllium: 70, Graphite: 80));
"electrolyzer" => ProductionBlock::new(3, true, cost!(Silicon: 50, Graphite: 40, Beryllium: 130, Tungsten: 80));
- "atmospheric-concentrator" => ProductionBlock::new(3, true, cost!(Oxide: 60, Beryllium: 180, Silicon: 150));
+ "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" => Incinerator::new(1, true, cost!(Tungsten: 15));
- "carbide-crucible" => ProductionBlock::new(3, true, cost!(Tungsten: 110, Thorium: 150, Oxide: 60));
+ "slag-incinerator" -> Incinerator::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));
+ "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, &[]);
+ "heat-source" -> HeatCrafter::new(1, false, &[]);
}
make_simple!(
@@ -60,30 +60,18 @@ make_simple!(
match n {
// TODO i didnt realize the significance of two tops before and kinda deleted them, add them back
"phase-heater" | "electric-heater" | "oxidation-chamber" | "slag-heater" => {
- let mut base = load(n, s);
+ let mut base = load!(from n which is ["phase-heater" | "electric-heater" | "oxidation-chamber" | "slag-heater"], s);
base.overlay(
- load(
- match r {
- Rotation::Up | Rotation::Right => match n {
- "phase-heater" => "phase-heater-top1",
- "oxidation-chamber" => "oxidation-chamber-top1",
- "slag-heater" => "slag-heater-top1",
- _ => "electric-heater-top1",
- },
- _ => match n {
- "phase-heater" => "phase-heater-top2",
- "oxidation-chamber" => "oxidation-chamber-top2",
- "slag-heater" => "slag-heater-top2",
- _ => "electric-heater-top2",
- },
- },
- s,
- )
+ match r {
+ Rotation::Up | Rotation::Right =>
+ load!(concat top1 => n which is ["phase-heater" | "electric-heater" | "oxidation-chamber" | "slag-heater"], s),
+ _ => load!(concat top2 => n which is ["phase-heater" | "electric-heater" | "oxidation-chamber" | "slag-heater"], s)
+ }
.rotate(r.rotated(false).count()),
);
base
}
- _ => load(n, s),
+ n => unimplemented!("{n}"),
}
},
|_, _, _, buff: &mut DataRead| {
@@ -95,5 +83,12 @@ make_simple!(
Ok(())
}
);
-make_simple!(HeatConduit);
+make_simple!(HeatConduit, |_, n, _, _, r: Rotation, s| {
+ let mut base = load!(from n which is ["heat-router" | "heat-redirector"], s);
+ base.overlay(match r {
+ Rotation::Up | Rotation::Right => load!(concat top1 => n which is ["heat-router" | "heat-redirector"], s),
+ _ => load!(concat top2 => n which is ["heat-router" | "heat-redirector"], s),
+ }.rotate(r.rotated(false).count()));
+ base
+});
make_simple!(Incinerator);
diff --git a/src/block/simple.rs b/src/block/simple.rs
index f3053ee..aa7f398 100644
--- a/src/block/simple.rs
+++ b/src/block/simple.rs
@@ -122,19 +122,7 @@ macro_rules! make_simple {
crate::block::simple::make_simple!($name, $draw, $read, false);
};
($name: ident => $read: expr) => {
- crate::block::simple::make_simple!(
- $name,
- |_, n, _, _, _, s| crate::data::renderer::load(n, s),
- $read
- );
- };
- ($name: ident) => {
- crate::block::simple::make_simple!(
- $name,
- |_, n, _, _, _, s| crate::data::renderer::load(n, s),
- |_, _, _, _| Ok(()),
- false
- );
+ crate::block::simple::make_simple!($name, |_, n, _, _, _, _| unimplemented!("{n}"), $read);
};
($name: ident => $draw: expr, $read: expr) => {
crate::block::simple::make_simple!($name, |_, _, _, _, _, scl| $draw(scl), $read);
@@ -146,6 +134,9 @@ macro_rules! make_simple {
|_, _, _, _| Ok(())
);
};
+ ($name: ident) => {
+ crate::block::simple::make_simple!($name, |_, n, _, _, _, _| unimplemented!("{n}"));
+ };
}
pub(crate) use make_simple;
diff --git a/src/block/storage.rs b/src/block/storage.rs
index b64a0cd..f3a9089 100644
--- a/src/block/storage.rs
+++ b/src/block/storage.rs
@@ -4,17 +4,17 @@ use crate::block::make_register;
use crate::block::simple::{cost, make_simple};
make_register! {
- "core-shard" => StorageBlock::new(3, true, cost!(Copper: 1000, Lead: 800));
- "core-foundation" => StorageBlock::new(4, true, cost!(Copper: 3000, Lead: 3000, Silicon: 2000));
- "core-nucleus" => StorageBlock::new(5, true, cost!(Copper: 8000, Lead: 8000, Thorium: 4000, Silicon: 5000));
- "core-bastion" => StorageBlock::new(4, true, cost!(Graphite: 1000, Silicon: 1000, Beryllium: 800));
- "core-citadel" => StorageBlock::new(5, true, cost!(Silicon: 4000, Beryllium: 4000, Tungsten: 3000, Oxide: 1000));
- "core-acropolis" => StorageBlock::new(6, true, cost!(Beryllium: 6000, Silicon: 5000, Tungsten: 5000, Carbide: 3000, Oxide: 3000));
- "container" => StorageBlock::new(2, true, cost!(Titanium: 100));
- "vault" => StorageBlock::new(3, true, cost!(Titanium: 250, Thorium: 125));
- "unloader" => ItemBlock::new(1, true, cost!(Titanium: 25, Silicon: 30));
- "reinforced-container" => StorageBlock::new(2, true, cost!(Tungsten: 30, Graphite: 40));
- "reinforced-vault" => StorageBlock::new(3, true, cost!(Tungsten: 125, Thorium: 70, Beryllium: 100));
+ "core-shard" -> StorageBlock::new(3, true, cost!(Copper: 1000, Lead: 800));
+ "core-foundation" -> StorageBlock::new(4, true, cost!(Copper: 3000, Lead: 3000, Silicon: 2000));
+ "core-nucleus" -> StorageBlock::new(5, true, cost!(Copper: 8000, Lead: 8000, Thorium: 4000, Silicon: 5000));
+ "core-bastion" -> StorageBlock::new(4, true, cost!(Graphite: 1000, Silicon: 1000, Beryllium: 800));
+ "core-citadel" -> StorageBlock::new(5, true, cost!(Silicon: 4000, Beryllium: 4000, Tungsten: 3000, Oxide: 1000));
+ "core-acropolis" -> StorageBlock::new(6, true, cost!(Beryllium: 6000, Silicon: 5000, Tungsten: 5000, Carbide: 3000, Oxide: 3000));
+ "container" -> StorageBlock::new(2, true, cost!(Titanium: 100));
+ "vault" -> StorageBlock::new(3, true, cost!(Titanium: 250, Thorium: 125));
+ "unloader" -> ItemBlock::new(1, true, cost!(Titanium: 25, Silicon: 30));
+ "reinforced-container" -> StorageBlock::new(2, true, cost!(Tungsten: 30, Graphite: 40));
+ "reinforced-vault" -> StorageBlock::new(3, true, cost!(Tungsten: 125, Thorium: 70, Beryllium: 100));
}
make_simple!(StorageBlock);
diff --git a/src/block/turrets.rs b/src/block/turrets.rs
index 6510d5c..0a3cf0e 100644
--- a/src/block/turrets.rs
+++ b/src/block/turrets.rs
@@ -4,7 +4,6 @@ use super::{BlockLogic, Rotation, State};
use crate::block::make_register;
use crate::block::simple::cost;
use crate::data::{renderer::*, DataRead, ReadError};
-use crate::utils::ImageUtils;
make_register! {
"duo" => ItemTurret::new(1, true, cost!(Copper: 35));
@@ -45,13 +44,22 @@ fn draw_turret(
_: Rotation,
s: Scale,
) -> ImageHolder {
- let path = match name {
+ let size = me.get_size();
+ let mut base = match name {
"breach" | "diffuse" | "sublimate" | "titan" | "disperse" | "afflict" | "lustre"
- | "scathe" | "malign" | "smite" => format!("reinforced-block-{}", me.get_size()),
- _ => format!("block-{}", me.get_size()),
+ | "scathe" | "malign" | "smite" => load!(s -> match size {
+ 3 => "reinforced-block-3",
+ 4 => "reinforced-block-4",
+ 5 => "reinforced-block-5",
+ }),
+ _ => load!(s -> match size {
+ 1 => "block-1",
+ 2 => "block-2",
+ 3 => "block-3",
+ 4 => "block-4",
+ }),
};
- let mut base = load(&path, s);
- base.overlay(&load(name, s));
+ base.overlay(load!(from name which is ["duo" | "scatter" | "scorch" | "hail" | "wave" | "tsunami" | "lancer" | "arc" | "parallax" | "swarmer" | "salvo" | "segment" | "fuse" | "ripple" | "cyclone" | "foreshadow" | "spectre" | "meltdown" | "breach" | "diffuse" | "sublimate" | "titan" | "disperse" | "afflict" | "lustre" | "scathe" | "malign" | "smite"], s).borrow());
base
}
diff --git a/src/block/units.rs b/src/block/units.rs
index fa31095..dcd15de 100644
--- a/src/block/units.rs
+++ b/src/block/units.rs
@@ -33,40 +33,33 @@ use crate::unit;
// )
// }
-make_simple!(ConstructorBlock, |me: &Self,
- name,
- _,
- _,
- rot: Rotation,
- s| {
- let mut base = load(name, s);
+make_simple!(ConstructorBlock, |_, name, _, _, rot: Rotation, s| {
+ let mut base = load!(from name which is ["additive-reconstructor" | "multiplicative-reconstructor" | "exponential-reconstructor" | "tetrative-reconstructor" | "tank-refabricator" | "mech-refabricator" | "ship-refabricator" | "prime-refabricator" | "tank-assembler" | "ship-assembler" | "mech-assembler"], s);
let times = rot.rotated(false).count();
if !name.contains("assembler") {
- let mut out = load(
- &match name {
- "additive-reconstructor"
- | "multiplicative-reconstructor"
- | "exponential-reconstructor"
- | "tetrative-reconstructor" => format!("factory-out-{}", me.size),
- _ => format!("factory-out-{}-dark", me.size),
- },
- s,
- );
- out.rotate(times);
- base.overlay(&out);
+ let mut out = load!(s -> match name {
+ "additive-reconstructor" => "factory-out-3",
+ "multiplicative-reconstructor" => "factory-out-5",
+ "tank-refabricator" | "mech-refabricator" | "ship-refabricator" =>
+ "factory-out-3-dark",
+ "exponential-reconstructor" => "factory-out-7",
+ "prime-refabricator" | "tank-assembler" | "ship-assembler" | "mech-assembler" =>
+ "factory-out-5-dark",
+ "tetrative-reconstructor" => "factory-out-9",
+ });
+ base.overlay(out.rotate(times));
- let mut input = load(
- &match name {
- "additive-reconstructor"
- | "multiplicative-reconstructor"
- | "exponential-reconstructor"
- | "tetrative-reconstructor" => format!("factory-in-{}", me.size),
- _ => format!("factory-in-{}-dark", me.size),
- },
- s,
- );
- input.rotate(times);
- base.overlay(&input);
+ let mut r#in = load!(s -> match name {
+ "additive-reconstructor" => "factory-in-3",
+ "multiplicative-reconstructor" => "factory-in-5",
+ "tank-refabricator" | "mech-refabricator" | "ship-refabricator" =>
+ "factory-in-3-dark",
+ "exponential-reconstructor" => "factory-in-7",
+ "prime-refabricator" | "tank-assembler" | "ship-assembler" | "mech-assembler" =>
+ "factory-in-5-dark",
+ "tetrative-reconstructor" => "factory-in-9",
+ });
+ base.overlay(r#in.rotate(times));
}
// TODO: the context cross is too small
@@ -89,24 +82,21 @@ make_simple!(ConstructorBlock, |me: &Self,
// }
// }
- base.overlay(&load(&format!("{name}-top"), s));
+ base.overlay(load!(concat top => name which is ["additive-reconstructor" | "multiplicative-reconstructor" | "exponential-reconstructor" | "tetrative-reconstructor" | "tank-refabricator" | "mech-refabricator" | "ship-refabricator" | "prime-refabricator" | "tank-assembler" | "ship-assembler" | "mech-assembler"], s).borrow());
if matches!(name, "mech-assembler" | "tank-assembler" | "ship-assembler") {
base.overlay(
- load(
- match rot {
- Rotation::Up | Rotation::Right => match name {
- "mech-assembler" => "mech-assembler-side1",
- "tank-assembler" => "tank-assembler-side1",
- _ => "ship-assembler-side1",
- },
- _ => match name {
- "mech-assembler" => "mech-assembler-side2",
- "tank-assembler" => "tank-assembler-side2",
- _ => "ship-assembler-side2",
- },
- },
- s,
- )
+ match rot {
+ Rotation::Up | Rotation::Right => load!(s -> match name {
+ "mech-assembler" => "mech-assembler-side1",
+ "tank-assembler" => "tank-assembler-side1",
+ "ship-assembler" => "ship-assembler-side1",
+ }),
+ _ => load!(s -> match name {
+ "mech-assembler" => "mech-assembler-side2",
+ "tank-assembler" => "tank-assembler-side2",
+ "ship-assembler" => "ship-assembler-side2",
+ }),
+ }
.rotate(times),
);
}
@@ -114,23 +104,20 @@ make_simple!(ConstructorBlock, |me: &Self,
});
make_simple!(UnitRepairTower);
make_simple!(AssemblerModule, |_, _, _, _, rot: Rotation, scl| {
- let mut base = load("basic-assembler-module", scl);
+ let mut base = load!("basic-assembler-module", scl);
base.overlay(
- load(
- match rot {
- Rotation::Up | Rotation::Right => "basic-assembler-module-side1",
- _ => "basic-assembler-module-side2",
- },
- scl,
- )
+ load!(scl -> match rot {
+ Rotation::Up | Rotation::Right => "basic-assembler-module-side1",
+ _ => "basic-assembler-module-side2",
+ })
.rotate(rot.rotated(false).count()),
);
base
});
make_simple!(
RepairTurret => |scl| {
- let mut bot = load("block-2", scl);
- let top = load("repair-turret", scl);
+ let mut bot = load!("block-2", scl);
+ let top = load!("repair-turret", scl);
bot.overlay(&top);
bot
},
@@ -166,7 +153,7 @@ make_register! {
"ship-assembler" => ConstructorBlock::new(5, true, cost!(Carbide: 100, Oxide: 200, Tungsten: 500, Silicon: 800, Thorium: 400));
"mech-assembler" => ConstructorBlock::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" => UnitRepairTower::new(2, true, cost!(Graphite: 90, Silicon: 90, Tungsten: 80));
+ "unit-repair-tower" -> UnitRepairTower::new(2, true, cost!(Graphite: 90, Silicon: 90, Tungsten: 80));
}
@@ -258,25 +245,22 @@ impl BlockLogic for AssemblerBlock {
rot: Rotation,
s: Scale,
) -> ImageHolder {
- let mut base = load(name, s);
- let mut out = load(
- match name {
- "ground-factory" | "air-factory" | "naval-factory" => "factory-out-3",
- _ => "factory-out-3-dark",
- },
- s,
- );
+ let mut base = load!(from name which is ["ground-factory" | "air-factory" | "naval-factory" | "tank-fabricator" | "ship-fabricator" | "mech-fabricator"], s);
+ let mut out = load!(s -> match name {
+ "ground-factory" | "air-factory" | "naval-factory" => "factory-out-3",
+ _ => "factory-out-3-dark",
+ });
out.rotate(rot.rotated(false).count());
base.overlay(&out);
- base.overlay(&load(
- &match name {
- "ground-factory" | "air-factory" | "naval-factory" => {
- format!("factory-top-{}", self.size)
- }
- _ => format!("{name}-top"),
- },
- s,
- ));
+ base.overlay(
+ load!(s -> match name {
+ "ground-factory" | "air-factory" | "naval-factory" => "factory-top-3",
+ "tank-fabricator" => "tank-fabricator-top",
+ "ship-fabricator" => "ship-fabricator-top",
+ "mech-fabricator" => "mech-fabricator-top",
+ })
+ .borrow(),
+ );
base
}
diff --git a/src/block/walls.rs b/src/block/walls.rs
index 900232f..2ec2e26 100644
--- a/src/block/walls.rs
+++ b/src/block/walls.rs
@@ -4,47 +4,42 @@ use crate::block::*;
use crate::data::dynamic::DynType;
use crate::data::renderer::load;
-make_simple!(WallBlock, |_, name, _, _, _, s| {
- match name {
- "thruster" => {
- let mut base = load("thruster", s);
- base.overlay(&load("thruster-top", s));
- base
- }
- _ => load(name, s),
- }
+make_simple!(WallBlock, |_, _, _, _, _, s| {
+ let mut base = load!("thruster", s);
+ base.overlay(&load!("thruster-top", 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));
+ "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));
+ "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));
+ "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));
}
@@ -80,21 +75,15 @@ impl BlockLogic for DoorBlock {
s: Scale,
) -> ImageHolder {
if let Some(state) = state {
- return if *Self::get_state(state) {
- // TODO check
- load(
- match name {
- "door" => "door-open",
- "blast-door" => "blast-door-open",
- _ => "door-large-open",
- },
- s,
- )
- } else {
- load(name, s)
+ if *Self::get_state(state) {
+ return load!(s -> match name {
+ "door" => "door-open",
+ "blast-door" => "blast-door-open",
+ _ => "door-large-open",
+ });
};
}
- load(name, s)
+ load!(from name which is ["door" | "blast-door" | "door-large"], s)
}
fn data_from_i32(&self, _: i32, _: GridPos) -> Result<DynData, DataConvertError> {
diff --git a/src/data/autotile.rs b/src/data/autotile.rs
index a79195e..28b864d 100644
--- a/src/data/autotile.rs
+++ b/src/data/autotile.rs
@@ -221,7 +221,23 @@ pub fn flrot(flip: u8, rot: u8, with: &mut ImageHolder) {
/// TODO figure out if a flip is cheaper than a rotate_270
pub fn rotations2tile((index, rot, flip): (u8, u8, u8), name: &str, scale: Scale) -> ImageHolder {
- let mut p = load(&format!("{name}-{index}"), scale);
+ let mut p = match index {
+ 0 => {
+ load!(concat 0 => name which is ["armored-duct" | "pulse-conduit" | "plated-conduit" | "conduit" | "conveyor" | "titanium-conveyor" | "armored-conveyor" | "duct"], scale)
+ }
+ 1 => {
+ load!(concat 1 => name which is ["armored-duct" | "pulse-conduit" | "plated-conduit" | "conduit" | "conveyor" | "titanium-conveyor" | "armored-conveyor" | "duct"], scale)
+ }
+ 2 => {
+ load!(concat 2 => name which is ["armored-duct" | "pulse-conduit" | "plated-conduit" | "conduit" | "conveyor" | "titanium-conveyor" | "armored-conveyor" | "duct"], scale)
+ }
+ 3 => {
+ load!(concat 3 => name which is ["armored-duct" | "pulse-conduit" | "plated-conduit" | "conduit" | "conveyor" | "titanium-conveyor" | "armored-conveyor" | "duct"], scale)
+ }
+ _ => {
+ load!(concat 4 => name which is ["armored-duct" | "pulse-conduit" | "plated-conduit" | "conduit" | "conveyor" | "titanium-conveyor" | "armored-conveyor" | "duct"], scale)
+ }
+ };
flrot(flip, rot, p.borrow_mut());
p
}
diff --git a/src/data/renderer.rs b/src/data/renderer.rs
index 2ae8ac8..c06fb44 100644
--- a/src/data/renderer.rs
+++ b/src/data/renderer.rs
@@ -1,5 +1,7 @@
//! schematic drawing
pub(crate) use super::autotile::*;
+use super::schematic::Schematic;
+use super::GridPos;
use crate::block::environment::METAL_FLOOR;
use crate::block::Rotation;
pub(crate) use crate::utils::{ImageUtils, Overlay, Repeat};
@@ -9,27 +11,9 @@ pub(crate) use image::{
};
pub(crate) use std::borrow::{Borrow, BorrowMut};
use std::ops::{Deref, DerefMut};
-use std::sync::LazyLock;
-
-use super::schematic::Schematic;
-use super::GridPos;
-
-macro_rules! r {
- ($v:expr) => {{
- static TMP: LazyLock<RgbaImage> = LazyLock::new(|| $v);
- &TMP
- }};
-}
-
-type Images = phf::Map<&'static str, &'static LazyLock<RgbaImage>>;
-static EMPTY_FULL: LazyLock<RgbaImage> = LazyLock::new(|| RgbaImage::new(32, 32));
-static EMPTY_QUAR: LazyLock<RgbaImage> = LazyLock::new(|| RgbaImage::new(8, 8));
-static EMPTY_EIGH: LazyLock<RgbaImage> = LazyLock::new(|| RgbaImage::new(4, 4));
-
-static FULL: Images = include!(concat!(env!("OUT_DIR"), "/full.rs"));
-// static HALF: Images = include!(concat!(env!("OUT_DIR"), "/half.rs"));
-static QUAR: Images = include!(concat!(env!("OUT_DIR"), "/quar.rs"));
-static EIGH: Images = include!(concat!(env!("OUT_DIR"), "/eigh.rs"));
+include!(concat!(env!("OUT_DIR"), "/full.rs"));
+include!(concat!(env!("OUT_DIR"), "/quar.rs"));
+include!(concat!(env!("OUT_DIR"), "/eigh.rs"));
pub enum ImageHolder {
Borrow(&'static RgbaImage),
@@ -101,6 +85,7 @@ impl From<RgbaImage> for ImageHolder {
}
#[derive(Debug, Copy, Clone)]
+#[repr(u8)]
pub enum Scale {
Full,
// Half,
@@ -125,22 +110,57 @@ impl std::ops::Mul<u32> for Scale {
}
}
-pub(crate) fn try_load(name: &str, scale: Scale) -> Option<&'static RgbaImage> {
- match scale {
- Scale::Quarter => QUAR.get(name).map(|v| LazyLock::force(v)),
- Scale::Eigth => EIGH.get(name).map(|v| LazyLock::force(v)),
- Scale::Full => FULL.get(name).map(|v| LazyLock::force(v)),
- // Scale::Half => HALF.get(&name).map(|v| LazyLock::force(v)),
- }
-}
-
-#[track_caller]
-pub(crate) fn load(name: &str, scale: Scale) -> ImageHolder {
- let Some(i) = try_load(name, scale) else {
- panic!("failed to load {name}")
+#[macro_export]
+macro_rules! load {
+ ($name:literal, $scale:ident) => { paste::paste! {
+ ImageHolder::from(std::sync::LazyLock::force(match $scale {
+ crate::data::renderer::Scale::Quarter => crate::data::renderer::quar::[<$name:snake:upper>],
+ crate::data::renderer::Scale::Eigth => crate::data::renderer::eigh::[<$name:snake:upper>],
+ crate::data::renderer::Scale::Full => crate::data::renderer::full::[<$name:snake:upper>],
+ }))
+ } };
+ ($name: literal) => { paste::paste! {
+ [crate::data::renderer::full::[<$name:snake:upper>], crate::data::renderer::quar::[<$name:snake:upper>], crate::data::renderer::eigh::[<$name:snake:upper>]]
+ } };
+ (from $v:ident which is [$($k:literal $(|)?)+], $scale: ident) => {
+ crate::data::renderer::load!($scale -> match $v {
+ $($k => $k,)+
+ })
+ };
+ // turn load!(s -> match x { "v" => "y" }) into match x { "v" => load!("y", s) }
+ ($scale:ident -> match $v:ident { $($k:pat => $nam:literal $(,)?)+ }) => {
+ match $v {
+ $($k => crate::data::renderer::load!($nam, $scale),)+
+ #[allow(unreachable_patterns)]
+ n => unreachable!("{n:?}"),
+ }
};
- ImageHolder::from(i)
+ (concat $x:expr => $v:ident which is [$($k:literal $(|)?)+], $scale: ident) => { paste::paste! {
+ match $v {
+ $($k =>
+ ImageHolder::from(std::sync::LazyLock::force(match $scale {
+ crate::data::renderer::Scale::Quarter => crate::data::renderer::quar::[<$k:snake:upper _ $x:snake:upper>],
+ crate::data::renderer::Scale::Eigth => crate::data::renderer::eigh::[<$k:snake:upper _ $x:snake:upper>],
+ crate::data::renderer::Scale::Full => crate::data::renderer::full::[<$k:snake:upper _ $x:snake:upper>],
+ })),
+ )+
+ #[allow(unreachable_patterns)]
+ n => unreachable!("{n:?}"),
+ }
+ } };
+ // (concat $x:expr, to $v:ident which is [$($k:literal $(|)?)+], $scale: ident) => { paste::paste! {
+ // match $v {
+ // $($k =>
+ // ImageHolder::from(**match $scale {
+ // crate::data::renderer::Scale::Quarter => crate::data::renderer::quar::[<$k:snake:upper $x:snake:upper>],
+ // crate::data::renderer::Scale::Eigth => crate::data::renderer::eigh::[<$k:snake:upper $x:snake:upper>],
+ // crate::data::renderer::Scale::Full => crate::data::renderer::full::[<$k:snake:upper $x:snake:upper>],
+ // }),
+ // )+
+ // }
+ // } }
}
+pub(crate) use load;
/// trait for renderable objects
pub trait Renderable {
@@ -278,11 +298,9 @@ impl Renderable for Map<'_> {
/// Loads all the images into memory (about 300mb)
pub fn warmup() {
- for map in [&FULL, &QUAR, &EIGH] {
- for val in map.values() {
- LazyLock::force(val);
- }
- }
+ full::warmup();
+ quar::warmup();
+ eigh::warmup();
}
#[test]
diff --git a/src/utils/image.rs b/src/utils/image.rs
index 4095404..423a4c7 100644
--- a/src/utils/image.rs
+++ b/src/utils/image.rs
@@ -1,7 +1,7 @@
use image::*;
pub trait Overlay<W> {
- /// Overlay with onto self at coordinates x, y, without blending
+ /// Overlay with => self at coordinates x, y, without blending
fn overlay_at(&mut self, with: &W, x: u32, y: u32) -> &mut Self;
}
@@ -13,7 +13,7 @@ pub trait RepeatNew {
pub trait ImageUtils {
/// Tint this image with the color
fn tint(&mut self, color: Rgb<u8>) -> &mut Self;
- /// Overlay with onto self (does not blend)
+ /// Overlay with => self (does not blend)
fn overlay(&mut self, with: &Self) -> &mut Self;
/// rotate
fn rotate(&mut self, times: u8) -> &mut Self;