diff --git a/src/main/java/com/simibubi/create/AllShapes.java b/src/main/java/com/simibubi/create/AllShapes.java index cb9a26925..787f245af 100644 --- a/src/main/java/com/simibubi/create/AllShapes.java +++ b/src/main/java/com/simibubi/create/AllShapes.java @@ -75,9 +75,9 @@ public class AllShapes { .forDirectional(UP), BELT_FUNNEL_RETRACTED = shape(3, -5, 14, 13, 13, 19).add(0, -5, 8, 16, 16, 14) .forHorizontal(NORTH), - BELT_FUNNEL_DEFAULT = shape(3, -5, 12, 13, 13, 17).add(0, -5, 6, 16, 16, 12) - .forHorizontal(NORTH), - BELT_FUNNEL_EXTENDED = shape(3, -5, 6, 13, 13, 17).add(0, -5, 0, 16, 16, 6) + BELT_FUNNEL_EXTENDED = shape(3, -4, 6, 13, 13, 17).add(2, -4, 10, 14, 14, 14) + .add(1, -4, 6, 15, 15, 10) + .add(0, -5, 0, 16, 16, 6) .forHorizontal(NORTH), PUMP = shape(2, 0, 2, 14, 5, 14).add(4, 0, 4, 12, 16, 12) .add(3, 12, 3, 13, 16, 13) diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index b418708d8..3dc452168 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -84,6 +84,7 @@ import com.simibubi.create.content.logistics.block.mechanicalArm.ArmRenderer; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity; import com.simibubi.create.content.logistics.block.packager.PackagerRenderer; import com.simibubi.create.content.logistics.block.packager.PackagerTileEntity; +import com.simibubi.create.content.logistics.block.realityFunnel.RealityFunnelTileEntity; import com.simibubi.create.content.logistics.block.redstone.AnalogLeverRenderer; import com.simibubi.create.content.logistics.block.redstone.AnalogLeverTileEntity; import com.simibubi.create.content.logistics.block.redstone.NixieTubeRenderer; @@ -217,11 +218,12 @@ public class AllTileEntities { register("adjustable_crate", AdjustableCrateTileEntity::new, AllBlocks.ADJUSTABLE_CRATE); public static final TileEntityEntry CREATIVE_CRATE = register("creative_crate", CreativeCrateTileEntity::new, AllBlocks.CREATIVE_CRATE); - + + public static final TileEntityEntry REALITY_FUNNEL = register("reality_funnel", + RealityFunnelTileEntity::new, AllBlocks.REALITY_FUNNEL, AllBlocks.BELT_FUNNEL, AllBlocks.CHUTE_FUNNEL); public static final TileEntityEntry PACKAGER = register("packager", PackagerTileEntity::new, AllBlocks.PACKAGER); - - + public static final TileEntityEntry EXTRACTOR = register("extractor", ExtractorTileEntity::new, AllBlocks.EXTRACTOR, AllBlocks.VERTICAL_EXTRACTOR); public static final TileEntityEntry LINKED_EXTRACTOR = register("linked_extractor", @@ -270,7 +272,7 @@ public class AllTileEntities { bind(HAND_CRANK, HandCrankRenderer::new); bind(CUCKOO_CLOCK, CuckooClockRenderer::new); bind(ANALOG_LEVER, AnalogLeverRenderer::new); - + bind(MECHANICAL_PUMP, PumpRenderer::new); bind(FLUID_TANK, FluidTankRenderer::new); @@ -302,6 +304,7 @@ public class AllTileEntities { bind(TRANSPOSER, SmartTileEntityRenderer::new); bind(LINKED_TRANSPOSER, SmartTileEntityRenderer::new); bind(FUNNEL, SmartTileEntityRenderer::new); + bind(REALITY_FUNNEL, SmartTileEntityRenderer::new); bind(BELT_TUNNEL, BeltTunnelRenderer::new); bind(MECHANICAL_ARM, ArmRenderer::new); bind(BELT_OBSERVER, BeltObserverRenderer::new); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/DirectionalExtenderScrollOptionSlot.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/DirectionalExtenderScrollOptionSlot.java index 874833491..b8892c6cd 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/DirectionalExtenderScrollOptionSlot.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/DirectionalExtenderScrollOptionSlot.java @@ -26,7 +26,7 @@ public class DirectionalExtenderScrollOptionSlot extends CenteredSideValueBoxTra @Override protected void rotate(BlockState state, MatrixStack ms) { - if (!direction.getAxis().isHorizontal()) + if (!getSide().getAxis().isHorizontal()) MatrixStacker.of(ms).rotateY(AngleHelper.horizontalAngle(state.get(BlockStateProperties.FACING)) - 90); super.rotate(state, ms); } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/FunnelFilterSlotPositioning.java b/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/FunnelFilterSlotPositioning.java new file mode 100644 index 000000000..fcf0af437 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/FunnelFilterSlotPositioning.java @@ -0,0 +1,96 @@ +package com.simibubi.create.content.logistics.block.realityFunnel; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.logistics.block.realityFunnel.BeltFunnelBlock.Shape; +import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.DirectionHelper; +import com.simibubi.create.foundation.utility.MatrixStacker; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.Direction.AxisDirection; +import net.minecraft.util.math.Vec3d; + +public class FunnelFilterSlotPositioning extends ValueBoxTransform.Sided { + + @Override + protected Vec3d getLocalOffset(BlockState state) { + if (AllBlocks.BELT_FUNNEL.has(state)) + if (state.get(BeltFunnelBlock.SHAPE) == Shape.RETRACTED) + return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 13, 7.5f), + AngleHelper.horizontalAngle(getSide()), Axis.Y); + + Vec3d localOffset = + getSide() == Direction.UP ? VecHelper.voxelSpace(8, 14.5f, 8) : VecHelper.voxelSpace(8, 1.5f, 8); + + if (getSide().getAxis() + .isHorizontal()) { + Vec3d southLocation = VecHelper.voxelSpace(8, 8, 14.5f); + localOffset = VecHelper.rotateCentered(southLocation, AngleHelper.horizontalAngle(getSide()), Axis.Y); + } + + if (AllBlocks.CHUTE_FUNNEL.has(state)) { + Direction facing = state.get(ChuteFunnelBlock.HORIZONTAL_FACING); + localOffset = localOffset.subtract(new Vec3d(facing.getDirectionVec()).scale(2 / 16f)); + } + + return localOffset; + } + + @Override + protected void rotate(BlockState state, MatrixStack ms) { + Direction facing = RealityFunnelBlock.getFunnelFacing(state); + + if (!facing.getAxis() + .isVertical() + && !(AllBlocks.BELT_FUNNEL.has(state) && state.get(BeltFunnelBlock.SHAPE) == Shape.RETRACTED)) { + Direction verticalDirection = DirectionHelper.rotateAround(getSide(), facing.rotateY() + .getAxis()); + if (facing.getAxis() == Axis.Z) + verticalDirection = verticalDirection.getOpposite(); + + boolean reverse = state.getBlock() instanceof HorizontalInteractionFunnelBlock + && !state.get(HorizontalInteractionFunnelBlock.PUSHING); + + float yRot = -AngleHelper.horizontalAngle(verticalDirection) + 180; + float xRot = -90; + boolean alongX = facing.getAxis() == Axis.X; + float zRotLast = alongX ^ facing.getAxisDirection() == AxisDirection.POSITIVE ? 180 : 0; + if (reverse) + zRotLast += 180; + + MatrixStacker.of(ms) + .rotateZ(alongX ? xRot : 0) + .rotateX(alongX ? 0 : xRot) + .rotateY(yRot) + .rotateZ(zRotLast); + return; + } + + super.rotate(state, ms); + } + + @Override + protected boolean isSideActive(BlockState state, Direction direction) { + Direction facing = RealityFunnelBlock.getFunnelFacing(state); + + if (facing == null) + return false; + + if (AllBlocks.BELT_FUNNEL.has(state)) + return state.get(BeltFunnelBlock.SHAPE) == Shape.RETRACTED ? direction == facing + : direction != Direction.DOWN && direction.getAxis() != facing.getAxis(); + + return direction.getAxis() != facing.getAxis(); + } + + @Override + protected Vec3d getSouthLocation() { + return Vec3d.ZERO; + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/HorizontalInteractionFunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/HorizontalInteractionFunnelBlock.java index 57774d5c7..dd53e51d2 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/HorizontalInteractionFunnelBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/HorizontalInteractionFunnelBlock.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.logistics.block.realityFunnel; import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.contraptions.wrench.IWrenchable; import net.minecraft.block.Block; @@ -13,6 +14,7 @@ import net.minecraft.item.ItemUseContext; import net.minecraft.state.BooleanProperty; import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; @@ -33,6 +35,16 @@ public abstract class HorizontalInteractionFunnelBlock extends HorizontalBlock i .with(POWERED, false)); } + @Override + public boolean hasTileEntity(BlockState state) { + return true; + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return AllTileEntities.REALITY_FUNNEL.create(); + } + @Override protected void fillStateContainer(Builder p_206840_1_) { super.fillStateContainer(p_206840_1_.add(HORIZONTAL_FACING, POWERED, PUSHING)); @@ -44,6 +56,16 @@ public abstract class HorizontalInteractionFunnelBlock extends HorizontalBlock i .isBlockPowered(ctx.getPos())); } + @Override + public void onReplaced(BlockState p_196243_1_, World p_196243_2_, BlockPos p_196243_3_, BlockState p_196243_4_, + boolean p_196243_5_) { + if (p_196243_1_.hasTileEntity() + && (p_196243_1_.getBlock() != p_196243_4_.getBlock() && !RealityFunnelBlock.isFunnel(p_196243_4_) + || !p_196243_4_.hasTileEntity())) { + p_196243_2_.removeTileEntity(p_196243_3_); + } + } + @Override public ItemStack getPickBlock(BlockState state, RayTraceResult target, IBlockReader world, BlockPos pos, PlayerEntity player) { diff --git a/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/RealityFunnelBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/RealityFunnelBlock.java index 54db37f47..69cc5eb62 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/RealityFunnelBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/RealityFunnelBlock.java @@ -1,7 +1,10 @@ package com.simibubi.create.content.logistics.block.realityFunnel; +import javax.annotation.Nullable; + import com.simibubi.create.AllBlocks; import com.simibubi.create.AllShapes; +import com.simibubi.create.AllTileEntities; import com.simibubi.create.content.logistics.block.chute.ChuteBlock; import com.simibubi.create.foundation.block.ProperDirectionalBlock; @@ -11,6 +14,7 @@ import net.minecraft.item.BlockItemUseContext; import net.minecraft.state.BooleanProperty; 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.BlockPos; import net.minecraft.util.math.shapes.ISelectionContext; @@ -44,6 +48,16 @@ public class RealityFunnelBlock extends ProperDirectionalBlock { .isBlockPowered(context.getPos())); } + @Override + public boolean hasTileEntity(BlockState state) { + return true; + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return AllTileEntities.REALITY_FUNNEL.create(); + } + @Override protected void fillStateContainer(Builder builder) { super.fillStateContainer(builder.add(POWERED)); @@ -105,4 +119,29 @@ public class RealityFunnelBlock extends ProperDirectionalBlock { return !(block instanceof RealityFunnelBlock) && !(block instanceof HorizontalInteractionFunnelBlock); } + @Nullable + public static Direction getFunnelFacing(BlockState state) { + if (state.has(FACING)) + return state.get(FACING); + if (state.has(BlockStateProperties.HORIZONTAL_FACING)) + return state.get(BlockStateProperties.HORIZONTAL_FACING); + return null; + } + + @Override + public void onReplaced(BlockState p_196243_1_, World p_196243_2_, BlockPos p_196243_3_, BlockState p_196243_4_, + boolean p_196243_5_) { + if (p_196243_1_.hasTileEntity() + && (p_196243_1_.getBlock() != p_196243_4_.getBlock() && !isFunnel(p_196243_4_) + || !p_196243_4_.hasTileEntity())) { + p_196243_2_.removeTileEntity(p_196243_3_); + } + } + + @Nullable + public static boolean isFunnel(BlockState state) { + return state.getBlock() instanceof RealityFunnelBlock + || state.getBlock() instanceof HorizontalInteractionFunnelBlock; + } + } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/RealityFunnelTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/RealityFunnelTileEntity.java new file mode 100644 index 000000000..39283c24a --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/realityFunnel/RealityFunnelTileEntity.java @@ -0,0 +1,36 @@ +package com.simibubi.create.content.logistics.block.realityFunnel; + +import java.util.List; + +import com.simibubi.create.foundation.tileEntity.SmartTileEntity; +import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InsertingBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InventoryManagementBehaviour.Attachments; + +import net.minecraft.tileentity.TileEntityType; + +public class RealityFunnelTileEntity extends SmartTileEntity { + + private FilteringBehaviour filtering; + private InsertingBehaviour inserting; + + public RealityFunnelTileEntity(TileEntityType tileEntityTypeIn) { + super(tileEntityTypeIn); + } + + @Override + public void addBehaviours(List behaviours) { + filtering = new FilteringBehaviour(this, new FunnelFilterSlotPositioning()); + behaviours.add(filtering); + inserting = + new InsertingBehaviour(this, Attachments.toward(() -> RealityFunnelBlock.getFunnelFacing(getBlockState()))); + behaviours.add(inserting); + } + + @Override + public double getMaxRenderDistanceSquared() { + return 64; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBoxTransform.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBoxTransform.java index b9047e1ed..ad6efc0b1 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBoxTransform.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/ValueBoxTransform.java @@ -98,8 +98,8 @@ public abstract class ValueBoxTransform { @Override protected Vec3d getLocalOffset(BlockState state) { Vec3d location = getSouthLocation(); - location = VecHelper.rotateCentered(location, AngleHelper.horizontalAngle(direction), Axis.Y); - location = VecHelper.rotateCentered(location, AngleHelper.verticalAngle(direction), Axis.Z); + location = VecHelper.rotateCentered(location, AngleHelper.horizontalAngle(getSide()), Axis.Y); + location = VecHelper.rotateCentered(location, AngleHelper.verticalAngle(getSide()), Axis.Z); return location; } @@ -107,8 +107,8 @@ public abstract class ValueBoxTransform { @Override protected void rotate(BlockState state, MatrixStack ms) { - float yRot = AngleHelper.horizontalAngle(direction) + 180; - float xRot = direction == Direction.UP ? 90 : direction == Direction.DOWN ? 270 : 0; + float yRot = AngleHelper.horizontalAngle(getSide()) + 180; + float xRot = getSide() == Direction.UP ? 90 : getSide() == Direction.DOWN ? 270 : 0; MatrixStacker.of(ms) .rotateY(yRot) .rotateX(xRot); @@ -116,18 +116,22 @@ public abstract class ValueBoxTransform { @Override public boolean shouldRender(BlockState state) { - return super.shouldRender(state) && isSideActive(state, direction); + return super.shouldRender(state) && isSideActive(state, getSide()); } @Override public boolean testHit(BlockState state, Vec3d localHit) { - return isSideActive(state, direction) && super.testHit(state, localHit); + return isSideActive(state, getSide()) && super.testHit(state, localHit); } protected boolean isSideActive(BlockState state, Direction direction) { return true; } + public Direction getSide() { + return direction; + } + } } diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java index b464b7eb9..4fa82b5e0 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringHandler.java @@ -3,6 +3,8 @@ package com.simibubi.create.foundation.tileEntity.behaviour.filtering; import com.simibubi.create.AllKeys; import com.simibubi.create.content.logistics.item.filter.FilterItem; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; +import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform.Sided; import com.simibubi.create.foundation.utility.RaycastHelper; import net.minecraft.client.Minecraft; @@ -47,15 +49,20 @@ public class FilteringHandler { BlockRayTraceResult ray = RaycastHelper.rayTraceRange(world, player, 10); if (ray == null) return; + if (behaviour.slotPositioning instanceof ValueBoxTransform.Sided) + ((Sided) behaviour.slotPositioning).fromSide(ray.getFace()); if (behaviour.testHit(ray.getHitVec())) { if (event.getSide() != LogicalSide.CLIENT) { - ItemStack heldItem = player.getHeldItem(hand).copy(); + ItemStack heldItem = player.getHeldItem(hand) + .copy(); if (!player.isCreative()) { - if (behaviour.getFilter().getItem() instanceof FilterItem) + if (behaviour.getFilter() + .getItem() instanceof FilterItem) player.inventory.placeItemBackInInventory(world, behaviour.getFilter()); if (heldItem.getItem() instanceof FilterItem) - player.getHeldItem(hand).shrink(1); + player.getHeldItem(hand) + .shrink(1); } if (heldItem.getItem() instanceof FilterItem) heldItem.setCount(1); @@ -87,6 +94,8 @@ public class FilteringHandler { return false; if (!filtering.isCountVisible()) return false; + if (filtering.slotPositioning instanceof ValueBoxTransform.Sided) + ((Sided) filtering.slotPositioning).fromSide(result.getFace()); if (!filtering.testHit(objectMouseOver.getHitVec())) return false; ItemStack filterItem = filtering.getFilter(); diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java index a1032566d..fdafeb1d3 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java @@ -9,6 +9,9 @@ import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBox; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBox.ItemValueBox; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxRenderer; +import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform.Sided; +import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; import net.minecraft.block.BlockState; @@ -16,6 +19,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.world.ClientWorld; import net.minecraft.item.ItemStack; +import net.minecraft.util.Direction; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; @@ -42,6 +46,8 @@ public class FilteringRenderer { return; if (mc.player.isSneaking()) return; + if (behaviour.slotPositioning instanceof ValueBoxTransform.Sided) + ((Sided) behaviour.slotPositioning).fromSide(result.getFace()); if (!behaviour.slotPositioning.shouldRender(state)) return; @@ -83,8 +89,28 @@ public class FilteringRenderer { .isEmpty()) return; + ValueBoxTransform slotPositioning = behaviour.slotPositioning; + BlockState blockState = tileEntityIn.getBlockState(); + + if (slotPositioning instanceof ValueBoxTransform.Sided) { + ValueBoxTransform.Sided sided = (ValueBoxTransform.Sided) slotPositioning; + Direction side = sided.getSide(); + for (Direction d : Iterate.directions) { + sided.fromSide(d); + if (!slotPositioning.shouldRender(blockState)) + continue; + + ms.push(); + slotPositioning.transform(blockState, ms); + ValueBoxRenderer.renderItemIntoValueBox(behaviour.getFilter(), ms, buffer, light, overlay); + ms.pop(); + } + sided.fromSide(side); + return; + } + ms.push(); - behaviour.slotPositioning.transform(tileEntityIn.getBlockState(), ms); + slotPositioning.transform(blockState, ms); ValueBoxRenderer.renderItemIntoValueBox(behaviour.getFilter(), ms, buffer, light, overlay); ms.pop(); }