mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/block/distribution.rs')
-rw-r--r--src/block/distribution.rs254
1 files changed, 4 insertions, 250 deletions
diff --git a/src/block/distribution.rs b/src/block/distribution.rs
index a8e1c5d..03b9295 100644
--- a/src/block/distribution.rs
+++ b/src/block/distribution.rs
@@ -1,266 +1,20 @@
//! conveyors ( & ducts )
-use std::borrow::BorrowMut;
-
use crate::block::simple::*;
use crate::block::*;
use crate::content;
+use crate::data::autotile::tile;
use crate::data::dynamic::DynType;
use crate::item;
-use bobbin_bits::U4;
-use image::imageops::{flip_horizontal_in_place as flip_h, flip_vertical_in_place as flip_v};
-#[cfg(test)]
-macro_rules! dir {
- (^) => {
- crate::block::Rotation::Up
- };
- (v) => {
- crate::block::Rotation::Down
- };
- (<) => {
- crate::block::Rotation::Left
- };
- (>) => {
- crate::block::Rotation::Right
- };
-}
-#[cfg(test)]
-macro_rules! conv {
- (_) => {
- None
- };
- ($dir:tt) => {
- Some((
- &crate::block::distribution::CONVEYOR,
- crate::block::distribution::dir!($dir),
- ))
- };
-}
-#[cfg(test)]
-macro_rules! define {
- ($a:tt,$b:tt,$c:tt,$d:tt) => {
- [
- crate::block::distribution::conv!($a),
- crate::block::distribution::conv!($b),
- crate::block::distribution::conv!($c),
- crate::block::distribution::conv!($d),
- ]
- };
-}
-#[cfg(test)]
-pub(crate) use conv;
-#[cfg(test)]
-pub(crate) use define;
-#[cfg(test)]
-pub(crate) use dir;
-
-#[test]
-fn test_mask() {
- macro_rules! assert {
- ($a:tt,$b:tt,$c:tt,$d:tt => $rot: tt => $expect: expr) => {
- assert_eq!(mask!(define!($a, $b, $c, $d), $rot), $expect)
- };
- }
- macro_rules! mask {
- ($cross:expr, $rot: tt) => {
- mask(
- &RenderingContext {
- position: PositionContext {
- position: GridPos(5, 5),
- width: 10,
- height: 10,
- },
- cross: $cross,
- rotation: dir!($rot),
- },
- "conveyor",
- )
- };
- }
- assert!(_,_,_,_ => ^ => U4::B0000);
- assert!(v,_,_,_ => > => U4::B1000);
- assert!(v,v,_,_ => v => U4::B1000);
- assert!(_,v,>,_ => > => U4::B0000);
- assert!(v,>,<,> => ^ => U4::B0001);
- assert!(v,>,>,_ => > => U4::B1000);
-}
-
-fn mask(ctx: &RenderingContext, n: &str) -> U4 {
- macro_rules! c {
- ($in: expr, $srot: expr, $name: expr, $at: expr) => {{
- if let Some((b, rot)) = $in {
- if b.name() == $name {
- // if they go down, we must not go up
- (rot == $at && rot.mirrored(true, true) != $srot) as u8
- } else {
- 0
- }
- } else {
- 0
- }
- }};
- }
- use Rotation::*;
- let mut x = 0b0000;
-
- // println!("{:?}, {ctx}", ctx.cross);
- x |= 8 * c!(ctx.cross[0], ctx.rotation, n, Down);
- x |= 4 * c!(ctx.cross[1], ctx.rotation, n, Left);
- x |= 2 * c!(ctx.cross[2], ctx.rotation, n, Up);
- x |= c!(ctx.cross[3], ctx.rotation, n, Right);
- U4::from(x)
-}
-
-fn tile(ctx: &RenderingContext<'_>, name: &str, rot: Rotation) -> ImageHolder {
- mask2tile(mask(ctx, name), rot, name)
-}
-
-const FLIP_X: u8 = 1;
-const FLIP_Y: u8 = 2;
-
-/// TODO figure out if a flip is cheaper than a rotate_270
-fn mask2tile(mask: U4, rot: Rotation, name: &str) -> ImageHolder {
- use U4::*;
- // let lo = |index: u8| {
- // load("distribution/conveyors", &format!("{name}-{index}"))
- // .unwrap()
- // .value()
- // };
- // r == 5 => flip_v + r - 1
- macro_rules! p {
- ($image:literal, $rotation:literal) => {
- ($image, $rotation, None)
- };
- ($image:literal, $rotation:literal, $flipping:expr) => {
- ($image, $rotation, Some($flipping))
- };
- }
-
- let (index, r, flip) = match mask {
- // from left
- B0001 => match rot {
- Rotation::Down => p!(1, 1, FLIP_Y), // ┐
- Rotation::Right => p!(0, 0), // ─
- Rotation::Up => p!(1, 3), // ┘
- _ => unreachable!(),
- },
- // from below
- B0010 => match rot {
- Rotation::Left => p!(1, 2), // ┐
- Rotation::Right => p!(1, 1), // ┌
- Rotation::Up => p!(0, 3), // │
- _ => unreachable!(),
- },
- // from bottom + left
- B0011 => match rot {
- Rotation::Right => p!(2, 0), // ┬
- Rotation::Up => p!(2, 3, FLIP_Y | FLIP_X), // ┤
- _ => unreachable!(),
- },
- // from right
- B0100 => match rot {
- Rotation::Left => p!(0, 2), // ─
- Rotation::Down => p!(1, 1), // ┌
- Rotation::Up => p!(1, 1, FLIP_X), // └
- _ => unreachable!(),
- },
- // from sides
- B0101 => match rot {
- Rotation::Up => p!(4, 3), // ┴
- Rotation::Down => p!(4, 1), // ┬
- _ => unreachable!(),
- },
- // from right + down
- B0110 => match rot {
- Rotation::Up => p!(2, 3), // ├,
- Rotation::Left => p!(2, 0, FLIP_X), // ┬
- _ => unreachable!(),
- },
- // from right + down + left
- B0111 => match rot {
- Rotation::Up => p!(3, 3), // ┼
- _ => unreachable!(),
- },
- // from above
- B1000 => match rot {
- Rotation::Down => p!(0, 1), // │
- Rotation::Left => p!(1, 0, FLIP_X), // ┘
- Rotation::Right => p!(1, 0), // └
- _ => unreachable!(),
- },
- // from top and left
- B1001 => match rot {
- Rotation::Right => p!(2, 0, FLIP_Y), // ┴
- Rotation::Down => p!(2, 1), // ┤
- _ => unreachable!(),
- },
- // from top sides
- B1010 => match rot {
- Rotation::Right => p!(4, 0), // ├
- Rotation::Left => p!(4, 3), // ┤
- _ => unreachable!(),
- },
- // from top, left, bottom
- B1011 => match rot {
- Rotation::Right => p!(3, 0), // ┼
- _ => unreachable!(),
- },
- // from top and right
- B1100 => match rot {
- Rotation::Down => p!(2, 3, FLIP_X), // ├
- Rotation::Left => p!(2, 2), // ┴
- _ => unreachable!(),
- },
- // from top, left, right
- B1101 => match rot {
- Rotation::Down => p!(3, 1), // ┼
- _ => unreachable!(),
- },
- // from top, right, bottom
- B1110 => match rot {
- Rotation::Left => p!(3, 0, FLIP_X), // ┼
- _ => unreachable!(),
- },
- B0000 => (
- 0,
- match rot {
- Rotation::Left => 2,
- Rotation::Right => 0,
- Rotation::Down => 1,
- Rotation::Up => 3,
- },
- None,
- ),
- // B0000 => (0, wrap(rot.count() as i8 - 1, 0, 3) as u8, None),
- B1111 => unreachable!(),
- };
- let mut p = ImageHolder::from(load("distribution/conveyors", &format!("{name}-{index}")));
- if let Some(op) = flip {
- let re: &mut RgbaImage = p.borrow_mut();
- if (op & FLIP_X) != 0 {
- flip_h(re);
- }
- if (op & FLIP_Y) != 0 {
- flip_v(re);
- }
- }
- if r == 0 {
- return p;
- }
- let mut p = p.own();
- p.rotate(r);
- ImageHolder::from(p)
-}
make_simple!(
ConveyorBlock,
|_, _, name, _, ctx: Option<&RenderingContext>| {
- if let Some(ctx) = ctx {
- return Some(tile(ctx, name, ctx.rotation));
- }
- None
+ let ctx = ctx.unwrap(); // we specified want_context to true
+ Some(tile(ctx, "distribution", "conveyors", name, ctx.rotation))
},
true
);
+
make_simple!(
JunctionBlock,
|_, _, _, _, _| None,