From 59f19adb8958309928a0c38a6b60a8b837c2ade2 Mon Sep 17 00:00:00 2001 From: grimmauld Date: Thu, 1 Oct 2020 13:08:16 +0200 Subject: [PATCH] optimized bucket dumping --- .../processing/BasinMovementBehaviour.java | 111 ++++++++++++------ 1 file changed, 74 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinMovementBehaviour.java index 890f26db5..b658ea9d0 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinMovementBehaviour.java @@ -1,36 +1,25 @@ package com.simibubi.create.content.contraptions.processing; +import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; import net.minecraft.entity.item.ItemEntity; import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraftforge.items.ItemStackHandler; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandlerModifiable; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import javax.annotation.Nullable; public class BasinMovementBehaviour extends MovementBehaviour { - @SuppressWarnings("unchecked") - public Map getOrReadInventory(MovementContext context) { - if (!(context.temporaryData instanceof List)) { - Map map = new HashMap<>(); - map.put("InputItems", new ItemStackHandler(9)); - map.put("OutputItems", new ItemStackHandler(8)); - map.forEach((s, h) -> h.deserializeNBT(context.tileData.getCompound(s))); - context.temporaryData = map; - } - return (Map) context.temporaryData; - } - - @Override - public void writeExtraData(MovementContext context) { - super.writeExtraData(context); - getOrReadInventory(context).forEach((s, h) -> context.tileData.put(s, h.serializeNBT())); - } + private static final Object NO_OR_EMPTY_BASIN = new Object(); @Override public boolean hasSpecialMovementRenderer() { @@ -40,25 +29,73 @@ public class BasinMovementBehaviour extends MovementBehaviour { @Override public void tick(MovementContext context) { super.tick(context); - Vec3d facingVec = VecHelper.rotate(new Vec3d(Direction.UP.getDirectionVec()), context.rotation.x, context.rotation.y, context.rotation.z); - facingVec.normalize(); - if (Direction.getFacingFromVector(facingVec.x, facingVec.y, facingVec.z) == Direction.DOWN) - dump(context, facingVec); + if (context.temporaryData != NO_OR_EMPTY_BASIN) { + Vec3d facingVec = VecHelper.rotate(new Vec3d(Direction.UP.getDirectionVec()), context.rotation.x, context.rotation.y, context.rotation.z); + facingVec.normalize(); + if (Direction.getFacingFromVector(facingVec.x, facingVec.y, facingVec.z) == Direction.DOWN) { + dump(context, facingVec); + } + } } private void dump(MovementContext context, Vec3d facingVec) { - getOrReadInventory(context).forEach((key, itemStackHandler) -> { - for (int i = 0; i < itemStackHandler.getSlots(); i++) { - if (itemStackHandler.getStackInSlot(i).isEmpty()) - continue; - ItemEntity itemEntity = new ItemEntity(context.world, context.position.x, context.position.y, context.position.z, itemStackHandler.getStackInSlot(i)); - itemEntity.setMotion(facingVec.scale(.05)); - context.world.addEntity(itemEntity); - itemStackHandler.setStackInSlot(i, ItemStack.EMPTY); + BasinTileEntity te = getOrCreate(context); + if (te == null) + return; + te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(itemStackHandler -> { + if (!(itemStackHandler instanceof IItemHandlerModifiable)) + return; + for (int i = 0; i < itemStackHandler.getSlots(); i++) { + if (itemStackHandler.getStackInSlot(i).isEmpty()) + continue; + ItemEntity itemEntity = new ItemEntity(context.world, context.position.x, context.position.y, context.position.z, itemStackHandler.getStackInSlot(i)); + itemEntity.setMotion(facingVec.scale(.05)); + context.world.addEntity(itemEntity); + ((IItemHandlerModifiable) itemStackHandler).setStackInSlot(i, ItemStack.EMPTY); + } + te.write(context.tileData); + context.temporaryData = NO_OR_EMPTY_BASIN; } - context.tileData.put(key, itemStackHandler.serializeNBT()); - }); - context.temporaryData = null; - context.contraption.customRenderTEs.stream().filter(te -> te.getPos().equals(context.localPos)).forEach(te -> te.read(context.tileData)); + ); + } + + @Nullable + private BasinTileEntity getOrCreate(MovementContext context) { + if (!(context.temporaryData instanceof BasinTileEntity || context.temporaryData == NO_OR_EMPTY_BASIN)) { + if (context.contraption.customRenderTEs.isEmpty()) { + // customRenderTEs are sometimes completely empty? Probably a server thing + context.tileData.putInt("x", context.localPos.getX()); + context.tileData.putInt("y", context.localPos.getY()); + context.tileData.putInt("z", context.localPos.getZ()); + TileEntity te = TileEntity.create(context.tileData); + if (te == null) { + context.temporaryData = NO_OR_EMPTY_BASIN; + return null; + } + te.setLocation(new WrappedWorld(context.world) { + @Override + public BlockState getBlockState(BlockPos pos) { + if (!pos.equals(te.getPos())) + return Blocks.AIR.getDefaultState(); + return context.state; + } + }, te.getPos()); + if (te instanceof KineticTileEntity) + ((KineticTileEntity) te).setSpeed(0); + te.getBlockState(); + context.temporaryData = te; + } else { + for (TileEntity te : context.contraption.customRenderTEs) { + if (te instanceof BasinTileEntity && te.getPos().equals(context.localPos)) { + context.temporaryData = te; + return ((BasinTileEntity) te); + } + } + context.temporaryData = NO_OR_EMPTY_BASIN; + } + } + if (!(context.temporaryData instanceof BasinTileEntity)) + return null; + return ((BasinTileEntity) context.temporaryData); } }