From 27b05bc43e057e8e54425a8a50e6749a7704337b Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Thu, 24 Sep 2020 20:32:16 +0200 Subject: [PATCH] Portable Storage Interface remaster - Implemented new PSI models by Kryppers - PSIs are now used in pairs like contacts - PSIs now act as an inventory proxy of the attached contraption - Comparators can detect when two PSIs are interfacing - Contraptions will continue moving after a second of inactivity --- .../actors/PortableStorageInterfaceBlock.java | 28 ++- .../PortableStorageInterfaceMovement.java | 181 ++++++++---------- .../PortableStorageInterfaceRenderer.java | 104 +++++++--- .../PortableStorageInterfaceTileEntity.java | 116 ++++++++++- .../foundation/item/ItemHandlerWrapper.java | 49 +++++ .../tileEntity/SmartTileEntity.java | 11 ++ .../fluid/SmartFluidTankBehaviour.java | 1 - .../inventory/InvManipulationBehaviour.java | 17 +- 8 files changed, 362 insertions(+), 145 deletions(-) create mode 100644 src/main/java/com/simibubi/create/foundation/item/ItemHandlerWrapper.java diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceBlock.java index d4795c41b..078b33117 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceBlock.java @@ -4,6 +4,7 @@ import javax.annotation.ParametersAreNonnullByDefault; import com.simibubi.create.AllShapes; import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.block.ITE; import com.simibubi.create.foundation.block.ProperDirectionalBlock; import mcp.MethodsReturnNonnullByDefault; @@ -14,20 +15,22 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; +import net.minecraft.world.World; @ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault -public class PortableStorageInterfaceBlock extends ProperDirectionalBlock { +public class PortableStorageInterfaceBlock extends ProperDirectionalBlock + implements ITE { public PortableStorageInterfaceBlock(Properties p_i48415_1_) { super(p_i48415_1_); } - + @Override public boolean hasTileEntity(BlockState state) { return true; } - + @Override public TileEntity createTileEntity(BlockState state, IBlockReader world) { return AllTileEntities.PORTABLE_STORAGE_INTERFACE.create(); @@ -44,4 +47,23 @@ public class PortableStorageInterfaceBlock extends ProperDirectionalBlock { return AllShapes.PORTABLE_STORAGE_INTERFACE.get(state.get(FACING)); } + @Override + public boolean hasComparatorInputOverride(BlockState state) { + return true; + } + + @Override + public int getComparatorInputOverride(BlockState blockState, World worldIn, BlockPos pos) { + try { + return getTileEntity(worldIn, pos).isConnected() ? 15 : 0; + } catch (TileEntityException e) { + } + return 0; + } + + @Override + public Class getTileEntityClass() { + return PortableStorageInterfaceTileEntity.class; + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceMovement.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceMovement.java index 6ceea2f44..f91b4dca7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceMovement.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceMovement.java @@ -1,133 +1,104 @@ package com.simibubi.create.content.contraptions.components.actors; -import java.util.function.Predicate; +import java.util.Optional; +import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; -import com.simibubi.create.foundation.config.AllConfigs; -import com.simibubi.create.foundation.item.ItemHelper; -import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; -import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour; -import com.simibubi.create.foundation.tileEntity.behaviour.inventory.SingleTargetAutoExtractingBehaviour; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.BlockState; -import net.minecraft.item.ItemStack; +import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.nbt.NBTUtil; 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.Vec3d; import net.minecraft.world.World; -import net.minecraftforge.items.IItemHandlerModifiable; -import net.minecraftforge.items.ItemHandlerHelper; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; public class PortableStorageInterfaceMovement extends MovementBehaviour { - private static final String _exporting_ = "Exporting"; - private static final String _delay_ = "Delay"; - private static final String _workingPos_ = "WorkingPos"; + static final String _workingPos_ = "WorkingPos"; + static final String _clientPrevPos_ = "ClientPrevPos"; @Override public Vec3d getActiveAreaOffset(MovementContext context) { return new Vec3d(context.state.get(PortableStorageInterfaceBlock.FACING) - .getDirectionVec()).scale(.85f); + .getDirectionVec()).scale(1.85f); + } + + @Override + @OnlyIn(Dist.CLIENT) + public void renderInContraption(MovementContext context, MatrixStack ms, MatrixStack msLocal, + IRenderTypeBuffer buffer) { + PortableStorageInterfaceRenderer.renderInContraption(context, ms, msLocal, buffer); } @Override public void visitNewPosition(MovementContext context, BlockPos pos) { - Direction currentFacing = getCurrentFacing(context); - PortableStorageInterfaceTileEntity psi = - getValidStationaryInterface(context.world, pos, currentFacing.getAxis()); + context.data.remove(_workingPos_); + if (findInterface(context, pos)) + context.stall = true; + } + + protected boolean findInterface(MovementContext context, BlockPos pos) { + Optional currentFacingIfValid = getCurrentFacingIfValid(context); + if (!currentFacingIfValid.isPresent()) + return false; + + Direction currentFacing = currentFacingIfValid.get(); + PortableStorageInterfaceTileEntity psi = findStationaryInterface(context.world, pos, currentFacing); if (psi == null) - return; - if (psi.isTransferring()) - return; - context.data.put(_workingPos_, NBTUtil.writeBlockPos(pos)); - context.stall = true; + return false; + + if (psi.isTransferring() && !context.world.isRemote) + return false; + context.data.put(_workingPos_, NBTUtil.writeBlockPos(psi.getPos())); + if (!context.world.isRemote) { + Vec3d diff = VecHelper.getCenterOf(psi.getPos()) + .subtract(context.position); + diff = VecHelper.project(diff, new Vec3d(currentFacing.getDirectionVec())); + float distance = (float) (diff.length() + 1.85f - 1); + psi.startTransferringTo(context.contraption, distance); + } else { + context.data.put(_clientPrevPos_, NBTUtil.writeBlockPos(pos)); + } + return true; } @Override public void tick(MovementContext context) { - if (!context.data.contains(_workingPos_)) + if (context.world.isRemote) { + boolean stalled = context.contraption.stalled; + if (stalled && !context.data.contains(_workingPos_)) { + BlockPos pos = new BlockPos(context.position); + if (!context.data.contains(_clientPrevPos_) + || !NBTUtil.readBlockPos(context.data.getCompound(_clientPrevPos_)) + .equals(pos)) + findInterface(context, pos); + } + if (!stalled) + reset(context); return; - if (context.world.isRemote) + } + + if (!context.data.contains(_workingPos_)) return; BlockPos pos = NBTUtil.readBlockPos(context.data.getCompound(_workingPos_)); + Optional currentFacingIfValid = getCurrentFacingIfValid(context); + if (!currentFacingIfValid.isPresent()) + return; + PortableStorageInterfaceTileEntity stationaryInterface = - getValidStationaryInterface(context.world, pos, getCurrentFacing(context).getAxis()); - if (stationaryInterface == null) { + getStationaryInterfaceAt(context.world, pos, currentFacingIfValid.get()); + if (stationaryInterface == null || !stationaryInterface.isTransferring()) { reset(context); return; } - - int nextExtract = context.data.getInt(_delay_); - if (nextExtract > 0) { - nextExtract--; - context.data.putInt(_delay_, nextExtract); - return; - } - - boolean extract = context.data.getBoolean(_exporting_); - boolean success = false; - IItemHandlerModifiable inv = context.contraption.inventory; - SingleTargetAutoExtractingBehaviour extracting = - TileEntityBehaviour.get(stationaryInterface, SingleTargetAutoExtractingBehaviour.TYPE); - FilteringBehaviour filtering = TileEntityBehaviour.get(stationaryInterface, FilteringBehaviour.TYPE); - - if (extract) { - // Export from Contraption - Predicate test = extracting.getFilterTest(); - int exactAmount = extracting.getAmountFromFilter(); - ItemStack itemExtracted = ItemStack.EMPTY; - if (exactAmount != -1) - itemExtracted = ItemHelper.extract(inv, test, exactAmount, false); - else - itemExtracted = ItemHelper.extract(inv, test, stationaryInterface::amountToExtract, false); - - if (!itemExtracted.isEmpty()) { - stationaryInterface.onExtract(itemExtracted); - success = exactAmount == -1; - } - - } else { - // Import to Contraption - if (extracting != null) { - extracting.setSynchronized(false); - extracting.withAdditionalFilter(stack -> { - if (filtering.anyAmount()) - return true; - return ItemHandlerHelper.insertItemStacked(inv, stack, true) - .isEmpty(); - }); - - extracting.withAmountThreshold(stack -> { - ItemStack tester = stack.copy(); - tester.setCount(tester.getMaxStackSize()); - return stack.getCount() - ItemHandlerHelper.insertItemStacked(inv, stack, true) - .getCount(); - }); - - extracting.setCallback(stack -> { - ItemHandlerHelper.insertItemStacked(inv, stack, false); - }); - - success = extracting.extract() && filtering.anyAmount(); - extracting.setSynchronized(true); - stationaryInterface.applyFilteringCallbacks(); - extracting.setCallback(stationaryInterface::onExtract); - } - } - - if (!success) { - reset(context); - return; - } - - context.data.putInt(_delay_, AllConfigs.SERVER.logistics.defaultExtractionTimer.get()); } @Override @@ -136,32 +107,42 @@ public class PortableStorageInterfaceMovement extends MovementBehaviour { } public void reset(MovementContext context) { + context.data.remove(_clientPrevPos_); context.data.remove(_workingPos_); - context.data.remove(_delay_); - context.data.remove(_exporting_); context.stall = false; } - private PortableStorageInterfaceTileEntity getValidStationaryInterface(World world, BlockPos pos, Axis validAxis) { + private PortableStorageInterfaceTileEntity findStationaryInterface(World world, BlockPos pos, Direction facing) { + for (int i = 0; i < 2; i++) { + PortableStorageInterfaceTileEntity interfaceAt = + getStationaryInterfaceAt(world, pos.offset(facing, i), facing); + if (interfaceAt == null) + continue; + return interfaceAt; + } + return null; + } + + private PortableStorageInterfaceTileEntity getStationaryInterfaceAt(World world, BlockPos pos, Direction facing) { TileEntity te = world.getTileEntity(pos); if (!(te instanceof PortableStorageInterfaceTileEntity)) return null; BlockState blockState = world.getBlockState(pos); if (!AllBlocks.PORTABLE_STORAGE_INTERFACE.has(blockState)) return null; - if (blockState.get(PortableStorageInterfaceBlock.FACING) - .getAxis() != validAxis) - return null; - if (world.isBlockPowered(pos)) + if (blockState.get(PortableStorageInterfaceBlock.FACING) != facing.getOpposite()) return null; return (PortableStorageInterfaceTileEntity) te; } - private Direction getCurrentFacing(MovementContext context) { + private Optional getCurrentFacingIfValid(MovementContext context) { Vec3d directionVec = new Vec3d(context.state.get(PortableStorageInterfaceBlock.FACING) .getDirectionVec()); directionVec = VecHelper.rotate(directionVec, context.rotation.x, context.rotation.y, context.rotation.z); - return Direction.getFacingFromVector(directionVec.x, directionVec.y, directionVec.z); + Direction facingFromVector = Direction.getFacingFromVector(directionVec.x, directionVec.y, directionVec.z); + if (directionVec.distanceTo(new Vec3d(facingFromVector.getDirectionVec())) > 1 / 8f) + return Optional.empty(); + return Optional.of(facingFromVector); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceRenderer.java index 7d57fb692..d3f869473 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceRenderer.java @@ -1,20 +1,25 @@ package com.simibubi.create.content.contraptions.components.actors; +import java.util.function.Consumer; + import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.AngleHelper; -import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.MatrixStacker; import com.simibubi.create.foundation.utility.SuperByteBuffer; import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; +import net.minecraft.nbt.NBTUtil; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; -import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.BlockPos; public class PortableStorageInterfaceRenderer extends SafeTileEntityRenderer { @@ -25,40 +30,83 @@ public class PortableStorageInterfaceRenderer extends SafeTileEntityRenderer sbb.renderInto(ms, vb), ms); + } - ms.push(); - - Direction facing = blockState.get(PortableStorageInterfaceBlock.FACING); - MatrixStacker.of(ms) - .centre() - .rotateY(AngleHelper.horizontalAngle(facing)) - .rotateX(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90) - .unCentre(); - - float progress = (float) ((AnimationTickHolder.getRenderTick() * .25f) % (Math.PI * 2)); - float bounce = (MathHelper.sin(progress) + 1) / 4f; + public static void renderInContraption(MovementContext context, MatrixStack ms, MatrixStack msLocal, + IRenderTypeBuffer buffer) { + BlockState blockState = context.state; + PortableStorageInterfaceTileEntity te = getTargetPSI(context); + IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid()); + float renderPartialTicks = Minecraft.getInstance() + .getRenderPartialTicks(); - if (bounce > 7/16f) { - middle = AllBlockPartials.PORTABLE_STORAGE_INTERFACE_MIDDLE_POWERED.renderOn(blockState); + float progress = 0; + boolean lit = false; + if (te != null) { + progress = te.getExtensionDistance(renderPartialTicks); + lit = te.isConnected(); } + render(blockState, progress, lit, sbb -> sbb.light(msLocal.peek() + .getModel()) + .renderInto(ms, vb), ms, msLocal); + } - ms.translate(0, bounce, 0); - - ms.push(); - ms.translate(0, 6/16f, 0); - middle.renderInto(ms, vb); - ms.pop(); - - ms.translate(0, bounce, 0); - top.renderInto(ms, vb); + protected static PortableStorageInterfaceTileEntity getTargetPSI(MovementContext context) { + String _workingPos_ = PortableStorageInterfaceMovement._workingPos_; + if (!context.contraption.stalled || !context.data.contains(_workingPos_)) + return null; - ms.pop(); + BlockPos pos = NBTUtil.readBlockPos(context.data.getCompound(_workingPos_)); + TileEntity tileEntity = context.world.getTileEntity(pos); + if (!(tileEntity instanceof PortableStorageInterfaceTileEntity)) + return null; + + PortableStorageInterfaceTileEntity psi = (PortableStorageInterfaceTileEntity) tileEntity; + if (!psi.isTransferring()) + return null; + return psi; + } + + private static void render(BlockState blockState, float progress, boolean lit, + Consumer drawCallback, MatrixStack... matrixStacks) { + for (MatrixStack ms : matrixStacks) + ms.push(); + + SuperByteBuffer middle = AllBlockPartials.PORTABLE_STORAGE_INTERFACE_MIDDLE.renderOn(blockState); + SuperByteBuffer top = AllBlockPartials.PORTABLE_STORAGE_INTERFACE_TOP.renderOn(blockState); + if (lit) + middle = AllBlockPartials.PORTABLE_STORAGE_INTERFACE_MIDDLE_POWERED.renderOn(blockState); + + Direction facing = blockState.get(PortableStorageInterfaceBlock.FACING); + for (MatrixStack ms : matrixStacks) + MatrixStacker.of(ms) + .centre() + .rotateY(AngleHelper.horizontalAngle(facing)) + .rotateX(facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90) + .unCentre(); + + for (MatrixStack ms : matrixStacks) { + ms.translate(0, progress / 2f, 0); + ms.push(); + ms.translate(0, 6 / 16f, 0); + } + + drawCallback.accept(middle); + + for (MatrixStack ms : matrixStacks) { + ms.pop(); + ms.translate(0, progress / 2f, 0); + } + + drawCallback.accept(top); + + for (MatrixStack ms : matrixStacks) + ms.pop(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceTileEntity.java index 3e27dd173..06eabc2fd 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/PortableStorageInterfaceTileEntity.java @@ -3,54 +3,150 @@ package com.simibubi.create.content.contraptions.components.actors; import java.util.List; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; +import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.item.ItemHandlerWrapper; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; -import com.simibubi.create.foundation.tileEntity.SyncedTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.utility.LerpedFloat; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; +import net.minecraft.util.math.MathHelper; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.IItemHandlerModifiable; -import net.minecraftforge.items.wrapper.CombinedInvWrapper; public class PortableStorageInterfaceTileEntity extends SmartTileEntity { - protected int transferTimeout; + protected int transferTimer; + protected float distance; protected LazyOptional capability; + protected LerpedFloat connectionAnimation; public PortableStorageInterfaceTileEntity(TileEntityType tileEntityTypeIn) { super(tileEntityTypeIn); - transferTimeout = 0; + transferTimer = 0; capability = LazyOptional.empty(); + connectionAnimation = LerpedFloat.linear().startWithValue(0); } - public void startTransferringTo(Contraption contraption) { - CombinedInvWrapper inventory = contraption.inventory; + public void startTransferringTo(Contraption contraption, float distance) { capability.invalidate(); - capability = LazyOptional.of(() -> inventory); - + capability = LazyOptional.of(() -> new InterfaceItemHandler(contraption.inventory)); + this.distance = distance; + startConnecting(); + notifyUpdate(); } @Override public void tick() { super.tick(); + boolean wasConnected = isConnected(); + + if (transferTimer > 0) { + transferTimer--; + if (transferTimer == 0) + capability.invalidate(); + } + + boolean isConnected = isConnected(); + if (wasConnected != isConnected && !world.isRemote) + markDirty(); + + float progress = 0; + int timeUnit = getTransferTimeout() / 2; + if (isConnected) + progress = 1; + else if (transferTimer >= timeUnit * 3) + progress = MathHelper.lerp((transferTimer - timeUnit * 3) / (float) timeUnit, 1, 0); + else if (transferTimer < timeUnit) + progress = MathHelper.lerp(transferTimer / (float) timeUnit, 0, 1); + connectionAnimation.setValue(progress); } + @Override + protected void read(CompoundNBT compound, boolean clientPacket) { + super.read(compound, clientPacket); + transferTimer = compound.getInt("Timer"); + distance = compound.getFloat("Distance"); + } + + @Override + protected void write(CompoundNBT compound, boolean clientPacket) { + super.write(compound, clientPacket); + compound.putInt("Timer", transferTimer); + compound.putFloat("Distance", distance); + } + public boolean isTransferring() { - return transferTimeout != 0; + return transferTimer != 0; + } + + boolean isConnected() { + int timeUnit = getTransferTimeout() / 2; + return transferTimer >= timeUnit && transferTimer < timeUnit * 3; + } + + float getExtensionDistance(float partialTicks) { + return connectionAnimation.getValue(partialTicks) * distance / 2; + } + + float getConnectionDistance() { + return distance; } @Override public LazyOptional getCapability(Capability cap, Direction side) { + if (isItemHandlerCap(cap)) + return capability.cast(); return super.getCapability(cap, side); } - public void resetTimer() { + public void startConnecting() { + transferTimer = getTransferTimeout() * 2; + } + + public void onContentTransferred() { + int timeUnit = getTransferTimeout() / 2; + transferTimer = timeUnit * 3; + sendData(); + } + protected Integer getTransferTimeout() { + return AllConfigs.SERVER.logistics.psiTimeout.get(); } @Override public void addBehaviours(List behaviours) {} + class InterfaceItemHandler extends ItemHandlerWrapper { + + public InterfaceItemHandler(IItemHandlerModifiable wrapped) { + super(wrapped); + } + + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + if (!isConnected()) + return ItemStack.EMPTY; + ItemStack extractItem = super.extractItem(slot, amount, simulate); + if (!simulate && !extractItem.isEmpty()) + onContentTransferred(); + return extractItem; + } + + @Override + public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { + if (!isConnected()) + return stack; + ItemStack insertItem = super.insertItem(slot, stack, simulate); + if (!simulate && !insertItem.equals(stack, false)) + onContentTransferred(); + return insertItem; + } + + } + } diff --git a/src/main/java/com/simibubi/create/foundation/item/ItemHandlerWrapper.java b/src/main/java/com/simibubi/create/foundation/item/ItemHandlerWrapper.java new file mode 100644 index 000000000..6a2190269 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/item/ItemHandlerWrapper.java @@ -0,0 +1,49 @@ +package com.simibubi.create.foundation.item; + +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.IItemHandlerModifiable; + +public class ItemHandlerWrapper implements IItemHandlerModifiable { + + private IItemHandlerModifiable wrapped; + + public ItemHandlerWrapper(IItemHandlerModifiable wrapped) { + this.wrapped = wrapped; + } + + @Override + public int getSlots() { + return wrapped.getSlots(); + } + + @Override + public ItemStack getStackInSlot(int slot) { + return wrapped.getStackInSlot(slot); + } + + @Override + public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) { + return wrapped.insertItem(slot, stack, simulate); + } + + @Override + public ItemStack extractItem(int slot, int amount, boolean simulate) { + return wrapped.extractItem(slot, amount, simulate); + } + + @Override + public int getSlotLimit(int slot) { + return wrapped.getSlotLimit(slot); + } + + @Override + public boolean isItemValid(int slot, ItemStack stack) { + return wrapped.isItemValid(slot, stack); + } + + @Override + public void setStackInSlot(int slot, ItemStack stack) { + wrapped.setStackInSlot(slot, stack); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java b/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java index bb1a42cdc..a40427a62 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/SmartTileEntity.java @@ -11,6 +11,9 @@ import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntityType; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.fluids.capability.CapabilityFluidHandler; +import net.minecraftforge.items.CapabilityItemHandler; public abstract class SmartTileEntity extends SyncedTileEntity implements ITickableTileEntity { @@ -145,5 +148,13 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka return (T) behaviours.get(type); return null; } + + protected boolean isItemHandlerCap(Capability cap) { + return cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY; + } + + protected boolean isFluidHandlerCap(Capability cap) { + return cap == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY; + } } diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/fluid/SmartFluidTankBehaviour.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/fluid/SmartFluidTankBehaviour.java index 971f7fd1e..03b111842 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/fluid/SmartFluidTankBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/fluid/SmartFluidTankBehaviour.java @@ -6,7 +6,6 @@ import org.apache.commons.lang3.mutable.MutableInt; import com.simibubi.create.foundation.fluid.CombinedTankWrapper; import com.simibubi.create.foundation.fluid.SmartFluidTank; -import com.simibubi.create.foundation.item.SmartInventory; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType; diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/inventory/InvManipulationBehaviour.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/inventory/InvManipulationBehaviour.java index 0a23edb51..727544e9a 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/inventory/InvManipulationBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/inventory/InvManipulationBehaviour.java @@ -36,6 +36,7 @@ public class InvManipulationBehaviour extends TileEntityBehaviour { protected LazyOptional targetCapability; protected boolean simulateNext; protected boolean bypassSided; + private boolean findNewNextTick; private BehaviourType behaviourType; @@ -55,7 +56,7 @@ public class InvManipulationBehaviour extends TileEntityBehaviour { InterfaceProvider target) { super(te); behaviourType = type; - setLazyTickRate(40); + setLazyTickRate(5); this.target = target; this.targetCapability = LazyOptional.empty(); simulateNext = false; @@ -137,11 +138,12 @@ public class InvManipulationBehaviour extends TileEntityBehaviour { @Override public void initialize() { super.initialize(); - findNewCapability(); + findNewNextTick = true; } protected void onHandlerInvalidated(LazyOptional handler) { - findNewCapability(); + findNewNextTick = true; + targetCapability = LazyOptional.empty(); } @Override @@ -150,6 +152,15 @@ public class InvManipulationBehaviour extends TileEntityBehaviour { if (!targetCapability.isPresent()) findNewCapability(); } + + @Override + public void tick() { + super.tick(); + if (findNewNextTick) { + findNewNextTick = false; + findNewCapability(); + } + } public int getAmountFromFilter() { int amount = -1;