mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'src/block/distribution.rs')
-rw-r--r--src/block/distribution.rs208
1 files changed, 150 insertions, 58 deletions
diff --git a/src/block/distribution.rs b/src/block/distribution.rs
index 08df5de..db21c17 100644
--- a/src/block/distribution.rs
+++ b/src/block/distribution.rs
@@ -8,53 +8,55 @@ use crate::item;
make_simple!(
ConveyorBlock,
- |_, _, name, _, ctx: Option<&RenderingContext>| {
+ |_, _, name, _, ctx: Option<&RenderingContext>, rot: Rotation| {
let ctx = ctx.unwrap(); // we set want_context to true
- Some(tile(ctx, "distribution", "conveyors", name, ctx.rotation))
+ Some(tile(ctx, "distribution", "conveyors", name, rot))
+ },
+ |_, _, _, buff: &mut DataRead| {
+ // format:
+ // - amount: `i32`
+ // - iterate amount:
+ // - val: `i32`
+ // - id = (((val >> 24) as u8) & 0xff) as u16
+ // - x = (val >> 16) as u8) as f32 / 127.0
+ // - y = ((val >> 8) as u8 as f32 + 128.0) / 255.0
+ let amount = buff.read_i32()?;
+ for _ in 0..amount {
+ buff.skip(4)?;
+ }
+ Ok(())
},
true
);
make_simple!(
DuctBlock,
- |_, _, name, _, ctx: Option<&RenderingContext>| {
+ |_, _, name, _, ctx: Option<&RenderingContext>, rot| {
let ctx = ctx.unwrap();
- Some(tile(ctx, "distribution", "ducts", name, ctx.rotation))
+ Some(tile(ctx, "distribution", "ducts", name, rot))
+ },
+ |_, _, _, buff: &mut DataRead| {
+ // format:
+ // - rec_dir: `i8`
+ buff.skip(1)
},
true
);
make_simple!(
JunctionBlock,
- |_, _, _, _, _| None,
- |_, _, _, _, _, buff: &mut crate::data::DataRead| {
- // format:
- // - iterate 4
- // - u8
- // - iterate u8
- // - i64
- for _ in 0..4 {
- let _ = buff.read_u8()?;
- let n = buff.read_u8()? as usize;
- buff.skip(n * 8)?;
- }
- Ok(())
- },
+ |_, _, _, _, _, _| None,
+ |_, _, _, buff: &mut DataRead| { read_directional_item_buffer(buff) },
false
);
-make_simple!(
- SimpleDuctBlock,
- |_, _, name, _, ctx: Option<&RenderingContext>| {
- let ctx = ctx.unwrap();
- let mut base = load("distribution/ducts", "duct-base").unwrap().clone();
- let mut top = load("distribution/ducts", name).unwrap().clone();
- top.rotate(ctx.rotation.rotated(false).count());
- base.overlay(&top, 0, 0);
- Some(ImageHolder::from(base))
- },
- true
-);
+make_simple!(SimpleDuctBlock, |_, _, name, _, _, rot: Rotation| {
+ let mut base = load("distribution/ducts", "duct-base").unwrap().clone();
+ let mut top = load("distribution/ducts", name).unwrap().clone();
+ top.rotate(rot.rotated(false).count());
+ base.overlay(&top, 0, 0);
+ Some(ImageHolder::from(base))
+});
fn draw_stack(
_: &StackConveyor,
@@ -62,9 +64,10 @@ fn draw_stack(
name: &str,
_: Option<&State>,
ctx: Option<&RenderingContext>,
+ rot: Rotation,
) -> Option<ImageHolder> {
let ctx = ctx.unwrap();
- let mask = mask(ctx, name);
+ let mask = mask(ctx, rot, name);
// clone to not hold lock
let edge = load("distribution/stack-conveyors", &format!("{name}-edge"))
.unwrap()
@@ -84,32 +87,29 @@ fn draw_stack(
.unwrap()
.clone()
};
- let empty = ctx.cross[ctx.rotation.count() as usize].map_or(true, |(v, _)| v.name != name);
+ 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
Some(ImageHolder::from(
- if ctx.rotation.mirrored(true, true).mask() == mask && empty && name != "surge-conveyor" {
+ if rot.mirrored(true, true).mask() == mask && empty && name != "surge-conveyor" {
// end
let mut base = gimme(2);
- edgify(
- ctx.rotation.mirrored(true, true).rotated(false).count(),
- &mut base,
- );
+ edgify(rot.mirrored(true, true).rotated(false).count(), &mut base);
base
} else if mask == B0000 && empty {
// single
let mut base = gimme(0);
- base.rotate(ctx.rotation.rotated(false).count());
+ base.rotate(rot.rotated(false).count());
edgify(5, &mut base);
base
} else if mask == B0000 {
// input
let mut base = gimme(1);
- edgify(ctx.rotation.rotated(false).count(), &mut base);
+ edgify(rot.rotated(false).count(), &mut base);
base
} else {
// directional
let mut base = gimme(0);
- let going = ctx.rotation.rotated(false).count();
+ let going = rot.rotated(false).count();
base.rotate(going);
for [r, i] in [[3, 0b1000], [0, 0b0100], [1, 0b0010], [2, 0b0001]] {
if (mask.into_u8() & i) == 0 && (going != r || empty) {
@@ -123,7 +123,15 @@ fn draw_stack(
))
}
-make_simple!(StackConveyor, draw_stack, true);
+make_simple!(
+ StackConveyor,
+ draw_stack,
+ // format:
+ // - link: `i32`
+ // - cooldown: `f32`
+ |_, _, _, buff: &mut DataRead| { buff.skip(8) },
+ true
+);
make_simple!(ControlBlock);
make_register! {
@@ -224,7 +232,8 @@ impl BlockLogic for ItemBlock {
_: &str,
name: &str,
state: Option<&State>,
- ctx: Option<&RenderingContext>,
+ _: Option<&RenderingContext>,
+ rot: Rotation,
) -> Option<ImageHolder> {
let mut p = load(
match name {
@@ -259,13 +268,13 @@ impl BlockLogic for ItemBlock {
}
if matches!(name, "duct-unloader" | "duct-router") {
let mut null = load("distribution/ducts", "top").unwrap().to_owned();
- null.rotate(ctx.unwrap().rotation.rotated(false).count());
+ null.rotate(rot.rotated(false).count());
if name == "duct-unloader" {
let mut top = load("distribution/ducts", "duct-unloader-top")
.unwrap()
.to_owned();
// this rotate call could be omitted if rotation == Right to save a clone
- top.rotate(ctx.unwrap().rotation.rotated(false).count());
+ top.rotate(rot.rotated(false).count());
null.overlay(&top, 0, 0);
}
p.overlay(&null, 0, 0);
@@ -277,8 +286,43 @@ impl BlockLogic for ItemBlock {
}
}
- fn want_context(&self) -> bool {
- true
+ /// format:
+ /// (sorter | unloader | duct router | item source)
+ /// - item: `i16` as item
+ /// (duct-unloader/directional):
+ /// - tmp: `i16`
+ /// - if tmp != -1: item = tmp as item
+ /// - offset: `u16`
+ /// (unit-cargo-unload-point)
+ /// - item: `u16` as item
+ /// - stale: `bool`
+ fn read(
+ &self,
+ b: &mut Build,
+ _: &BlockRegistry,
+ _: &EntityMapping,
+ buff: &mut DataRead,
+ ) -> Result<(), DataReadError> {
+ match b.block.name() {
+ "duct-unloader" => {
+ let n = buff.read_i16()?;
+ if n != -1 {
+ b.state = Some(Self::create_state(item::Type::try_from(n as u16).ok()));
+ }
+ }
+ "unit-cargo-unload-point" => {
+ b.state = Some(Self::create_state(
+ item::Type::try_from(buff.read_u16()?).ok(),
+ ));
+ buff.skip(1)?;
+ }
+ _ => {
+ b.state = Some(Self::create_state(
+ item::Type::try_from(buff.read_u16()?).ok(),
+ ));
+ }
+ }
+ Ok(())
}
}
@@ -414,25 +458,29 @@ impl BlockLogic for BridgeBlock {
}
/// format:
- /// - out: `i32`
- /// - warmup: `f32`
- /// - iterate `links<u8>`
- /// - in+: `i32`
- /// - moved: `bool`
+ /// (item bridge)
+ /// - become [`read_buffered_item_bridge`]
+ /// (buffered brige)
+ /// - become [`read_item_buffer`]
+ /// (mass driver) (9b)
+ /// - link: `i32`
+ /// - rotation: `f32`
+ /// - state: `i8`
fn read(
&self,
- _: &str,
- _: &str,
+ t: &mut Build,
_: &super::BlockRegistry,
_: &crate::data::map::EntityMapping,
buff: &mut crate::data::DataRead,
) -> Result<(), crate::data::ReadError> {
- buff.read_i32()?;
- buff.read_f32()?;
- for _ in 0..buff.read_u8()? {
- buff.read_i32()?;
+ match t.block.name() {
+ "bridge-conveyor" => read_buffered_item_bridge(buff)?,
+ "phase-conveyor" | "phase-conduit" | "bridge-conduit" => read_item_bridge(buff)?,
+ "mass-driver" => buff.skip(9)?,
+ // no state?
+ "duct-bridge" | "reinforced-bridge-conduit" => {}
+ _ => unreachable!(), // surely no forget
}
- buff.read_bool()?;
Ok(())
}
}
@@ -443,3 +491,47 @@ pub struct BridgeConvertError {
pub x: i16,
pub y: i16,
}
+
+/// format;
+/// - call [`read_item_bridge`]
+/// - become [`read_item_buffer`]
+fn read_buffered_item_bridge(buff: &mut DataRead) -> Result<(), DataReadError> {
+ read_item_bridge(buff)?;
+ read_item_buffer(buff)
+}
+
+/// format:
+/// - index: `u8`
+/// - iter `u8`
+/// l: `i64`
+fn read_item_buffer(buff: &mut DataRead) -> Result<(), DataReadError> {
+ buff.skip(1)?;
+ let n = buff.read_u8()? as usize;
+ buff.skip(n * 8)
+}
+
+/// format:
+/// - link: `i32`
+/// - warmup: `f32`
+/// - iterate `u8`
+/// - incoming: `i32`
+/// - moved: `bool`
+fn read_item_bridge(buff: &mut DataRead) -> Result<(), DataReadError> {
+ buff.skip(8)?;
+ let n = buff.read_u8()? as usize;
+ buff.skip((n * 4) + 1)
+}
+
+/// format:
+/// - iterate 4
+/// - u8
+/// - iterate u8
+/// - i64
+fn read_directional_item_buffer(buff: &mut DataRead) -> Result<(), DataReadError> {
+ for _ in 0..4 {
+ let _ = buff.read_u8()?;
+ let n = buff.read_u8()? as usize;
+ buff.skip(n * 8)?;
+ }
+ Ok(())
+}