mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/block/distribution.rs')
| -rw-r--r-- | src/block/distribution.rs | 254 |
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, |