From cb25c5ab21cc710d0716ca9fe3c198c5628a190b Mon Sep 17 00:00:00 2001 From: _0Steven <42909981+SuicidalSteve@users.noreply.github.com> Date: Sun, 24 Jan 2021 16:46:07 +0100 Subject: [PATCH 1/3] Omnidirectional Crushing -Fix directionality of horizontally placed crushing wheels. -Allow crushing wheels to work omnidirectionally -Allow downwards crushers to deposit directly into belts/chutes/depots and such below. -Allow horizontal crushers to take input from belts going below them. -Allow horizontal crushers to deposit directly into belts/chutes/depots and such placed below, offset by one in the output direction. -Crushers stall when they have a valid output block but cannot actually output. -Crushers outputting in any direction except down will shoot out the item entities with some speed. -Crushers can take entity input from their corresponding input directions rather than just up. However, outputting the entity drops in the right location does currently not work consistently. --- .../java/com/simibubi/create/AllShapes.java | 8 +- .../crusher/CrushingWheelBlock.java | 55 ++++--- .../crusher/CrushingWheelControllerBlock.java | 58 ++++--- .../CrushingWheelControllerTileEntity.java | 144 +++++++++++++----- .../BeltCrusherInteractionHandler.java | 86 +++++++++++ .../relays/belt/transport/BeltInventory.java | 4 + 6 files changed, 281 insertions(+), 74 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltCrusherInteractionHandler.java diff --git a/src/main/java/com/simibubi/create/AllShapes.java b/src/main/java/com/simibubi/create/AllShapes.java index ee77c574d..a96686a77 100644 --- a/src/main/java/com/simibubi/create/AllShapes.java +++ b/src/main/java/com/simibubi/create/AllShapes.java @@ -111,7 +111,10 @@ public class AllShapes { .forHorizontal(Direction.SOUTH), PUMP = shape(2, 0, 2, 14, 5, 14).add(4, 0, 4, 12, 16, 12) .add(3, 12, 3, 13, 16, 13) - .forDirectional(Direction.UP) + .forDirectional(Direction.UP), + CRUSHING_WHEEL_CONTROLLER_COLLISION = shape(0, 0, 0, 16, 13, 16) + .forDirectional(Direction.DOWN) + ; @@ -147,7 +150,8 @@ public class AllShapes { HEATER_BLOCK_SHAPE = shape(2, 0, 2, 14, 14, 14).add(0, 0, 0, 16, 4, 16) .build(), HEATER_BLOCK_SPECIAL_COLLISION_SHAPE = shape(0, 0, 0, 16, 4, 16).build(), - CRUSHING_WHEEL_COLLISION_SHAPE = cuboid(0, 0, 0, 16, 22, 16), SEAT = cuboid(0, 0, 0, 16, 8, 16), + CRUSHING_WHEEL_COLLISION_SHAPE = cuboid(0, 0, 0, 16, 16, 16), + SEAT = cuboid(0, 0, 0, 16, 8, 16), SEAT_COLLISION = cuboid(0, 0, 0, 16, 6, 16), MECHANICAL_PROCESSOR_SHAPE = shape(VoxelShapes.fullCube()).erase(4, 0, 4, 12, 16, 12) .build(), diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelBlock.java index 548b4c6f8..9b76c0b3f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelBlock.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.components.crusher; import static com.simibubi.create.content.contraptions.components.crusher.CrushingWheelControllerBlock.VALID; +import static com.simibubi.create.content.contraptions.components.crusher.CrushingWheelControllerBlock.FACING; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; @@ -17,6 +18,7 @@ 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.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; @@ -53,7 +55,7 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock implements ITE @Override public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { - for (Direction d : Iterate.horizontalDirections) { + for (Direction d : Iterate.directions) { if (d.getAxis() == state.get(AXIS)) continue; if (AllBlocks.CRUSHING_WHEEL_CONTROLLER.has(worldIn.getBlockState(pos.offset(d)))) @@ -65,21 +67,26 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock implements ITE } } - public void updateControllers(BlockState state, World world, BlockPos pos, Direction facing) { - if (facing.getAxis() == state.get(AXIS) || facing.getAxis() - .isVertical()) + public void updateControllers(BlockState state, World world, BlockPos pos, Direction side) { + if (side.getAxis() == state.get(AXIS)) return; if (world == null) return; - BlockPos controllerPos = pos.offset(facing); - BlockPos otherWheelPos = pos.offset(facing, 2); + BlockPos controllerPos = pos.offset(side); + BlockPos otherWheelPos = pos.offset(side, 2); boolean controllerExists = AllBlocks.CRUSHING_WHEEL_CONTROLLER.has(world.getBlockState(controllerPos)); boolean controllerIsValid = controllerExists && world.getBlockState(controllerPos) - .get(VALID); + .get(VALID); + Direction controllerOldDirection = controllerExists + ? world.getBlockState(controllerPos) + .get(FACING) + : null; + boolean controllerShouldExist = false; boolean controllerShouldBeValid = false; + Direction controllerNewDirection = Direction.DOWN; BlockState otherState = world.getBlockState(otherWheelPos); if (AllBlocks.CRUSHING_WHEEL.has(otherState)) { @@ -90,10 +97,22 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock implements ITE CrushingWheelTileEntity otherTe = getTileEntity(world, otherWheelPos); if (te != null && otherTe != null && (te.getSpeed() > 0) != (otherTe.getSpeed() > 0) - && te.getSpeed() != 0) { - float signum = Math.signum(te.getSpeed()) * (state.get(AXIS) == Axis.X ? -1 : 1); - controllerShouldBeValid = facing.getAxisDirection() - .getOffset() != signum; + && te.getSpeed() != 0) { + Axis wheelAxis = state.get(AXIS); + Axis sideAxis = side.getAxis(); + int controllerADO = Math.round(Math.signum(te.getSpeed())) * side.getAxisDirection().getOffset(); + Vec3d controllerDirVec = new Vec3d(wheelAxis == Axis.X ? 1 : 0 + , wheelAxis == Axis.Y ? 1 : 0 + , wheelAxis == Axis.Z ? 1 : 0) + .crossProduct(new Vec3d(sideAxis == Axis.X ? 1 : 0 + , sideAxis == Axis.Y ? 1 : 0 + , sideAxis == Axis.Z ? 1 : 0)); + + controllerNewDirection = Direction.getFacingFromVector(controllerDirVec.x * controllerADO + , controllerDirVec.y * controllerADO + , controllerDirVec.z * controllerADO); + + controllerShouldBeValid = true; } if (otherState.get(AXIS) != state.get(AXIS)) controllerShouldExist = false; @@ -111,18 +130,20 @@ public class CrushingWheelBlock extends RotatedPillarKineticBlock implements ITE if (!controllerExists) { if (!world.getBlockState(controllerPos) - .getMaterial() - .isReplaceable()) + .getMaterial() + .isReplaceable()) return; world.setBlockState(controllerPos, AllBlocks.CRUSHING_WHEEL_CONTROLLER.getDefaultState() - .with(VALID, controllerShouldBeValid)); - } else if (controllerIsValid != controllerShouldBeValid) { + .with(VALID, controllerShouldBeValid) + .with(FACING, controllerNewDirection)); + } else if (controllerIsValid != controllerShouldBeValid || controllerOldDirection != controllerNewDirection) { world.setBlockState(controllerPos, world.getBlockState(controllerPos) - .with(VALID, controllerShouldBeValid)); + .with(VALID, controllerShouldBeValid) + .with(FACING, controllerNewDirection)); } ((CrushingWheelControllerBlock) AllBlocks.CRUSHING_WHEEL_CONTROLLER.get()) - .updateSpeed(world.getBlockState(controllerPos), world, controllerPos); + .updateSpeed(world.getBlockState(controllerPos), world, controllerPos); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerBlock.java b/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerBlock.java index d85549b7f..97ddd3101 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerBlock.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerBlock.java @@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.components.crusher; import java.util.Random; import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllShapes; import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.foundation.block.ITE; @@ -11,6 +12,7 @@ import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.block.DirectionalBlock; import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.entity.player.PlayerEntity; @@ -23,7 +25,7 @@ import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; -import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.shapes.ISelectionContext; @@ -34,7 +36,7 @@ import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorld; import net.minecraft.world.World; -public class CrushingWheelControllerBlock extends Block +public class CrushingWheelControllerBlock extends DirectionalBlock implements ITE { public CrushingWheelControllerBlock(Properties p_i48440_1_) { @@ -66,27 +68,40 @@ public class CrushingWheelControllerBlock extends Block @Override protected void fillStateContainer(Builder builder) { builder.add(VALID); + builder.add(FACING); super.fillStateContainer(builder); } public void onEntityCollision(BlockState state, World worldIn, BlockPos pos, Entity entityIn) { if (!state.get(VALID)) return; + + Direction facing = state.get(FACING); + Axis axis = facing.getAxis(); + + checkEntityForProcessing(worldIn, pos, entityIn); + withTileEntityDo(worldIn, pos, te -> { if (te.processingEntity == entityIn) - entityIn.setMotionMultiplier(state, new Vec3d(0.25D, (double) 0.05F, 0.25D)); + + entityIn.setMotionMultiplier(state, new Vec3d(axis == Axis.X ? (double) 0.05F : 0.25D + , axis == Axis.Y ? (double) 0.05F : 0.25D + , axis == Axis.Z ? (double) 0.05F : 0.25D)); }); } - @Override - public void onLanded(IBlockReader worldIn, Entity entityIn) { - super.onLanded(worldIn, entityIn); + public void checkEntityForProcessing(World worldIn, BlockPos pos, Entity entityIn){ try { - CrushingWheelControllerTileEntity te = getTileEntity(worldIn, entityIn.getPosition().down()); + CrushingWheelControllerTileEntity te = getTileEntity(worldIn, pos); if (te.crushingspeed == 0) return; if (entityIn instanceof ItemEntity) ((ItemEntity) entityIn).setPickupDelay(10); + CompoundNBT data = entityIn.getPersistentData(); + if (data.contains("BypassCrushingWheel")) { + if (pos.equals(NBTUtil.readBlockPos(data.getCompound("BypassCrushingWheel")))) + return; + } if (te.isOccupied()) return; boolean isPlayer = entityIn instanceof PlayerEntity; @@ -99,6 +114,12 @@ public class CrushingWheelControllerBlock extends Block } catch (TileEntityException e) {} } + @Override + public void onLanded(IBlockReader worldIn, Entity entityIn) { + super.onLanded(worldIn, entityIn); + //Moved to onEntityCollision to allow for omnidirectional input + } + @Override public void animateTick(BlockState stateIn, World worldIn, BlockPos pos, Random rand) { if (!stateIn.get(VALID)) @@ -128,7 +149,7 @@ public class CrushingWheelControllerBlock extends Block return; } - for (Direction d : Iterate.horizontalDirections) { + for (Direction d : Iterate.directions) { BlockState neighbour = world.getBlockState(pos.offset(d)); if (!AllBlocks.CRUSHING_WHEEL.has(neighbour)) continue; @@ -144,22 +165,19 @@ public class CrushingWheelControllerBlock extends Block @Override public VoxelShape getCollisionShape(BlockState state, IBlockReader worldIn, BlockPos pos, - ISelectionContext context) { + ISelectionContext context) { if (!state.get(VALID)) - return VoxelShapes.fullCube(); + return AllShapes.CRUSHING_WHEEL_CONTROLLER_COLLISION.get(state.get(FACING)); Entity entity = context.getEntity(); if (entity != null) { - if (entity != null) { - CompoundNBT data = entity.getPersistentData(); - if (data.contains("BypassCrushingWheel")) { - if (pos.equals(NBTUtil.readBlockPos(data.getCompound("BypassCrushingWheel")))) - return VoxelShapes.empty(); - } - } - if (new AxisAlignedBB(pos).contains(entity.getPositionVec())) - return VoxelShapes.empty(); + CompoundNBT data = entity.getPersistentData(); + if (data.contains("BypassCrushingWheel")) { + if (pos.equals(NBTUtil.readBlockPos(data.getCompound("BypassCrushingWheel")))) + if (state.get(FACING) != Direction.UP) //Allow output items to land on top of the block rather than falling back through. + return VoxelShapes.empty(); + } try { CrushingWheelControllerTileEntity te = getTileEntity(worldIn, pos); @@ -167,7 +185,7 @@ public class CrushingWheelControllerBlock extends Block return VoxelShapes.empty(); } catch (TileEntityException e) {} } - return VoxelShapes.fullCube(); + return AllShapes.CRUSHING_WHEEL_CONTROLLER_COLLISION.get(state.get(FACING)); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerTileEntity.java index 2c1eb2f3b..88d2ee50e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerTileEntity.java @@ -6,6 +6,8 @@ import java.util.Optional; import java.util.Random; import java.util.UUID; +import static com.simibubi.create.content.contraptions.components.crusher.CrushingWheelControllerBlock.FACING; + import com.simibubi.create.AllRecipeTypes; import com.simibubi.create.content.contraptions.processing.ProcessingInventory; import com.simibubi.create.content.contraptions.processing.ProcessingRecipe; @@ -16,6 +18,7 @@ import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; import com.simibubi.create.foundation.utility.VecHelper; +import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; import net.minecraft.item.BlockItem; @@ -28,7 +31,9 @@ import net.minecraft.particles.ItemParticleData; import net.minecraft.particles.ParticleTypes; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraftforge.common.capabilities.Capability; @@ -63,7 +68,15 @@ public class CrushingWheelControllerTileEntity extends SmartTileEntity { @Override public void addBehaviours(List behaviours) { - behaviours.add(new DirectBeltInputBehaviour(this)); + behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::supportsDirectBeltInput)); + } + + private boolean supportsDirectBeltInput(Direction side) { + BlockState blockState = getBlockState(); + if (blockState == null) + return false; + Direction direction = blockState.get(CrushingWheelControllerBlock.FACING); + return direction == Direction.DOWN || direction == side; } @Override @@ -72,26 +85,37 @@ public class CrushingWheelControllerTileEntity extends SmartTileEntity { if (searchForEntity) { searchForEntity = false; List search = world.getEntitiesInAABBexcluding(null, new AxisAlignedBB(getPos()), - e -> entityUUID.equals(e.getUniqueID())); + e -> entityUUID.equals(e.getUniqueID())); if (search.isEmpty()) clear(); else processingEntity = search.get(0); } + + if (!isOccupied()) return; if (crushingspeed == 0) return; float speed = crushingspeed * 4; - Vec3d outPos = VecHelper.getCenterOf(pos); + + Vec3d centerPos = VecHelper.getCenterOf(pos); + Direction facing = getBlockState().get(FACING); + int offset = facing.getAxisDirection().getOffset(); + Vec3d outSpeed = new Vec3d((facing.getAxis() == Axis.X ? 0.25D : 0.0D) * offset + , offset == 1 ? (facing.getAxis() == Axis.Y ? 0.5D : 0.0D) : 0.0D //Increased upwards speed so upwards crushing wheels shoot out the item properly. + , (facing.getAxis() == Axis.Z ? 0.25D : 0.0D) * offset); //No downwards speed, so downwards crushing wheels drop the items as before. + Vec3d outPos = centerPos.add((facing.getAxis() == Axis.X ? .55f * offset : 0f) + , (facing.getAxis() == Axis.Y ? .55f * offset : 0f) + , (facing.getAxis() == Axis.Z ? .55f * offset : 0f)); if (!hasEntity()) { float processingSpeed = - MathHelper.clamp((speed) / (!inventory.appliedRecipe ? MathHelper.log2(inventory.getStackInSlot(0) - .getCount()) : 1), .25f, 20); + MathHelper.clamp((speed) / (!inventory.appliedRecipe ? MathHelper.log2(inventory.getStackInSlot(0) + .getCount()) : 1), .25f, 20); inventory.remainingTime -= processingSpeed; spawnParticles(inventory.getStackInSlot(0)); @@ -105,61 +129,111 @@ public class CrushingWheelControllerTileEntity extends SmartTileEntity { return; } - if (inventory.remainingTime <= 0) { - for (int slot = 0; slot < inventory.getSlots(); slot++) { - ItemStack stack = inventory.getStackInSlot(slot); - if (stack.isEmpty()) - continue; - ItemEntity entityIn = new ItemEntity(world, outPos.x, outPos.y, outPos.z, stack); - entityIn.setMotion(Vec3d.ZERO); - entityIn.getPersistentData() - .put("BypassCrushingWheel", NBTUtil.writeBlockPos(pos)); - world.addEntity(entityIn); - } - inventory.clear(); - world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), 2 | 16); + if (inventory.remainingTime > 0) { return; } + inventory.remainingTime = 0; + + //Output Items + if (facing.getAxis().isHorizontal() || facing == Direction.DOWN) { + BlockPos nextPos = pos.add(facing.getAxis() == Axis.X ? 1f * offset : 0f + , (facing == Direction.DOWN || facing.getAxis().isHorizontal()) ? -1f : 0f + , facing.getAxis() == Axis.Z ? 1f * offset : 0f); + DirectBeltInputBehaviour behaviour = TileEntityBehaviour.get(world, nextPos, DirectBeltInputBehaviour.TYPE); + if (behaviour != null) { + boolean changed = false; + if (!behaviour.canInsertFromSide(facing)) + return; + for (int slot = 0; slot < inventory.getSlots(); slot++) { + ItemStack stack = inventory.getStackInSlot(slot); + if (stack.isEmpty()) + continue; + ItemStack remainder = behaviour.handleInsertion(stack, facing, false); + if (remainder.equals(stack, false)) + continue; + inventory.setStackInSlot(slot, remainder); + changed = true; + } + if (changed) { + markDirty(); + sendData(); + } + return; + } + } + + //Eject Items + for (int slot = 0; slot < inventory.getSlots(); slot++) { + ItemStack stack = inventory.getStackInSlot(slot); + if (stack.isEmpty()) + continue; + ItemEntity entityIn = new ItemEntity(world, outPos.x, outPos.y, outPos.z, stack); + entityIn.setMotion(outSpeed); + entityIn.getPersistentData() + .put("BypassCrushingWheel", NBTUtil.writeBlockPos(pos)); + world.addEntity(entityIn); + } + inventory.clear(); + world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), 2 | 16); + return; } if (!processingEntity.isAlive() || !processingEntity.getBoundingBox() - .intersects(new AxisAlignedBB(pos).grow(.5f))) { + .intersects(new AxisAlignedBB(pos).grow(.5f))) { clear(); return; } double xMotion = ((pos.getX() + .5f) - processingEntity.getX()) / 2f; + double yMotion = ((pos.getY() + .5f) - processingEntity.getY()) / 2f; double zMotion = ((pos.getZ() + .5f) - processingEntity.getZ()) / 2f; if (processingEntity.isSneaking()) xMotion = zMotion = 0; - - processingEntity.setMotion(new Vec3d(xMotion, Math.max(-speed / 4f, -.5f), zMotion)); + double movement = Math.max(-speed / 4f, -.5f) * -offset; + processingEntity.setMotion(new Vec3d(facing.getAxis() == Axis.X ? movement : xMotion + , facing.getAxis() == Axis.Y ? movement : 0f //Do not move entities upwards or downwards for horizontal crushers, + , facing.getAxis() == Axis.Z ? movement : zMotion)); //Or they'll only get their feet crushed. if (world.isRemote) return; if (!(processingEntity instanceof ItemEntity)) { processingEntity.attackEntityFrom(CrushingWheelTileEntity.damageSource, - AllConfigs.SERVER.kinetics.crushingDamage.get()); + AllConfigs.SERVER.kinetics.crushingDamage.get()); if (!processingEntity.isAlive()) { - processingEntity.setPosition(outPos.x, outPos.y - .75f, outPos.z); + processingEntity.setPosition(outPos.x + (facing.getAxis() == Axis.X ? .75f * offset : 0f) //This is supposed to move the mobs to the output location + , outPos.y + (facing.getAxis() == Axis.Y ? .75f * offset : 0f) //So the item drops end up on the other end + , outPos.z + (facing.getAxis() == Axis.Z ? .75f * offset : 0f)); //This, however, does not currently work consistently for non-downwards crushers. } return; } ItemEntity itemEntity = (ItemEntity) processingEntity; itemEntity.setPickupDelay(20); - if (processingEntity.getY() < pos.getY() + .25f) { - inventory.clear(); - inventory.setStackInSlot(0, itemEntity.getItem() - .copy()); - itemInserted(inventory.getStackInSlot(0)); - itemEntity.remove(); - world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), 2 | 16); + if (facing.getAxis() == Axis.Y) { + if (processingEntity.getY() * -offset < (centerPos.y - .25f) * -offset) { + intakeItem(itemEntity); + } + } else if (facing.getAxis() == Axis.Z) { + if (processingEntity.getZ() * -offset < (centerPos.z - .25f) * -offset) { + intakeItem(itemEntity); + } + } else { + if (processingEntity.getX() * -offset < (centerPos.x - .25f) * -offset) { + intakeItem(itemEntity); + } } + } + private void intakeItem(ItemEntity itemEntity) { + inventory.clear(); + inventory.setStackInSlot(0, itemEntity.getItem() + .copy()); + itemInserted(inventory.getStackInSlot(0)); + itemEntity.remove(); + world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), 2 | 16); } protected void spawnParticles(ItemStack stack) { @@ -169,14 +243,14 @@ public class CrushingWheelControllerTileEntity extends SmartTileEntity { IParticleData particleData = null; if (stack.getItem() instanceof BlockItem) particleData = new BlockParticleData(ParticleTypes.BLOCK, ((BlockItem) stack.getItem()).getBlock() - .getDefaultState()); + .getDefaultState()); else particleData = new ItemParticleData(ParticleTypes.ITEM, stack); Random r = world.rand; for (int i = 0; i < 4; i++) world.addParticle(particleData, pos.getX() + r.nextFloat(), pos.getY() + r.nextFloat(), - pos.getZ() + r.nextFloat(), 0, 0, 0); + pos.getZ() + r.nextFloat(), 0, 0, 0); } private void applyRecipe() { @@ -185,11 +259,11 @@ public class CrushingWheelControllerTileEntity extends SmartTileEntity { List list = new ArrayList<>(); if (recipe.isPresent()) { int rolls = inventory.getStackInSlot(0) - .getCount(); + .getCount(); inventory.clear(); for (int roll = 0; roll < rolls; roll++) { List rolledResults = recipe.get() - .rollResults(); + .rollResults(); for (int i = 0; i < rolledResults.size(); i++) { ItemStack stack = rolledResults.get(i); ItemHelper.addToList(stack, list); @@ -238,7 +312,7 @@ public class CrushingWheelControllerTileEntity extends SmartTileEntity { private void itemInserted(ItemStack stack) { Optional> recipe = findRecipe(); inventory.remainingTime = recipe.isPresent() ? recipe.get() - .getProcessingDuration() : 100; + .getProcessingDuration() : 100; inventory.appliedRecipe = false; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltCrusherInteractionHandler.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltCrusherInteractionHandler.java new file mode 100644 index 000000000..c1c9fae10 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltCrusherInteractionHandler.java @@ -0,0 +1,86 @@ +package com.simibubi.create.content.contraptions.relays.belt.transport; + +import com.simibubi.create.content.contraptions.components.crusher.CrushingWheelControllerBlock; +import com.simibubi.create.content.contraptions.components.crusher.CrushingWheelControllerTileEntity; +import com.simibubi.create.content.contraptions.relays.belt.BeltHelper; +import net.minecraft.block.BlockState; +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.MathHelper; +import net.minecraft.world.World; +import net.minecraftforge.items.ItemHandlerHelper; + +public class BeltCrusherInteractionHandler { + + public static boolean checkForCrushers(BeltInventory beltInventory, TransportedItemStack currentItem, + float nextOffset) { + + boolean beltMovementPositive = beltInventory.beltMovementPositive; + int firstUpcomingSegment = (int) Math.floor(currentItem.beltPosition); + int step = beltMovementPositive ? 1 : -1; + firstUpcomingSegment = MathHelper.clamp(firstUpcomingSegment, 0, beltInventory.belt.beltLength - 1); + + for (int segment = firstUpcomingSegment; beltMovementPositive ? segment <= nextOffset + : segment + 1 >= nextOffset; segment += step) { + BlockPos crusherPos = BeltHelper.getPositionForOffset(beltInventory.belt, segment) + .up(); + World world = beltInventory.belt.getWorld(); + BlockState crusherState = world.getBlockState(crusherPos); + if (!(crusherState.getBlock() instanceof CrushingWheelControllerBlock)) + continue; + Direction crusherFacing = crusherState.get(CrushingWheelControllerBlock.FACING); + Direction movementFacing = beltInventory.belt.getMovementFacing(); + boolean blocking = crusherFacing == movementFacing; + if (crusherFacing != movementFacing) + continue; + + float crusherEntry = segment + .5f; + crusherEntry += .399f * (beltMovementPositive ? -1 : 1); + + boolean hasCrossed = nextOffset > crusherEntry && beltMovementPositive + || nextOffset < crusherEntry && !beltMovementPositive; + if (!hasCrossed) + return false; + if (blocking) + currentItem.beltPosition = crusherEntry; + + TileEntity te = world.getTileEntity(crusherPos); + if (!(te instanceof CrushingWheelControllerTileEntity)) + return true; + + CrushingWheelControllerTileEntity crusherTE = (CrushingWheelControllerTileEntity) te; + + int amountToExtract = -1; + ItemStack toInsert = currentItem.stack.copy(); + if (amountToExtract > toInsert.getCount()) + if (blocking) + return true; + else + continue; + + ItemStack remainder = ItemHandlerHelper.insertItemStacked(crusherTE.inventory, toInsert, false); + if (toInsert.equals(remainder, false)) + if (blocking) + return true; + else + continue; + + int notFilled = currentItem.stack.getCount() - toInsert.getCount(); + if (!remainder.isEmpty()) { + remainder.grow(notFilled); + } else if (notFilled > 0) + remainder = ItemHandlerHelper.copyStackWithSize(currentItem.stack, notFilled); + + currentItem.stack = remainder; + beltInventory.belt.sendData(); + if (blocking) + return true; + } + + return false; + } + + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltInventory.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltInventory.java index 1284afba9..1646171bd 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltInventory.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltInventory.java @@ -151,6 +151,10 @@ public class BeltInventory { if (BeltFunnelInteractionHandler.checkForFunnels(this, currentItem, nextOffset)) continue; + // Horizontal Crushing Wheels + if (BeltCrusherInteractionHandler.checkForCrushers(this, currentItem, nextOffset)) + continue; + // Apply Movement currentItem.beltPosition += limitedMovement; currentItem.sideOffset += From f1c8e926861257cc0c61a448ac96c12f6f9bac71 Mon Sep 17 00:00:00 2001 From: _0Steven <42909981+SuicidalSteve@users.noreply.github.com> Date: Mon, 25 Jan 2021 16:39:47 +0100 Subject: [PATCH 2/3] Horizontal Crushers Bugfix -Fix bug where horizontal crushers would input items they just output when the belt was 'facing' the opposite direction. --- .../CrushingWheelControllerTileEntity.java | 2 +- .../BeltCrusherInteractionHandler.java | 23 +++++-------------- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerTileEntity.java index 88d2ee50e..147605918 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crusher/CrushingWheelControllerTileEntity.java @@ -137,7 +137,7 @@ public class CrushingWheelControllerTileEntity extends SmartTileEntity { //Output Items if (facing.getAxis().isHorizontal() || facing == Direction.DOWN) { BlockPos nextPos = pos.add(facing.getAxis() == Axis.X ? 1f * offset : 0f - , (facing == Direction.DOWN || facing.getAxis().isHorizontal()) ? -1f : 0f + , (-1f) , facing.getAxis() == Axis.Z ? 1f * offset : 0f); DirectBeltInputBehaviour behaviour = TileEntityBehaviour.get(world, nextPos, DirectBeltInputBehaviour.TYPE); if (behaviour != null) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltCrusherInteractionHandler.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltCrusherInteractionHandler.java index c1c9fae10..61a6b1514 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltCrusherInteractionHandler.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltCrusherInteractionHandler.java @@ -32,19 +32,18 @@ public class BeltCrusherInteractionHandler { continue; Direction crusherFacing = crusherState.get(CrushingWheelControllerBlock.FACING); Direction movementFacing = beltInventory.belt.getMovementFacing(); - boolean blocking = crusherFacing == movementFacing; if (crusherFacing != movementFacing) continue; float crusherEntry = segment + .5f; crusherEntry += .399f * (beltMovementPositive ? -1 : 1); + float postCrusherEntry = crusherEntry + .199f * (!beltMovementPositive ? -1 : 1); - boolean hasCrossed = nextOffset > crusherEntry && beltMovementPositive - || nextOffset < crusherEntry && !beltMovementPositive; + boolean hasCrossed = nextOffset > crusherEntry && nextOffset < postCrusherEntry && beltMovementPositive + || nextOffset < crusherEntry && nextOffset > postCrusherEntry && !beltMovementPositive; if (!hasCrossed) return false; - if (blocking) - currentItem.beltPosition = crusherEntry; + currentItem.beltPosition = crusherEntry; TileEntity te = world.getTileEntity(crusherPos); if (!(te instanceof CrushingWheelControllerTileEntity)) @@ -52,20 +51,11 @@ public class BeltCrusherInteractionHandler { CrushingWheelControllerTileEntity crusherTE = (CrushingWheelControllerTileEntity) te; - int amountToExtract = -1; ItemStack toInsert = currentItem.stack.copy(); - if (amountToExtract > toInsert.getCount()) - if (blocking) - return true; - else - continue; ItemStack remainder = ItemHandlerHelper.insertItemStacked(crusherTE.inventory, toInsert, false); if (toInsert.equals(remainder, false)) - if (blocking) - return true; - else - continue; + return true; int notFilled = currentItem.stack.getCount() - toInsert.getCount(); if (!remainder.isEmpty()) { @@ -75,8 +65,7 @@ public class BeltCrusherInteractionHandler { currentItem.stack = remainder; beltInventory.belt.sendData(); - if (blocking) - return true; + return true; } return false; From 53a6ad00d505b5b1f4956c213357d16c094d3ca9 Mon Sep 17 00:00:00 2001 From: _0Steven <42909981+SuicidalSteve@users.noreply.github.com> Date: Tue, 26 Jan 2021 19:11:45 +0100 Subject: [PATCH 3/3] Crushing More Bugs -Increase the size of the window in which the crusher picks up items to avoid it skipping over items at some of the highest speeds. --- .../relays/belt/transport/BeltCrusherInteractionHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltCrusherInteractionHandler.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltCrusherInteractionHandler.java index 61a6b1514..5568591f1 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltCrusherInteractionHandler.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/transport/BeltCrusherInteractionHandler.java @@ -37,7 +37,7 @@ public class BeltCrusherInteractionHandler { float crusherEntry = segment + .5f; crusherEntry += .399f * (beltMovementPositive ? -1 : 1); - float postCrusherEntry = crusherEntry + .199f * (!beltMovementPositive ? -1 : 1); + float postCrusherEntry = crusherEntry + .799f * (!beltMovementPositive ? -1 : 1); boolean hasCrossed = nextOffset > crusherEntry && nextOffset < postCrusherEntry && beltMovementPositive || nextOffset < crusherEntry && nextOffset > postCrusherEntry && !beltMovementPositive;