diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index c6acc3cf0..8700b2185 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -99,10 +99,6 @@ import net.minecraftforge.registries.IForgeRegistry; public enum AllBlocks { - __MATERIALS__(), - COPPER_ORE(new CopperOreBlock()), - ZINC_ORE(new Block(Properties.from(Blocks.GOLD_ORE))), - __SCHEMATICS__(), SCHEMATICANNON(new SchematicannonBlock()), SCHEMATICANNON_CONNECTOR(new RenderUtilityBlock()), @@ -241,6 +237,10 @@ public enum AllBlocks { VOLCANIC_ROCK(new VolcanicRockBlock()), + __MATERIALS__(), + COPPER_ORE(new CopperOreBlock()), + ZINC_ORE(new Block(Properties.from(Blocks.GOLD_ORE))), + ; private enum ComesWith { diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java b/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java index 734e2909c..702a4b94a 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java @@ -1,10 +1,15 @@ package com.simibubi.create.foundation.behaviour; import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.AllItems; import com.simibubi.create.foundation.behaviour.ValueBox.ItemValueBox; import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.TessellatorHelper; +import com.simibubi.create.modules.contraptions.relays.elementary.CogWheelBlock; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraft.block.FenceBlock; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.renderer.BufferBuilder; @@ -14,6 +19,8 @@ import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.Vec3d; @@ -73,10 +80,26 @@ public class ValueBoxRenderer { IBakedModel modelWithOverrides = itemRenderer.getModelWithOverrides(filter); boolean blockItem = modelWithOverrides.isGui3d(); float scale = (!blockItem ? .5f : 1f) - 1 / 64f; - float zOffset = (!blockItem ? -.225f : 0); + float zOffset = (!blockItem ? -.225f : 0) + customZOffset(filter.getItem()); GlStateManager.scaled(scale, scale, scale); GlStateManager.translated(0, 0, zOffset); itemRenderer.renderItem(filter, TransformType.FIXED); } + private static float customZOffset(Item item) { + float NUDGE = -.1f; + if (AllItems.FILTER.get() == item) + return NUDGE; + if (item instanceof BlockItem) { + Block block = ((BlockItem) item).getBlock(); + if (block instanceof CogWheelBlock) + return NUDGE; + if (block instanceof FenceBlock) + return NUDGE; + if (block == Blocks.END_ROD) + return NUDGE; + } + return 0; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/AutoExtractingBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/AutoExtractingBehaviour.java index cb9d0acd2..6cd639b3d 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/AutoExtractingBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/AutoExtractingBehaviour.java @@ -22,12 +22,14 @@ public class AutoExtractingBehaviour extends ExtractingBehaviour { private int timer; Supplier shouldExtract; Supplier shouldPause; + private boolean ticking; public AutoExtractingBehaviour(SmartTileEntity te, Supplier>> attachments, Consumer onExtract, int delay) { super(te, attachments, onExtract); shouldPause = () -> false; shouldExtract = () -> true; + ticking = true; this.delay = delay; } @@ -47,16 +49,22 @@ public class AutoExtractingBehaviour extends ExtractingBehaviour { } @Override - public boolean extract() { + public boolean extract(int amount) { timer = delay; - return super.extract(); + return super.extract(amount); } @Override public void tick() { super.tick(); + + if (!ticking) + return; + + if (getWorld().isRemote) + return; - if (shouldPause.get()) { + if (getShouldPause().get()) { timer = 0; return; } @@ -66,15 +74,27 @@ public class AutoExtractingBehaviour extends ExtractingBehaviour { return; } - if (!shouldExtract.get()) + if (!getShouldExtract().get()) return; extract(); } + + public void setTicking(boolean ticking) { + this.ticking = ticking; + } @Override public IBehaviourType getType() { return TYPE; } + public Supplier getShouldExtract() { + return shouldExtract; + } + + public Supplier getShouldPause() { + return shouldPause; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/ExtractingBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/ExtractingBehaviour.java index 4309d2ede..9a2a5714a 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/ExtractingBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/ExtractingBehaviour.java @@ -2,6 +2,7 @@ package com.simibubi.create.foundation.behaviour.inventory; import java.util.List; import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; @@ -22,43 +23,60 @@ public class ExtractingBehaviour extends InventoryManagementBehaviour { public static IBehaviourType TYPE = new IBehaviourType() { }; - private Predicate extractionFilter; + private Function customAmountFilter; + private Predicate customFilter; private Consumer callback; public ExtractingBehaviour(SmartTileEntity te, Supplier>> attachments, Consumer onExtract) { super(te, attachments); - extractionFilter = stack -> true; + customAmountFilter = stack -> 64; + customFilter = stack -> true; callback = onExtract; } - public ExtractingBehaviour withSpecialFilter(Predicate filter) { - this.extractionFilter = filter; + public ExtractingBehaviour withAmountThreshold(Function filter) { + this.customAmountFilter = filter; return this; } - + + public ExtractingBehaviour withAdditionalFilter(Predicate filter) { + this.customFilter = filter; + return this; + } + public boolean extract() { - if (getWorld().isRemote) - return false; - int amount = -1; - Predicate test = extractionFilter; - FilteringBehaviour filter = get(tileEntity, FilteringBehaviour.TYPE); if (filter != null) { ItemStack filterItem = filter.getFilter(); amount = filterItem.isEmpty() ? -1 : filterItem.getCount(); - test = extractionFilter.and(filter::test); } + return extract(amount); + } + + public boolean extract(int exactAmount) { + if (getWorld().isRemote) + return false; + + Predicate test = customFilter; + FilteringBehaviour filter = get(tileEntity, FilteringBehaviour.TYPE); + if (filter != null) + test = customFilter.and(filter::test); for (IItemHandler inv : getInventories()) { - ItemStack extract = ItemHelper.extract(inv, test, amount, false); + ItemStack extract = ItemStack.EMPTY; + if (exactAmount != -1) + extract = ItemHelper.extract(inv, test, exactAmount, false); + else + extract = ItemHelper.extract(inv, test, customAmountFilter, false); + if (!extract.isEmpty()) { callback.accept(extract); return true; } } - + return false; } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/SingleTargetAutoExtractingBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/SingleTargetAutoExtractingBehaviour.java index d4a999eaa..37b6f65e8 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/SingleTargetAutoExtractingBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/SingleTargetAutoExtractingBehaviour.java @@ -7,6 +7,7 @@ import com.simibubi.create.foundation.behaviour.base.IBehaviourType; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; @@ -32,6 +33,18 @@ public class SingleTargetAutoExtractingBehaviour extends AutoExtractingBehaviour return this; } + @Override + public void writeNBT(CompoundNBT nbt) { + nbt.putBoolean("Advantage", advantageOnNextSync); + super.writeNBT(nbt); + } + + @Override + public void readNBT(CompoundNBT nbt) { + advantageOnNextSync = nbt.getBoolean("Advantage"); + super.readNBT(nbt); + } + @Override public boolean extract() { if (synced) { diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/SynchronizedExtraction.java b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/SynchronizedExtraction.java index 92da9bc05..34407b2c9 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/SynchronizedExtraction.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/SynchronizedExtraction.java @@ -53,9 +53,9 @@ public class SynchronizedExtraction { continue; if (!behaviour.synced) continue; - if (behaviour.shouldPause.get()) + if (behaviour.getShouldPause().get()) continue; - if (!behaviour.shouldExtract.get()) + if (!behaviour.getShouldExtract().get()) continue; if (!behaviour.inventories.keySet().stream() .anyMatch(p -> p.getKey().add(behaviour.getPos()).equals(pos))) diff --git a/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java b/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java index 063891818..01db1b043 100644 --- a/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java +++ b/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java @@ -2,6 +2,7 @@ package com.simibubi.create.foundation.item; import java.util.ArrayList; import java.util.List; +import java.util.function.Function; import java.util.function.Predicate; import org.apache.commons.lang3.mutable.MutableInt; @@ -134,11 +135,48 @@ public class ItemHelper { else break Extraction; } while (true); - + if (amountRequired && extracting.getCount() < exactAmount) return ItemStack.EMPTY; return extracting; } + public static ItemStack extract(IItemHandler inv, Predicate test, + Function amountFunction, boolean simulate) { + ItemStack extracting = ItemStack.EMPTY; + int maxExtractionCount = CreateConfig.parameters.extractorAmount.get(); + + for (int slot = 0; slot < inv.getSlots(); slot++) { + if (extracting.isEmpty()) { + ItemStack stackInSlot = inv.getStackInSlot(slot); + if (stackInSlot.isEmpty()) + continue; + int maxExtractionCountForItem = amountFunction.apply(stackInSlot); + if (maxExtractionCountForItem == 0) + continue; + maxExtractionCount = Math.min(maxExtractionCount, maxExtractionCountForItem); + } + + ItemStack stack = inv.extractItem(slot, maxExtractionCount - extracting.getCount(), true); + + if (!test.test(stack)) + continue; + if (!extracting.isEmpty() && !ItemHandlerHelper.canItemStacksStack(stack, extracting)) + continue; + + if (extracting.isEmpty()) + extracting = stack.copy(); + else + extracting.grow(stack.getCount()); + + if (!simulate) + inv.extractItem(slot, stack.getCount(), false); + if (extracting.getCount() == maxExtractionCount) + break; + } + + return extracting; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java b/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java index 472666268..904c55da3 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/TessellatorHelper.java @@ -45,6 +45,15 @@ public class TessellatorHelper { GlStateManager.color3f(1, 1, 1); } + + public static void fightZFighting(int id) { + long randomBits = (long) id * 493286711L; + randomBits = randomBits * randomBits * 4392167121L + randomBits * 98761L; + float xNudge = (((float) (randomBits >> 16 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F; + float yNudge = (((float) (randomBits >> 20 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F; + float zNudge = (((float) (randomBits >> 24 & 7L) + 0.5F) / 8.0F - 0.5F) * 0.004F; + GlStateManager.translatef(xNudge, yNudge, zNudge); + } public static void begin() { begin(DefaultVertexFormats.POSITION_TEX); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/AllBeltAttachments.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/AllBeltAttachments.java index 2373205ff..f6554b17f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/AllBeltAttachments.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/AllBeltAttachments.java @@ -1,6 +1,6 @@ package com.simibubi.create.modules.contraptions.relays.belt; -import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.function.Consumer; @@ -23,6 +23,7 @@ public enum AllBeltAttachments { BELT_FUNNEL(AllBlocks.BELT_FUNNEL), BELT_OBSERVER(AllBlocks.ENTITY_DETECTOR), MECHANICAL_PRESS(AllBlocks.MECHANICAL_PRESS), + LOGISTICAL_ATTACHABLES(AllBlocks.EXTRACTOR), ; @@ -38,8 +39,8 @@ public enum AllBeltAttachments { public BlockPos getBeltPositionForAttachment(IWorld world, BlockPos pos, BlockState state); - default boolean isAttachedCorrectly(IWorld world, BlockPos attachmentPos, BlockPos beltPos, BlockState attachmentState, - BlockState beltState) { + default boolean isAttachedCorrectly(IWorld world, BlockPos attachmentPos, BlockPos beltPos, + BlockState attachmentState, BlockState beltState) { return true; } @@ -47,7 +48,8 @@ public enum AllBeltAttachments { return false; } - default boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) { + default boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, + BeltAttachmentState state) { return false; } @@ -101,7 +103,7 @@ public enum AllBeltAttachments { private BeltTileEntity te; public Tracker(BeltTileEntity te) { - attachments = new ArrayList<>(0); + attachments = new LinkedList<>(); this.te = te; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltInventory.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltInventory.java index 2860414d2..abaefb46f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltInventory.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltInventory.java @@ -60,6 +60,7 @@ public class BeltInventory { Iterator iterator = items.iterator(); float beltSpeed = belt.getDirectionAwareBeltMovementSpeed(); + Direction movementFacing = belt.getMovementFacing(); float spacing = 1; Items: while (iterator.hasNext()) { @@ -111,12 +112,16 @@ public class BeltInventory { if (beltSegment != null) { current.locked = false; - for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) { + List attachments = beltSegment.attachmentTracker.attachments; + for (BeltAttachmentState attachmentState : attachments) { if (attachmentState.attachment.processItem(beltSegment, current, attachmentState)) current.locked = true; } - if (!current.locked || current.stack.isEmpty()) + if (!current.locked || current.stack.isEmpty()) { + if (!attachments.isEmpty()) + attachments.add(attachments.remove(0)); belt.sendData(); + } continue; } } @@ -140,17 +145,17 @@ public class BeltInventory { } // Belt tunnels - { + if (!onClient) { int seg1 = (int) current.beltPosition; int seg2 = (int) nextOffset; if (!beltMovementPositive && nextOffset == 0) seg2 = -1; if (seg1 != seg2) { - if (stuckAtTunnel(seg2, current.stack, belt.getMovementFacing())) { + if (stuckAtTunnel(seg2, current.stack, movementFacing)) { continue; } - flapTunnel(seg1, belt.getMovementFacing(), false); - flapTunnel(seg2, belt.getMovementFacing().getOpposite(), true); + flapTunnel(seg1, movementFacing, false); + flapTunnel(seg2, movementFacing.getOpposite(), true); } } @@ -186,7 +191,6 @@ public class BeltInventory { int lastOffset = beltMovementPositive ? belt.beltLength - 1 : 0; BlockPos nextPosition = getPositionForOffset(beltMovementPositive ? belt.beltLength : -1); BlockState state = world.getBlockState(nextPosition); - Direction movementFacing = belt.getMovementFacing(); // next block is a basin or a saw if (AllBlocks.BASIN.typeOf(state) || AllBlocks.SAW.typeOf(state)) { @@ -205,7 +209,7 @@ public class BeltInventory { if (remainder.isEmpty()) { iterator.remove(); current = null; - flapTunnel(lastOffset, belt.getMovementFacing(), false); + flapTunnel(lastOffset, movementFacing, false); } belt.sendData(); @@ -220,7 +224,7 @@ public class BeltInventory { eject(current); iterator.remove(); current = null; - flapTunnel(lastOffset, belt.getMovementFacing(), false); + flapTunnel(lastOffset, movementFacing, false); belt.sendData(); } continue; @@ -241,7 +245,7 @@ public class BeltInventory { if (nextBelt.tryInsertingFromSide(movementFacing, current, false)) { iterator.remove(); current = null; - flapTunnel(lastOffset, belt.getMovementFacing(), false); + flapTunnel(lastOffset, movementFacing, false); belt.sendData(); } @@ -298,8 +302,6 @@ public class BeltInventory { TileEntity te = belt.getWorld().getTileEntity(pos); if (te == null || !(te instanceof BeltTunnelTileEntity)) return; - if (side.getAxis() == Axis.Z) - side = side.getOpposite(); ((BeltTunnelTileEntity) te).flap(side, inward ^ side.getAxis() == Axis.Z); } @@ -308,24 +310,19 @@ public class BeltInventory { } public boolean canInsertFrom(int segment, Direction side) { - float min = segment + .5f - (SEGMENT_WINDOW / 2); - float max = segment + .5f + (SEGMENT_WINDOW / 2); + float segmentPos = segment; + if (belt.getMovementFacing() == side.getOpposite()) + return false; + if (belt.getMovementFacing() != side) + segmentPos += .5f; + else if (!beltMovementPositive) + segmentPos += 1f; for (TransportedItemStack stack : items) { float currentPos = stack.beltPosition; - // Searched past relevant stacks - if (beltMovementPositive ? currentPos < segment : currentPos - 1 > segment) - break; - - // Item inside extraction window - if (currentPos > min && currentPos < max) - return false; - - // Items on the belt get prioritized if the previous item was inserted on the - // same segment if (stack.insertedAt == segment && stack.insertedFrom == side - && (beltMovementPositive ? currentPos <= segment + 1.5 : currentPos - 1.5 >= segment)) + && (beltMovementPositive ? currentPos <= segmentPos + 1 : currentPos >= segmentPos - 1)) return false; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java index 6df2fc7fa..c5024c8a4 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java @@ -47,6 +47,7 @@ public class BeltTileEntity extends KineticTileEntity { public int color; public int beltLength; public int index; + public Direction lastInsert; protected BlockPos controller; protected BeltInventory inventory; @@ -272,8 +273,9 @@ public class BeltTileEntity extends KineticTileEntity { } public Direction getMovementFacing() { - return Direction.getFacingFromAxisDirection(getBeltFacing().getAxis(), - getBeltMovementSpeed() < 0 ? POSITIVE : NEGATIVE); + Axis axis = getBeltFacing().getAxis(); + return Direction.getFacingFromAxisDirection(axis, + getBeltMovementSpeed() < 0 ^ axis == Axis.X ? NEGATIVE : POSITIVE); } protected Direction getBeltFacing() { @@ -296,21 +298,23 @@ public class BeltTileEntity extends KineticTileEntity { return false; BeltInventory nextInventory = nextBeltController.getInventory(); + if (getSpeed() == 0) + return false; if (!nextInventory.canInsertFrom(index, side)) return false; if (simulate) return true; - transportedStack.beltPosition = index + .5f; + transportedStack.beltPosition = index + .5f - Math.signum(getSpeed()) / 16f; Direction movementFacing = getMovementFacing(); if (!side.getAxis().isVertical()) { - if (movementFacing != side) + if (movementFacing != side) { transportedStack.sideOffset = side.getAxisDirection().getOffset() * .35f; - else + if (side.getAxis() == Axis.X) + transportedStack.sideOffset *= -1; + } else transportedStack.beltPosition = getDirectionAwareBeltMovementSpeed() > 0 ? index : index + 1; - if (side.getAxis() == Axis.X ^ movementFacing.getAxis() == Axis.X) - transportedStack.sideOffset *= -1; } transportedStack.prevSideOffset = transportedStack.sideOffset; @@ -321,17 +325,6 @@ public class BeltTileEntity extends KineticTileEntity { nextBeltController.markDirty(); nextBeltController.sendData(); - if (side.getAxis().isHorizontal()) { - if (AllBlocks.BELT_TUNNEL.typeOf(world.getBlockState(pos.up()))) { - TileEntity tileEntity = world.getTileEntity(pos.up()); - if (tileEntity != null && tileEntity instanceof BeltTunnelTileEntity) { - if (side.getAxis() == Axis.X) - side = side.getOpposite(); - ((BeltTunnelTileEntity) tileEntity).flap(side, side.getAxis() == Axis.X); - } - } - } - return true; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntityRenderer.java index 4b97bf555..570df9de4 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntityRenderer.java @@ -98,6 +98,7 @@ public class BeltTileEntityRenderer extends TileEntityRenderer { for (TransportedItemStack transported : te.getInventory().items) { GlStateManager.pushMatrix(); + TessellatorHelper.fightZFighting(transported.angle); float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition); float sideOffset = MathHelper.lerp(partialTicks, transported.prevSideOffset, transported.sideOffset); float verticalMovement = verticality; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTunnelTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTunnelTileEntity.java index bdfa22721..5fd34ba36 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTunnelTileEntity.java @@ -1,6 +1,10 @@ package com.simibubi.create.modules.contraptions.relays.belt; import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTileEntities; @@ -11,6 +15,8 @@ import com.simibubi.create.modules.contraptions.relays.belt.BeltTunnelBlock.Shap import net.minecraft.block.BlockState; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.INBT; +import net.minecraft.nbt.ListNBT; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntity; @@ -19,6 +25,7 @@ import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.AxisDirection; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; @@ -29,14 +36,14 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT private LazyOptional cap = LazyOptional.empty(); private boolean initialize; - private Direction flapToSend; - private boolean flapInward; + private List> flapsToSend; public BeltTunnelTileEntity() { super(AllTileEntities.BELT_TUNNEL.type); flaps = new HashMap<>(); syncedFlaps = new HashMap<>(); initialize = true; + flapsToSend = new LinkedList<>(); } @Override @@ -91,7 +98,7 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT public boolean toggleSyncForFlap(Direction face) { if (!flaps.containsKey(face)) return false; - if (syncedFlaps.containsKey(face)) + if (syncedFlaps.containsKey(face)) syncedFlaps.remove(face); else syncedFlaps.put(face, ItemStack.EMPTY); @@ -103,10 +110,16 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT @Override public CompoundNBT writeToClient(CompoundNBT tag) { CompoundNBT writeToClient = super.writeToClient(tag); - if (flapToSend != null) { - writeToClient.putInt("Flap", flapToSend.getIndex()); - writeToClient.putBoolean("FlapInward", flapInward); - flapToSend = null; + if (!flapsToSend.isEmpty()) { + ListNBT flapsNBT = new ListNBT(); + for (Pair pair : flapsToSend) { + CompoundNBT flap = new CompoundNBT(); + flap.putInt("Flap", pair.getKey().getIndex()); + flap.putBoolean("FlapInward", pair.getValue()); + flapsNBT.add(flap); + } + writeToClient.put("Flaps", flapsNBT); + flapsToSend.clear(); } return writeToClient; } @@ -114,9 +127,13 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT @Override public void readClientUpdate(CompoundNBT tag) { super.readClientUpdate(tag); - if (tag.contains("Flap")) { - Direction side = Direction.byIndex(tag.getInt("Flap")); - flap(side, tag.getBoolean("FlapInward")); + if (tag.contains("Flaps")) { + ListNBT flapsNBT = tag.getList("Flaps", NBT.TAG_COMPOUND); + for (INBT inbt : flapsNBT) { + CompoundNBT flap = (CompoundNBT) inbt; + Direction side = Direction.byIndex(flap.getInt("Flap")); + flap(side, flap.getBoolean("FlapInward")); + } } else initFlaps(); } @@ -156,17 +173,18 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT return; } - flapToSend = side; - flapInward = inward; - sendData(); + flapsToSend.add(Pair.of(side, inward)); } @Override public void tick() { if (initialize) initFlaps(); - if (!world.isRemote) + if (!world.isRemote) { + if (!flapsToSend.isEmpty()) + sendData(); return; + } flaps.forEach((d, value) -> value.tick()); } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/ItemHandlerBeltSegment.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/ItemHandlerBeltSegment.java index dc930066c..8a1884b03 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/ItemHandlerBeltSegment.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/ItemHandlerBeltSegment.java @@ -4,7 +4,7 @@ import net.minecraft.item.ItemStack; import net.minecraftforge.items.IItemHandler; public class ItemHandlerBeltSegment implements IItemHandler { - + private final BeltInventory beltInventory; int offset; @@ -32,7 +32,7 @@ public class ItemHandlerBeltSegment implements IItemHandler { if (!simulate) { TransportedItemStack newStack = new TransportedItemStack(stack); newStack.insertedAt = offset; - newStack.beltPosition = offset + .5f; + newStack.beltPosition = offset + .5f + (beltInventory.beltMovementPositive ? -1 : 1) / 16f; newStack.prevBeltPosition = newStack.beltPosition; this.beltInventory.insert(newStack); this.beltInventory.belt.markDirty(); diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/ExtractorForBeltsBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltAttachableLogisticalBlock.java similarity index 72% rename from src/main/java/com/simibubi/create/modules/logistics/block/belts/ExtractorForBeltsBlock.java rename to src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltAttachableLogisticalBlock.java index 5b1f9f3bf..df8d652f3 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/belts/ExtractorForBeltsBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltAttachableLogisticalBlock.java @@ -6,11 +6,11 @@ import java.util.stream.Collectors; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; -import com.simibubi.create.foundation.behaviour.inventory.ExtractingBehaviour; -import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; -import com.simibubi.create.modules.contraptions.relays.belt.TransportedItemStack; +import com.simibubi.create.foundation.behaviour.inventory.SingleTargetAutoExtractingBehaviour; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment; +import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; +import com.simibubi.create.modules.contraptions.relays.belt.TransportedItemStack; import net.minecraft.block.BlockState; import net.minecraft.item.ItemStack; @@ -19,7 +19,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.IWorld; import net.minecraft.world.World; -public abstract class ExtractorForBeltsBlock extends AttachedLogisticalBlock implements IBeltAttachment { +public abstract class BeltAttachableLogisticalBlock extends AttachedLogisticalBlock implements IBeltAttachment { @Override public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { @@ -51,7 +51,8 @@ public abstract class ExtractorForBeltsBlock extends AttachedLogisticalBlock imp ItemStack stack = transported.stack; FilteringBehaviour filtering = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE); - ExtractingBehaviour extracting = TileEntityBehaviour.get(world, pos, ExtractingBehaviour.TYPE); + SingleTargetAutoExtractingBehaviour extracting = TileEntityBehaviour.get(world, pos, + SingleTargetAutoExtractingBehaviour.TYPE); if (extracting == null) return false; @@ -64,12 +65,23 @@ public abstract class ExtractorForBeltsBlock extends AttachedLogisticalBlock imp public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) { BlockPos pos = state.attachmentPos; World world = te.getWorld(); - ExtractingBehaviour extracting = TileEntityBehaviour.get(world, pos, ExtractingBehaviour.TYPE); - + ItemStack stack = transported.stack; + + SingleTargetAutoExtractingBehaviour extracting = TileEntityBehaviour.get(world, pos, + SingleTargetAutoExtractingBehaviour.TYPE); + if (extracting == null) return false; - extracting.extract(); - return false; + if (extracting.getShouldPause().get()) + return false; + + FilteringBehaviour filtering = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE); + if (filtering != null && (!filtering.test(stack) || stack.getCount() < filtering.getFilter().getCount())) + return false; + if (!extracting.getShouldExtract().get()) + return !filtering.getFilter().isEmpty(); + + return !extracting.extractFromInventory(); } } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelBlock.java index 0685b1ab6..72b77f7bc 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelBlock.java @@ -1,6 +1,7 @@ package com.simibubi.create.modules.logistics.block.belts; import java.util.Arrays; +import java.util.Collections; import java.util.List; import com.simibubi.create.AllBlocks; @@ -21,7 +22,6 @@ import net.minecraft.state.BooleanProperty; import net.minecraft.state.StateContainer.Builder; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; -import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; @@ -29,8 +29,7 @@ import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorld; import net.minecraft.world.World; -public class FunnelBlock extends AttachedLogisticalBlock - implements IBeltAttachment, IWithTileEntity { +public class FunnelBlock extends AttachedLogisticalBlock implements IBeltAttachment, IWithTileEntity { public static final BooleanProperty BELT = BooleanProperty.create("belt"); @@ -55,7 +54,7 @@ public class FunnelBlock extends AttachedLogisticalBlock protected boolean isVertical() { return false; } - + @Override public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) { if (worldIn.isRemote) @@ -111,6 +110,22 @@ public class FunnelBlock extends AttachedLogisticalBlock @Override public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { onAttachmentPlaced(worldIn, pos, state); + + if (isOnBelt(worldIn, pos)) { + TileEntity te = worldIn.getTileEntity(pos.down()); + if (!(te instanceof BeltTileEntity)) + return; + BeltTileEntity belt = (BeltTileEntity) te; + BeltTileEntity controllerBelt = belt.getControllerTE(); + if (controllerBelt == null) + return; + if (worldIn.isRemote) + return; + controllerBelt.getInventory().forEachWithin(belt.index + .5f, .55f, (transportedItemStack) -> { + controllerBelt.getInventory().eject(transportedItemStack); + return Collections.emptyList(); + }); + } } @Override @@ -145,8 +160,6 @@ public class FunnelBlock extends AttachedLogisticalBlock @Override public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) { Direction movementFacing = te.getMovementFacing(); - if (movementFacing.getAxis() == Axis.Z) - movementFacing = movementFacing.getOpposite(); if (movementFacing != te.getWorld().getBlockState(state.attachmentPos).get(HORIZONTAL_FACING)) return false; return process(te, transported, state); @@ -168,5 +181,5 @@ public class FunnelBlock extends AttachedLogisticalBlock return true; } } - + } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelTileEntity.java index e6aab658d..04d9fb949 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelTileEntity.java @@ -2,6 +2,7 @@ package com.simibubi.create.modules.logistics.block.belts; import java.util.List; +import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTileEntities; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; @@ -11,6 +12,7 @@ import com.simibubi.create.foundation.behaviour.inventory.InsertingBehaviour; import com.simibubi.create.foundation.behaviour.inventory.InventoryManagementBehaviour.Attachments; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock; import net.minecraft.item.ItemStack; @@ -18,10 +20,12 @@ import net.minecraft.nbt.CompoundNBT; import net.minecraft.particles.ItemParticleData; import net.minecraft.particles.ParticleTypes; import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvents; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; @@ -79,7 +83,16 @@ public class FunnelTileEntity extends SmartTileEntity { if (!filtering.test(stack)) return stack; - ItemStack remainder = inserting.insert(stack.copy(), false); + ItemStack remainder = ItemStack.EMPTY; + + BeltTileEntity targetingBelt = getTargetingBelt(); + if (targetingBelt != null) { + Direction facing = AttachedLogisticalBlock.getBlockFacing(getBlockState()); + if (!targetingBelt.tryInsertingFromSide(facing, stack.copy(), false)) + remainder = stack; + } else { + remainder = inserting.insert(stack.copy(), false); + } if (remainder.isEmpty()) { if (!world.isRemote) @@ -87,10 +100,22 @@ public class FunnelTileEntity extends SmartTileEntity { justEaten = stack.copy(); } - sendData(); + if (remainder.getCount() != stack.getCount()) + sendData(); + return remainder; } + protected BeltTileEntity getTargetingBelt() { + BlockPos targetPos = pos.offset(AttachedLogisticalBlock.getBlockFacing(getBlockState())); + if (!AllBlocks.BELT.typeOf(world.getBlockState(targetPos))) + return null; + TileEntity te = world.getTileEntity(targetPos); + if (te == null || !(te instanceof BeltTileEntity)) + return null; + return (BeltTileEntity) te; + } + public void spawnParticles(ItemStack stack) { Vec3i directionVec = getBlockState().get(BlockStateProperties.HORIZONTAL_FACING).getDirectionVec(); float xSpeed = directionVec.getX() * 1 / 8f; diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorBlock.java index 030aaa353..6cf6ca55f 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorBlock.java @@ -5,6 +5,7 @@ import com.simibubi.create.foundation.utility.AllShapes; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock; +import com.simibubi.create.modules.logistics.block.belts.BeltAttachableLogisticalBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -21,7 +22,7 @@ import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; -public class ExtractorBlock extends AttachedLogisticalBlock { +public class ExtractorBlock extends BeltAttachableLogisticalBlock { public static BooleanProperty POWERED = BlockStateProperties.POWERED; diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorTileEntity.java index 8d1aed68c..ae11ddf36 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorTileEntity.java @@ -9,9 +9,11 @@ import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning; +import com.simibubi.create.foundation.behaviour.inventory.AutoExtractingBehaviour; import com.simibubi.create.foundation.behaviour.inventory.ExtractingBehaviour; import com.simibubi.create.foundation.behaviour.inventory.SingleTargetAutoExtractingBehaviour; import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock; import com.simibubi.create.modules.logistics.item.CardboardBoxItem; @@ -34,6 +36,7 @@ public class ExtractorTileEntity extends SmartTileEntity { protected ExtractingBehaviour extracting; protected FilteringBehaviour filtering; + protected boolean extractingToBelt; public ExtractorTileEntity() { this(AllTileEntities.EXTRACTOR.type); @@ -80,6 +83,20 @@ public class ExtractorTileEntity extends SmartTileEntity { world.addEntity(entityIn); } + protected boolean isAttachedToBelt() { + Direction blockFacing = AttachedLogisticalBlock.getBlockFacing(getBlockState()); + return AllBlocks.BELT.typeOf(world.getBlockState(pos.offset(blockFacing))); + } + + protected boolean isTargetingBelt() { + if (!AllBlocks.BELT.typeOf(world.getBlockState(pos.down()))) + return false; + TileEntity te = world.getTileEntity(pos.down()); + if (te == null || !(te instanceof BeltTileEntity)) + return false; + return ((KineticTileEntity) te).getSpeed() != 0; + } + protected boolean isPowered() { return getBlockState().get(ExtractorBlock.POWERED); } @@ -104,4 +121,15 @@ public class ExtractorTileEntity extends SmartTileEntity { return world.getEntitiesWithinAABBExcludingEntity(null, new AxisAlignedBB(getPos())).isEmpty(); } + @Override + public void tick() { + ((AutoExtractingBehaviour) extracting).setTicking(!isAttachedToBelt()); + super.tick(); + boolean onBelt = isTargetingBelt(); + if (extractingToBelt != onBelt) { + extractingToBelt = onBelt; + ((AutoExtractingBehaviour) extracting).setDelay(onBelt ? 0 : CreateConfig.parameters.extractorDelay.get()); + } + } + } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerBlock.java index 2a2c1b238..e0e44197d 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerBlock.java @@ -2,7 +2,7 @@ package com.simibubi.create.modules.logistics.block.transposer; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.utility.AllShapes; -import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock; +import com.simibubi.create.modules.logistics.block.belts.BeltAttachableLogisticalBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -19,7 +19,7 @@ import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; -public class TransposerBlock extends AttachedLogisticalBlock { +public class TransposerBlock extends BeltAttachableLogisticalBlock { public static BooleanProperty POWERED = BlockStateProperties.POWERED; diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerTileEntity.java index de129731b..2bce19482 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerTileEntity.java @@ -2,15 +2,21 @@ package com.simibubi.create.modules.logistics.block.transposer; import java.util.List; +import com.simibubi.create.AllBlocks; import com.simibubi.create.AllTileEntities; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.inventory.InsertingBehaviour; import com.simibubi.create.foundation.behaviour.inventory.InventoryManagementBehaviour.Attachments; +import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock; import com.simibubi.create.modules.logistics.block.extractor.ExtractorTileEntity; import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; import net.minecraftforge.items.ItemHandlerHelper; public class TransposerTileEntity extends ExtractorTileEntity { @@ -31,18 +37,42 @@ public class TransposerTileEntity extends ExtractorTileEntity { inserting = new InsertingBehaviour(this, Attachments.toward(() -> AttachedLogisticalBlock.getBlockFacing(getBlockState()).getOpposite())); behaviours.add(inserting); - extracting.withSpecialFilter(this::shouldExtract); + extracting.withAmountThreshold(this::amountToExtract).withAdditionalFilter(this::shouldExtract); } public void filterChanged(ItemStack stack) { } + protected int amountToExtract(ItemStack stack) { + ItemStack tester = stack.copy(); + tester.setCount(64); + return 64 - inserting.insert(tester, true).getCount(); + } + protected boolean shouldExtract(ItemStack stack) { + if (isTargetingBelt()) { + Direction facing = AttachedLogisticalBlock.getBlockFacing(getBlockState()).getOpposite(); + BlockPos targetPos = pos.offset(facing); + BeltTileEntity te = (BeltTileEntity) world.getTileEntity(targetPos); + return te.tryInsertingFromSide(facing, stack, true); + } + if (filtering.getFilter().isEmpty()) return true; return inserting.insert(stack, true).isEmpty(); } - + + @Override + protected boolean isTargetingBelt() { + BlockPos targetPos = pos.offset(AttachedLogisticalBlock.getBlockFacing(getBlockState()).getOpposite()); + if (!AllBlocks.BELT.typeOf(world.getBlockState(targetPos))) + return false; + TileEntity te = world.getTileEntity(targetPos); + if (te == null || !(te instanceof BeltTileEntity)) + return false; + return ((KineticTileEntity) te).getSpeed() != 0; + } + @Override protected boolean canExtract() { return inserting.getInventory() != null; @@ -50,8 +80,17 @@ public class TransposerTileEntity extends ExtractorTileEntity { @Override protected void onExtract(ItemStack stack) { + if (isTargetingBelt()) { + Direction facing = AttachedLogisticalBlock.getBlockFacing(getBlockState()).getOpposite(); + BlockPos targetPos = pos.offset(facing); + BeltTileEntity te = (BeltTileEntity) world.getTileEntity(targetPos); + if (te.tryInsertingFromSide(facing, stack, false)) + return; + } + ItemStack remainder = inserting.insert(stack, false); - remainder = ItemHandlerHelper.insertItemStacked(extracting.getInventory(), remainder, false); + if (!remainder.isEmpty()) + remainder = ItemHandlerHelper.insertItemStacked(extracting.getInventory(), remainder, false); if (!remainder.isEmpty()) super.onExtract(remainder); }