Dreaming of Belts

- Extractors and Transposers now work when attached on belt casing
- Removed extraction delay for extractors putting items on belts
- Funnels and transposers now insert onto belts with their corresponding input direction
- Chained belts no longer space items out to 1.5m
- Belts now merge items properly
- Extractors, funnels and Transposers now take turns when inserting to/extracting from belts
- Inserting items on a segment no longer skips belt attachment processing
- Fixed belt tunnels not flapping properly when items are exactly 1m apart
- Overlapping items on merging belts should now have less z-fighting issues
- Fixed Transposers pulling more items than it can insert
- Fixed a few items in value boxes not displaying properly
This commit is contained in:
simibubi 2020-01-14 20:48:43 +01:00
parent 07ef48fefb
commit dea7a9869f
21 changed files with 363 additions and 113 deletions

View file

@ -99,10 +99,6 @@ import net.minecraftforge.registries.IForgeRegistry;
public enum AllBlocks { public enum AllBlocks {
__MATERIALS__(),
COPPER_ORE(new CopperOreBlock()),
ZINC_ORE(new Block(Properties.from(Blocks.GOLD_ORE))),
__SCHEMATICS__(), __SCHEMATICS__(),
SCHEMATICANNON(new SchematicannonBlock()), SCHEMATICANNON(new SchematicannonBlock()),
SCHEMATICANNON_CONNECTOR(new RenderUtilityBlock()), SCHEMATICANNON_CONNECTOR(new RenderUtilityBlock()),
@ -241,6 +237,10 @@ public enum AllBlocks {
VOLCANIC_ROCK(new VolcanicRockBlock()), VOLCANIC_ROCK(new VolcanicRockBlock()),
__MATERIALS__(),
COPPER_ORE(new CopperOreBlock()),
ZINC_ORE(new Block(Properties.from(Blocks.GOLD_ORE))),
; ;
private enum ComesWith { private enum ComesWith {

View file

@ -1,10 +1,15 @@
package com.simibubi.create.foundation.behaviour; package com.simibubi.create.foundation.behaviour;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.behaviour.ValueBox.ItemValueBox; import com.simibubi.create.foundation.behaviour.ValueBox.ItemValueBox;
import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.TessellatorHelper; 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.Minecraft;
import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.BufferBuilder; 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.IBakedModel;
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType; import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; 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.item.ItemStack;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -73,10 +80,26 @@ public class ValueBoxRenderer {
IBakedModel modelWithOverrides = itemRenderer.getModelWithOverrides(filter); IBakedModel modelWithOverrides = itemRenderer.getModelWithOverrides(filter);
boolean blockItem = modelWithOverrides.isGui3d(); boolean blockItem = modelWithOverrides.isGui3d();
float scale = (!blockItem ? .5f : 1f) - 1 / 64f; 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.scaled(scale, scale, scale);
GlStateManager.translated(0, 0, zOffset); GlStateManager.translated(0, 0, zOffset);
itemRenderer.renderItem(filter, TransformType.FIXED); 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;
}
} }

View file

@ -22,12 +22,14 @@ public class AutoExtractingBehaviour extends ExtractingBehaviour {
private int timer; private int timer;
Supplier<Boolean> shouldExtract; Supplier<Boolean> shouldExtract;
Supplier<Boolean> shouldPause; Supplier<Boolean> shouldPause;
private boolean ticking;
public AutoExtractingBehaviour(SmartTileEntity te, Supplier<List<Pair<BlockPos, Direction>>> attachments, public AutoExtractingBehaviour(SmartTileEntity te, Supplier<List<Pair<BlockPos, Direction>>> attachments,
Consumer<ItemStack> onExtract, int delay) { Consumer<ItemStack> onExtract, int delay) {
super(te, attachments, onExtract); super(te, attachments, onExtract);
shouldPause = () -> false; shouldPause = () -> false;
shouldExtract = () -> true; shouldExtract = () -> true;
ticking = true;
this.delay = delay; this.delay = delay;
} }
@ -47,16 +49,22 @@ public class AutoExtractingBehaviour extends ExtractingBehaviour {
} }
@Override @Override
public boolean extract() { public boolean extract(int amount) {
timer = delay; timer = delay;
return super.extract(); return super.extract(amount);
} }
@Override @Override
public void tick() { public void tick() {
super.tick(); super.tick();
if (!ticking)
return;
if (getWorld().isRemote)
return;
if (shouldPause.get()) { if (getShouldPause().get()) {
timer = 0; timer = 0;
return; return;
} }
@ -66,15 +74,27 @@ public class AutoExtractingBehaviour extends ExtractingBehaviour {
return; return;
} }
if (!shouldExtract.get()) if (!getShouldExtract().get())
return; return;
extract(); extract();
} }
public void setTicking(boolean ticking) {
this.ticking = ticking;
}
@Override @Override
public IBehaviourType<?> getType() { public IBehaviourType<?> getType() {
return TYPE; return TYPE;
} }
public Supplier<Boolean> getShouldExtract() {
return shouldExtract;
}
public Supplier<Boolean> getShouldPause() {
return shouldPause;
}
} }

View file

@ -2,6 +2,7 @@ package com.simibubi.create.foundation.behaviour.inventory;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -22,43 +23,60 @@ public class ExtractingBehaviour extends InventoryManagementBehaviour {
public static IBehaviourType<ExtractingBehaviour> TYPE = new IBehaviourType<ExtractingBehaviour>() { public static IBehaviourType<ExtractingBehaviour> TYPE = new IBehaviourType<ExtractingBehaviour>() {
}; };
private Predicate<ItemStack> extractionFilter; private Function<ItemStack, Integer> customAmountFilter;
private Predicate<ItemStack> customFilter;
private Consumer<ItemStack> callback; private Consumer<ItemStack> callback;
public ExtractingBehaviour(SmartTileEntity te, Supplier<List<Pair<BlockPos, Direction>>> attachments, public ExtractingBehaviour(SmartTileEntity te, Supplier<List<Pair<BlockPos, Direction>>> attachments,
Consumer<ItemStack> onExtract) { Consumer<ItemStack> onExtract) {
super(te, attachments); super(te, attachments);
extractionFilter = stack -> true; customAmountFilter = stack -> 64;
customFilter = stack -> true;
callback = onExtract; callback = onExtract;
} }
public ExtractingBehaviour withSpecialFilter(Predicate<ItemStack> filter) { public ExtractingBehaviour withAmountThreshold(Function<ItemStack, Integer> filter) {
this.extractionFilter = filter; this.customAmountFilter = filter;
return this; return this;
} }
public ExtractingBehaviour withAdditionalFilter(Predicate<ItemStack> filter) {
this.customFilter = filter;
return this;
}
public boolean extract() { public boolean extract() {
if (getWorld().isRemote)
return false;
int amount = -1; int amount = -1;
Predicate<ItemStack> test = extractionFilter;
FilteringBehaviour filter = get(tileEntity, FilteringBehaviour.TYPE); FilteringBehaviour filter = get(tileEntity, FilteringBehaviour.TYPE);
if (filter != null) { if (filter != null) {
ItemStack filterItem = filter.getFilter(); ItemStack filterItem = filter.getFilter();
amount = filterItem.isEmpty() ? -1 : filterItem.getCount(); 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<ItemStack> test = customFilter;
FilteringBehaviour filter = get(tileEntity, FilteringBehaviour.TYPE);
if (filter != null)
test = customFilter.and(filter::test);
for (IItemHandler inv : getInventories()) { 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()) { if (!extract.isEmpty()) {
callback.accept(extract); callback.accept(extract);
return true; return true;
} }
} }
return false; return false;
} }

View file

@ -7,6 +7,7 @@ import com.simibubi.create.foundation.behaviour.base.IBehaviourType;
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -32,6 +33,18 @@ public class SingleTargetAutoExtractingBehaviour extends AutoExtractingBehaviour
return this; 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 @Override
public boolean extract() { public boolean extract() {
if (synced) { if (synced) {

View file

@ -53,9 +53,9 @@ public class SynchronizedExtraction {
continue; continue;
if (!behaviour.synced) if (!behaviour.synced)
continue; continue;
if (behaviour.shouldPause.get()) if (behaviour.getShouldPause().get())
continue; continue;
if (!behaviour.shouldExtract.get()) if (!behaviour.getShouldExtract().get())
continue; continue;
if (!behaviour.inventories.keySet().stream() if (!behaviour.inventories.keySet().stream()
.anyMatch(p -> p.getKey().add(behaviour.getPos()).equals(pos))) .anyMatch(p -> p.getKey().add(behaviour.getPos()).equals(pos)))

View file

@ -2,6 +2,7 @@ package com.simibubi.create.foundation.item;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableInt;
@ -134,11 +135,48 @@ public class ItemHelper {
else else
break Extraction; break Extraction;
} while (true); } while (true);
if (amountRequired && extracting.getCount() < exactAmount) if (amountRequired && extracting.getCount() < exactAmount)
return ItemStack.EMPTY; return ItemStack.EMPTY;
return extracting; return extracting;
} }
public static ItemStack extract(IItemHandler inv, Predicate<ItemStack> test,
Function<ItemStack, Integer> 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;
}
} }

View file

@ -45,6 +45,15 @@ public class TessellatorHelper {
GlStateManager.color3f(1, 1, 1); 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() { public static void begin() {
begin(DefaultVertexFormats.POSITION_TEX); begin(DefaultVertexFormats.POSITION_TEX);

View file

@ -1,6 +1,6 @@
package com.simibubi.create.modules.contraptions.relays.belt; package com.simibubi.create.modules.contraptions.relays.belt;
import java.util.ArrayList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -23,6 +23,7 @@ public enum AllBeltAttachments {
BELT_FUNNEL(AllBlocks.BELT_FUNNEL), BELT_FUNNEL(AllBlocks.BELT_FUNNEL),
BELT_OBSERVER(AllBlocks.ENTITY_DETECTOR), BELT_OBSERVER(AllBlocks.ENTITY_DETECTOR),
MECHANICAL_PRESS(AllBlocks.MECHANICAL_PRESS), 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); public BlockPos getBeltPositionForAttachment(IWorld world, BlockPos pos, BlockState state);
default boolean isAttachedCorrectly(IWorld world, BlockPos attachmentPos, BlockPos beltPos, BlockState attachmentState, default boolean isAttachedCorrectly(IWorld world, BlockPos attachmentPos, BlockPos beltPos,
BlockState beltState) { BlockState attachmentState, BlockState beltState) {
return true; return true;
} }
@ -47,7 +48,8 @@ public enum AllBeltAttachments {
return false; return false;
} }
default boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) { default boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported,
BeltAttachmentState state) {
return false; return false;
} }
@ -101,7 +103,7 @@ public enum AllBeltAttachments {
private BeltTileEntity te; private BeltTileEntity te;
public Tracker(BeltTileEntity te) { public Tracker(BeltTileEntity te) {
attachments = new ArrayList<>(0); attachments = new LinkedList<>();
this.te = te; this.te = te;
} }

View file

@ -60,6 +60,7 @@ public class BeltInventory {
Iterator<TransportedItemStack> iterator = items.iterator(); Iterator<TransportedItemStack> iterator = items.iterator();
float beltSpeed = belt.getDirectionAwareBeltMovementSpeed(); float beltSpeed = belt.getDirectionAwareBeltMovementSpeed();
Direction movementFacing = belt.getMovementFacing();
float spacing = 1; float spacing = 1;
Items: while (iterator.hasNext()) { Items: while (iterator.hasNext()) {
@ -111,12 +112,16 @@ public class BeltInventory {
if (beltSegment != null) { if (beltSegment != null) {
current.locked = false; current.locked = false;
for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) { List<BeltAttachmentState> attachments = beltSegment.attachmentTracker.attachments;
for (BeltAttachmentState attachmentState : attachments) {
if (attachmentState.attachment.processItem(beltSegment, current, attachmentState)) if (attachmentState.attachment.processItem(beltSegment, current, attachmentState))
current.locked = true; 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(); belt.sendData();
}
continue; continue;
} }
} }
@ -140,17 +145,17 @@ public class BeltInventory {
} }
// Belt tunnels // Belt tunnels
{ if (!onClient) {
int seg1 = (int) current.beltPosition; int seg1 = (int) current.beltPosition;
int seg2 = (int) nextOffset; int seg2 = (int) nextOffset;
if (!beltMovementPositive && nextOffset == 0) if (!beltMovementPositive && nextOffset == 0)
seg2 = -1; seg2 = -1;
if (seg1 != seg2) { if (seg1 != seg2) {
if (stuckAtTunnel(seg2, current.stack, belt.getMovementFacing())) { if (stuckAtTunnel(seg2, current.stack, movementFacing)) {
continue; continue;
} }
flapTunnel(seg1, belt.getMovementFacing(), false); flapTunnel(seg1, movementFacing, false);
flapTunnel(seg2, belt.getMovementFacing().getOpposite(), true); flapTunnel(seg2, movementFacing.getOpposite(), true);
} }
} }
@ -186,7 +191,6 @@ public class BeltInventory {
int lastOffset = beltMovementPositive ? belt.beltLength - 1 : 0; int lastOffset = beltMovementPositive ? belt.beltLength - 1 : 0;
BlockPos nextPosition = getPositionForOffset(beltMovementPositive ? belt.beltLength : -1); BlockPos nextPosition = getPositionForOffset(beltMovementPositive ? belt.beltLength : -1);
BlockState state = world.getBlockState(nextPosition); BlockState state = world.getBlockState(nextPosition);
Direction movementFacing = belt.getMovementFacing();
// next block is a basin or a saw // next block is a basin or a saw
if (AllBlocks.BASIN.typeOf(state) || AllBlocks.SAW.typeOf(state)) { if (AllBlocks.BASIN.typeOf(state) || AllBlocks.SAW.typeOf(state)) {
@ -205,7 +209,7 @@ public class BeltInventory {
if (remainder.isEmpty()) { if (remainder.isEmpty()) {
iterator.remove(); iterator.remove();
current = null; current = null;
flapTunnel(lastOffset, belt.getMovementFacing(), false); flapTunnel(lastOffset, movementFacing, false);
} }
belt.sendData(); belt.sendData();
@ -220,7 +224,7 @@ public class BeltInventory {
eject(current); eject(current);
iterator.remove(); iterator.remove();
current = null; current = null;
flapTunnel(lastOffset, belt.getMovementFacing(), false); flapTunnel(lastOffset, movementFacing, false);
belt.sendData(); belt.sendData();
} }
continue; continue;
@ -241,7 +245,7 @@ public class BeltInventory {
if (nextBelt.tryInsertingFromSide(movementFacing, current, false)) { if (nextBelt.tryInsertingFromSide(movementFacing, current, false)) {
iterator.remove(); iterator.remove();
current = null; current = null;
flapTunnel(lastOffset, belt.getMovementFacing(), false); flapTunnel(lastOffset, movementFacing, false);
belt.sendData(); belt.sendData();
} }
@ -298,8 +302,6 @@ public class BeltInventory {
TileEntity te = belt.getWorld().getTileEntity(pos); TileEntity te = belt.getWorld().getTileEntity(pos);
if (te == null || !(te instanceof BeltTunnelTileEntity)) if (te == null || !(te instanceof BeltTunnelTileEntity))
return; return;
if (side.getAxis() == Axis.Z)
side = side.getOpposite();
((BeltTunnelTileEntity) te).flap(side, inward ^ side.getAxis() == Axis.Z); ((BeltTunnelTileEntity) te).flap(side, inward ^ side.getAxis() == Axis.Z);
} }
@ -308,24 +310,19 @@ public class BeltInventory {
} }
public boolean canInsertFrom(int segment, Direction side) { public boolean canInsertFrom(int segment, Direction side) {
float min = segment + .5f - (SEGMENT_WINDOW / 2); float segmentPos = segment;
float max = segment + .5f + (SEGMENT_WINDOW / 2); if (belt.getMovementFacing() == side.getOpposite())
return false;
if (belt.getMovementFacing() != side)
segmentPos += .5f;
else if (!beltMovementPositive)
segmentPos += 1f;
for (TransportedItemStack stack : items) { for (TransportedItemStack stack : items) {
float currentPos = stack.beltPosition; 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 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; return false;
} }

View file

@ -47,6 +47,7 @@ public class BeltTileEntity extends KineticTileEntity {
public int color; public int color;
public int beltLength; public int beltLength;
public int index; public int index;
public Direction lastInsert;
protected BlockPos controller; protected BlockPos controller;
protected BeltInventory inventory; protected BeltInventory inventory;
@ -272,8 +273,9 @@ public class BeltTileEntity extends KineticTileEntity {
} }
public Direction getMovementFacing() { public Direction getMovementFacing() {
return Direction.getFacingFromAxisDirection(getBeltFacing().getAxis(), Axis axis = getBeltFacing().getAxis();
getBeltMovementSpeed() < 0 ? POSITIVE : NEGATIVE); return Direction.getFacingFromAxisDirection(axis,
getBeltMovementSpeed() < 0 ^ axis == Axis.X ? NEGATIVE : POSITIVE);
} }
protected Direction getBeltFacing() { protected Direction getBeltFacing() {
@ -296,21 +298,23 @@ public class BeltTileEntity extends KineticTileEntity {
return false; return false;
BeltInventory nextInventory = nextBeltController.getInventory(); BeltInventory nextInventory = nextBeltController.getInventory();
if (getSpeed() == 0)
return false;
if (!nextInventory.canInsertFrom(index, side)) if (!nextInventory.canInsertFrom(index, side))
return false; return false;
if (simulate) if (simulate)
return true; return true;
transportedStack.beltPosition = index + .5f; transportedStack.beltPosition = index + .5f - Math.signum(getSpeed()) / 16f;
Direction movementFacing = getMovementFacing(); Direction movementFacing = getMovementFacing();
if (!side.getAxis().isVertical()) { if (!side.getAxis().isVertical()) {
if (movementFacing != side) if (movementFacing != side) {
transportedStack.sideOffset = side.getAxisDirection().getOffset() * .35f; transportedStack.sideOffset = side.getAxisDirection().getOffset() * .35f;
else if (side.getAxis() == Axis.X)
transportedStack.sideOffset *= -1;
} else
transportedStack.beltPosition = getDirectionAwareBeltMovementSpeed() > 0 ? index : index + 1; transportedStack.beltPosition = getDirectionAwareBeltMovementSpeed() > 0 ? index : index + 1;
if (side.getAxis() == Axis.X ^ movementFacing.getAxis() == Axis.X)
transportedStack.sideOffset *= -1;
} }
transportedStack.prevSideOffset = transportedStack.sideOffset; transportedStack.prevSideOffset = transportedStack.sideOffset;
@ -321,17 +325,6 @@ public class BeltTileEntity extends KineticTileEntity {
nextBeltController.markDirty(); nextBeltController.markDirty();
nextBeltController.sendData(); 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; return true;
} }

View file

@ -98,6 +98,7 @@ public class BeltTileEntityRenderer extends TileEntityRenderer<BeltTileEntity> {
for (TransportedItemStack transported : te.getInventory().items) { for (TransportedItemStack transported : te.getInventory().items) {
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
TessellatorHelper.fightZFighting(transported.angle);
float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition); float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition);
float sideOffset = MathHelper.lerp(partialTicks, transported.prevSideOffset, transported.sideOffset); float sideOffset = MathHelper.lerp(partialTicks, transported.prevSideOffset, transported.sideOffset);
float verticalMovement = verticality; float verticalMovement = verticality;

View file

@ -1,6 +1,10 @@
package com.simibubi.create.modules.contraptions.relays.belt; package com.simibubi.create.modules.contraptions.relays.belt;
import java.util.HashMap; 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.AllBlocks;
import com.simibubi.create.AllTileEntities; 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.block.BlockState;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.INBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
@ -19,6 +25,7 @@ import net.minecraft.util.Direction.Axis;
import net.minecraft.util.Direction.AxisDirection; import net.minecraft.util.Direction.AxisDirection;
import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
@ -29,14 +36,14 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT
private LazyOptional<IItemHandler> cap = LazyOptional.empty(); private LazyOptional<IItemHandler> cap = LazyOptional.empty();
private boolean initialize; private boolean initialize;
private Direction flapToSend; private List<Pair<Direction, Boolean>> flapsToSend;
private boolean flapInward;
public BeltTunnelTileEntity() { public BeltTunnelTileEntity() {
super(AllTileEntities.BELT_TUNNEL.type); super(AllTileEntities.BELT_TUNNEL.type);
flaps = new HashMap<>(); flaps = new HashMap<>();
syncedFlaps = new HashMap<>(); syncedFlaps = new HashMap<>();
initialize = true; initialize = true;
flapsToSend = new LinkedList<>();
} }
@Override @Override
@ -91,7 +98,7 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT
public boolean toggleSyncForFlap(Direction face) { public boolean toggleSyncForFlap(Direction face) {
if (!flaps.containsKey(face)) if (!flaps.containsKey(face))
return false; return false;
if (syncedFlaps.containsKey(face)) if (syncedFlaps.containsKey(face))
syncedFlaps.remove(face); syncedFlaps.remove(face);
else else
syncedFlaps.put(face, ItemStack.EMPTY); syncedFlaps.put(face, ItemStack.EMPTY);
@ -103,10 +110,16 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT
@Override @Override
public CompoundNBT writeToClient(CompoundNBT tag) { public CompoundNBT writeToClient(CompoundNBT tag) {
CompoundNBT writeToClient = super.writeToClient(tag); CompoundNBT writeToClient = super.writeToClient(tag);
if (flapToSend != null) { if (!flapsToSend.isEmpty()) {
writeToClient.putInt("Flap", flapToSend.getIndex()); ListNBT flapsNBT = new ListNBT();
writeToClient.putBoolean("FlapInward", flapInward); for (Pair<Direction, Boolean> pair : flapsToSend) {
flapToSend = null; 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; return writeToClient;
} }
@ -114,9 +127,13 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT
@Override @Override
public void readClientUpdate(CompoundNBT tag) { public void readClientUpdate(CompoundNBT tag) {
super.readClientUpdate(tag); super.readClientUpdate(tag);
if (tag.contains("Flap")) { if (tag.contains("Flaps")) {
Direction side = Direction.byIndex(tag.getInt("Flap")); ListNBT flapsNBT = tag.getList("Flaps", NBT.TAG_COMPOUND);
flap(side, tag.getBoolean("FlapInward")); for (INBT inbt : flapsNBT) {
CompoundNBT flap = (CompoundNBT) inbt;
Direction side = Direction.byIndex(flap.getInt("Flap"));
flap(side, flap.getBoolean("FlapInward"));
}
} else } else
initFlaps(); initFlaps();
} }
@ -156,17 +173,18 @@ public class BeltTunnelTileEntity extends SyncedTileEntity implements ITickableT
return; return;
} }
flapToSend = side; flapsToSend.add(Pair.of(side, inward));
flapInward = inward;
sendData();
} }
@Override @Override
public void tick() { public void tick() {
if (initialize) if (initialize)
initFlaps(); initFlaps();
if (!world.isRemote) if (!world.isRemote) {
if (!flapsToSend.isEmpty())
sendData();
return; return;
}
flaps.forEach((d, value) -> value.tick()); flaps.forEach((d, value) -> value.tick());
} }

View file

@ -4,7 +4,7 @@ import net.minecraft.item.ItemStack;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
public class ItemHandlerBeltSegment implements IItemHandler { public class ItemHandlerBeltSegment implements IItemHandler {
private final BeltInventory beltInventory; private final BeltInventory beltInventory;
int offset; int offset;
@ -32,7 +32,7 @@ public class ItemHandlerBeltSegment implements IItemHandler {
if (!simulate) { if (!simulate) {
TransportedItemStack newStack = new TransportedItemStack(stack); TransportedItemStack newStack = new TransportedItemStack(stack);
newStack.insertedAt = offset; newStack.insertedAt = offset;
newStack.beltPosition = offset + .5f; newStack.beltPosition = offset + .5f + (beltInventory.beltMovementPositive ? -1 : 1) / 16f;
newStack.prevBeltPosition = newStack.beltPosition; newStack.prevBeltPosition = newStack.beltPosition;
this.beltInventory.insert(newStack); this.beltInventory.insert(newStack);
this.beltInventory.belt.markDirty(); this.beltInventory.belt.markDirty();

View file

@ -6,11 +6,11 @@ import java.util.stream.Collectors;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.behaviour.inventory.ExtractingBehaviour; import com.simibubi.create.foundation.behaviour.inventory.SingleTargetAutoExtractingBehaviour;
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.modules.contraptions.relays.belt.TransportedItemStack;
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState; 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.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.block.BlockState;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -19,7 +19,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
public abstract class ExtractorForBeltsBlock extends AttachedLogisticalBlock implements IBeltAttachment { public abstract class BeltAttachableLogisticalBlock extends AttachedLogisticalBlock implements IBeltAttachment {
@Override @Override
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { 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; ItemStack stack = transported.stack;
FilteringBehaviour filtering = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE); 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) if (extracting == null)
return false; return false;
@ -64,12 +65,23 @@ public abstract class ExtractorForBeltsBlock extends AttachedLogisticalBlock imp
public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) { public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
BlockPos pos = state.attachmentPos; BlockPos pos = state.attachmentPos;
World world = te.getWorld(); 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) if (extracting == null)
return false; return false;
extracting.extract(); if (extracting.getShouldPause().get())
return false; 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();
} }
} }

View file

@ -1,6 +1,7 @@
package com.simibubi.create.modules.logistics.block.belts; package com.simibubi.create.modules.logistics.block.belts;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.List; import java.util.List;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
@ -21,7 +22,6 @@ import net.minecraft.state.BooleanProperty;
import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.StateContainer.Builder;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape; 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.IWorld;
import net.minecraft.world.World; import net.minecraft.world.World;
public class FunnelBlock extends AttachedLogisticalBlock public class FunnelBlock extends AttachedLogisticalBlock implements IBeltAttachment, IWithTileEntity<FunnelTileEntity> {
implements IBeltAttachment, IWithTileEntity<FunnelTileEntity> {
public static final BooleanProperty BELT = BooleanProperty.create("belt"); public static final BooleanProperty BELT = BooleanProperty.create("belt");
@ -55,7 +54,7 @@ public class FunnelBlock extends AttachedLogisticalBlock
protected boolean isVertical() { protected boolean isVertical() {
return false; return false;
} }
@Override @Override
public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) { public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) {
if (worldIn.isRemote) if (worldIn.isRemote)
@ -111,6 +110,22 @@ public class FunnelBlock extends AttachedLogisticalBlock
@Override @Override
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
onAttachmentPlaced(worldIn, pos, state); 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 @Override
@ -145,8 +160,6 @@ public class FunnelBlock extends AttachedLogisticalBlock
@Override @Override
public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) { public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
Direction movementFacing = te.getMovementFacing(); Direction movementFacing = te.getMovementFacing();
if (movementFacing.getAxis() == Axis.Z)
movementFacing = movementFacing.getOpposite();
if (movementFacing != te.getWorld().getBlockState(state.attachmentPos).get(HORIZONTAL_FACING)) if (movementFacing != te.getWorld().getBlockState(state.attachmentPos).get(HORIZONTAL_FACING))
return false; return false;
return process(te, transported, state); return process(te, transported, state);
@ -168,5 +181,5 @@ public class FunnelBlock extends AttachedLogisticalBlock
return true; return true;
} }
} }
} }

View file

@ -2,6 +2,7 @@ package com.simibubi.create.modules.logistics.block.belts;
import java.util.List; import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; 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.behaviour.inventory.InventoryManagementBehaviour.Attachments;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.VecHelper; 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 com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -18,10 +20,12 @@ import net.minecraft.nbt.CompoundNBT;
import net.minecraft.particles.ItemParticleData; import net.minecraft.particles.ItemParticleData;
import net.minecraft.particles.ParticleTypes; import net.minecraft.particles.ParticleTypes;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvents; import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.Vec3i;
@ -79,7 +83,16 @@ public class FunnelTileEntity extends SmartTileEntity {
if (!filtering.test(stack)) if (!filtering.test(stack))
return 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 (remainder.isEmpty()) {
if (!world.isRemote) if (!world.isRemote)
@ -87,10 +100,22 @@ public class FunnelTileEntity extends SmartTileEntity {
justEaten = stack.copy(); justEaten = stack.copy();
} }
sendData(); if (remainder.getCount() != stack.getCount())
sendData();
return remainder; 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) { public void spawnParticles(ItemStack stack) {
Vec3i directionVec = getBlockState().get(BlockStateProperties.HORIZONTAL_FACING).getDirectionVec(); Vec3i directionVec = getBlockState().get(BlockStateProperties.HORIZONTAL_FACING).getDirectionVec();
float xSpeed = directionVec.getX() * 1 / 8f; float xSpeed = directionVec.getX() * 1 / 8f;

View file

@ -5,6 +5,7 @@ import com.simibubi.create.foundation.utility.AllShapes;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock; 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.Block;
import net.minecraft.block.BlockState; 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.IBlockReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class ExtractorBlock extends AttachedLogisticalBlock { public class ExtractorBlock extends BeltAttachableLogisticalBlock {
public static BooleanProperty POWERED = BlockStateProperties.POWERED; public static BooleanProperty POWERED = BlockStateProperties.POWERED;

View file

@ -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.base.TileEntityBehaviour;
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning; 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.ExtractingBehaviour;
import com.simibubi.create.foundation.behaviour.inventory.SingleTargetAutoExtractingBehaviour; import com.simibubi.create.foundation.behaviour.inventory.SingleTargetAutoExtractingBehaviour;
import com.simibubi.create.foundation.utility.VecHelper; 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.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock; import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock;
import com.simibubi.create.modules.logistics.item.CardboardBoxItem; import com.simibubi.create.modules.logistics.item.CardboardBoxItem;
@ -34,6 +36,7 @@ public class ExtractorTileEntity extends SmartTileEntity {
protected ExtractingBehaviour extracting; protected ExtractingBehaviour extracting;
protected FilteringBehaviour filtering; protected FilteringBehaviour filtering;
protected boolean extractingToBelt;
public ExtractorTileEntity() { public ExtractorTileEntity() {
this(AllTileEntities.EXTRACTOR.type); this(AllTileEntities.EXTRACTOR.type);
@ -80,6 +83,20 @@ public class ExtractorTileEntity extends SmartTileEntity {
world.addEntity(entityIn); 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() { protected boolean isPowered() {
return getBlockState().get(ExtractorBlock.POWERED); return getBlockState().get(ExtractorBlock.POWERED);
} }
@ -104,4 +121,15 @@ public class ExtractorTileEntity extends SmartTileEntity {
return world.getEntitiesWithinAABBExcludingEntity(null, new AxisAlignedBB(getPos())).isEmpty(); 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());
}
}
} }

View file

@ -2,7 +2,7 @@ package com.simibubi.create.modules.logistics.block.transposer;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.utility.AllShapes; 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.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -19,7 +19,7 @@ import net.minecraft.world.IBlockReader;
import net.minecraft.world.IWorldReader; import net.minecraft.world.IWorldReader;
import net.minecraft.world.World; import net.minecraft.world.World;
public class TransposerBlock extends AttachedLogisticalBlock { public class TransposerBlock extends BeltAttachableLogisticalBlock {
public static BooleanProperty POWERED = BlockStateProperties.POWERED; public static BooleanProperty POWERED = BlockStateProperties.POWERED;

View file

@ -2,15 +2,21 @@ package com.simibubi.create.modules.logistics.block.transposer;
import java.util.List; import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.behaviour.inventory.InsertingBehaviour; import com.simibubi.create.foundation.behaviour.inventory.InsertingBehaviour;
import com.simibubi.create.foundation.behaviour.inventory.InventoryManagementBehaviour.Attachments; 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.belts.AttachedLogisticalBlock;
import com.simibubi.create.modules.logistics.block.extractor.ExtractorTileEntity; import com.simibubi.create.modules.logistics.block.extractor.ExtractorTileEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType; import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
public class TransposerTileEntity extends ExtractorTileEntity { public class TransposerTileEntity extends ExtractorTileEntity {
@ -31,18 +37,42 @@ public class TransposerTileEntity extends ExtractorTileEntity {
inserting = new InsertingBehaviour(this, inserting = new InsertingBehaviour(this,
Attachments.toward(() -> AttachedLogisticalBlock.getBlockFacing(getBlockState()).getOpposite())); Attachments.toward(() -> AttachedLogisticalBlock.getBlockFacing(getBlockState()).getOpposite()));
behaviours.add(inserting); behaviours.add(inserting);
extracting.withSpecialFilter(this::shouldExtract); extracting.withAmountThreshold(this::amountToExtract).withAdditionalFilter(this::shouldExtract);
} }
public void filterChanged(ItemStack stack) { 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) { 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()) if (filtering.getFilter().isEmpty())
return true; return true;
return inserting.insert(stack, true).isEmpty(); 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 @Override
protected boolean canExtract() { protected boolean canExtract() {
return inserting.getInventory() != null; return inserting.getInventory() != null;
@ -50,8 +80,17 @@ public class TransposerTileEntity extends ExtractorTileEntity {
@Override @Override
protected void onExtract(ItemStack stack) { 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); 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()) if (!remainder.isEmpty())
super.onExtract(remainder); super.onExtract(remainder);
} }