mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-11 04:22:00 +01:00
Chute Implementation
- Chutes can now transfer items - Chutes now propagate air flow from attached fans - Fixed a few issues with mechanical arms - Removed unused chute models - Implemented appropriate interactions between funnels and chutes
This commit is contained in:
parent
f820e2be27
commit
cd189a5fa9
27 changed files with 891 additions and 368 deletions
|
@ -74,8 +74,8 @@ public class AllShapes {
|
|||
.add(0, 10, 0, 16, 13, 16)
|
||||
.forDirectional(UP),
|
||||
CHUTE_FUNNEL = shape(3, -2, 3, 13, 2, 13).add(2, 2, 2, 14, 6, 14)
|
||||
.add(1, 5, 1, 15, 16, 15)
|
||||
.add(0, 8, 0, 16, 14, 16)
|
||||
.add(1, 5, 1, 15, 18, 15)
|
||||
.forDirectional(UP),
|
||||
BELT_FUNNEL_RETRACTED = shape(3, -5, 14, 13, 13, 19).add(0, -5, 8, 16, 16, 14)
|
||||
.forHorizontal(NORTH),
|
||||
|
|
|
@ -72,6 +72,8 @@ import com.simibubi.create.content.logistics.block.belts.observer.BeltObserverRe
|
|||
import com.simibubi.create.content.logistics.block.belts.observer.BeltObserverTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelRenderer;
|
||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.chute.ChuteRenderer;
|
||||
import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.depot.DepotRenderer;
|
||||
import com.simibubi.create.content.logistics.block.depot.DepotTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.diodes.AdjustablePulseRepeaterTileEntity;
|
||||
|
@ -154,6 +156,8 @@ public class AllTileEntities {
|
|||
register("fluid_tank", FluidTankTileEntity::new, AllBlocks.FLUID_TANK);
|
||||
|
||||
public static final TileEntityEntry<BeltTileEntity> BELT = register("belt", BeltTileEntity::new, AllBlocks.BELT);
|
||||
public static final TileEntityEntry<ChuteTileEntity> CHUTE =
|
||||
register("chute", ChuteTileEntity::new, AllBlocks.CHUTE);
|
||||
public static final TileEntityEntry<BeltTunnelTileEntity> BELT_TUNNEL =
|
||||
register("belt_tunnel", BeltTunnelTileEntity::new, AllBlocks.BELT_TUNNEL);
|
||||
public static final TileEntityEntry<ArmTileEntity> MECHANICAL_ARM =
|
||||
|
@ -301,6 +305,7 @@ public class AllTileEntities {
|
|||
bind(ROTATION_SPEED_CONTROLLER, SpeedControllerRenderer::new);
|
||||
bind(PACKAGER, PackagerRenderer::new);
|
||||
bind(DEPOT, DepotRenderer::new);
|
||||
bind(CHUTE, ChuteRenderer::new);
|
||||
|
||||
bind(CREATIVE_CRATE, SmartTileEntityRenderer::new);
|
||||
bind(REDSTONE_LINK, SmartTileEntityRenderer::new);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.content.contraptions.components.fan;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
|
@ -34,19 +35,38 @@ public class EncasedFanBlock extends DirectionalKineticBlock implements ITE<Enca
|
|||
blockUpdate(state, worldIn, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReplaced(BlockState state, World world, BlockPos pos, BlockState p_196243_4_, boolean p_196243_5_) {
|
||||
if (state.hasTileEntity() && (state.getBlock() != p_196243_4_.getBlock() || !p_196243_4_.hasTileEntity())) {
|
||||
withTileEntityDo(world, pos, EncasedFanTileEntity::updateChute);
|
||||
world.removeTileEntity(pos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos,
|
||||
boolean isMoving) {
|
||||
boolean isMoving) {
|
||||
blockUpdate(state, worldIn, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getStateForPlacement(BlockItemUseContext context) {
|
||||
World world = context.getWorld();
|
||||
BlockPos pos = context.getPos();
|
||||
Direction face = context.getFace();
|
||||
|
||||
BlockState placedOn = world.getBlockState(pos.offset(face.getOpposite()));
|
||||
BlockState placedOnOpposite = world.getBlockState(pos.offset(face));
|
||||
if (AllBlocks.CHUTE.has(placedOn))
|
||||
return getDefaultState().with(FACING, face.getOpposite());
|
||||
if (AllBlocks.CHUTE.has(placedOnOpposite))
|
||||
return getDefaultState().with(FACING, face);
|
||||
|
||||
Direction preferredFacing = getPreferredFacing(context);
|
||||
if (preferredFacing == null)
|
||||
preferredFacing = context.getNearestLookingDirection();
|
||||
return getDefaultState().with(FACING,
|
||||
context.getPlayer().isSneaking() ? preferredFacing : preferredFacing.getOpposite());
|
||||
return getDefaultState().with(FACING, context.getPlayer()
|
||||
.isSneaking() ? preferredFacing : preferredFacing.getOpposite());
|
||||
}
|
||||
|
||||
protected void blockUpdate(BlockState state, World worldIn, BlockPos pos) {
|
||||
|
@ -70,14 +90,16 @@ public class EncasedFanBlock extends DirectionalKineticBlock implements ITE<Enca
|
|||
|
||||
@Override
|
||||
public Axis getRotationAxis(BlockState state) {
|
||||
return state.get(FACING).getAxis();
|
||||
return state.get(FACING)
|
||||
.getAxis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasShaftTowards(IWorldReader world, BlockPos pos, BlockState state, Direction face) {
|
||||
return face == state.get(FACING).getOpposite();
|
||||
return face == state.get(FACING)
|
||||
.getOpposite();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean showCapacityWithAnnotation() {
|
||||
return true;
|
||||
|
|
|
@ -2,11 +2,13 @@ package com.simibubi.create.content.contraptions.components.fan;
|
|||
|
||||
import com.simibubi.create.AllTags.AllBlockTags;
|
||||
import com.simibubi.create.content.contraptions.base.GeneratingKineticTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.config.CKinetics;
|
||||
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
@ -60,7 +62,8 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
|
|||
}
|
||||
|
||||
public void updateGenerator(Direction facing) {
|
||||
boolean shouldGenerate = world.isBlockPowered(pos) && facing == Direction.DOWN && world.isBlockPresent(pos.down()) && blockBelowIsHot();
|
||||
boolean shouldGenerate = world.isBlockPowered(pos) && facing == Direction.DOWN
|
||||
&& world.isBlockPresent(pos.down()) && blockBelowIsHot();
|
||||
if (shouldGenerate == isGenerator)
|
||||
return;
|
||||
|
||||
|
@ -69,7 +72,9 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
|
|||
}
|
||||
|
||||
public boolean blockBelowIsHot() {
|
||||
return world.getBlockState(pos.down()).getBlock().isIn(AllBlockTags.FAN_HEATERS.tag);
|
||||
return world.getBlockState(pos.down())
|
||||
.getBlock()
|
||||
.isIn(AllBlockTags.FAN_HEATERS.tag);
|
||||
}
|
||||
|
||||
public float getMaxDistance() {
|
||||
|
@ -94,6 +99,22 @@ public class EncasedFanTileEntity extends GeneratingKineticTileEntity {
|
|||
public void onSpeedChanged(float prevSpeed) {
|
||||
super.onSpeedChanged(prevSpeed);
|
||||
updateAirFlow = true;
|
||||
updateChute();
|
||||
}
|
||||
|
||||
public void updateChute() {
|
||||
Direction direction = getBlockState().get(EncasedFanBlock.FACING);
|
||||
if (!direction.getAxis()
|
||||
.isVertical())
|
||||
return;
|
||||
TileEntity poweredChute = world.getTileEntity(pos.offset(direction));
|
||||
if (!(poweredChute instanceof ChuteTileEntity))
|
||||
return;
|
||||
ChuteTileEntity chuteTE = (ChuteTileEntity) poweredChute;
|
||||
if (direction == Direction.DOWN)
|
||||
chuteTE.updatePull();
|
||||
else
|
||||
chuteTE.updatePush(1);
|
||||
}
|
||||
|
||||
public void blockInFrontChanged() {
|
||||
|
|
|
@ -9,6 +9,9 @@ import net.minecraft.nbt.CompoundNBT;
|
|||
import net.minecraft.util.Direction;
|
||||
|
||||
public class TransportedItemStack implements Comparable<TransportedItemStack> {
|
||||
|
||||
private static Random R = new Random();
|
||||
|
||||
public ItemStack stack;
|
||||
public float beltPosition;
|
||||
public float sideOffset;
|
||||
|
@ -25,7 +28,7 @@ public class TransportedItemStack implements Comparable<TransportedItemStack> {
|
|||
|
||||
public TransportedItemStack(ItemStack stack) {
|
||||
this.stack = stack;
|
||||
angle = new Random().nextInt(360);
|
||||
angle = R.nextInt(360);
|
||||
sideOffset = prevSideOffset = getTargetSideOffset();
|
||||
insertedFrom = Direction.UP;
|
||||
}
|
||||
|
|
|
@ -4,23 +4,34 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
import com.simibubi.create.AllShapes;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.state.DirectionProperty;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.state.IProperty;
|
||||
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.Hand;
|
||||
import net.minecraft.util.IStringSerializable;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
|
@ -28,7 +39,7 @@ import net.minecraft.world.IWorld;
|
|||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ChuteBlock extends Block implements IWrenchable {
|
||||
public class ChuteBlock extends Block implements IWrenchable, ITE<ChuteTileEntity> {
|
||||
public static final IProperty<Shape> SHAPE = EnumProperty.create("shape", Shape.class);
|
||||
public static final DirectionProperty FACING = BlockStateProperties.FACING_EXCEPT_UP;
|
||||
|
||||
|
@ -41,6 +52,16 @@ public class ChuteBlock extends Block implements IWrenchable {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileEntity createTileEntity(BlockState state, IBlockReader world) {
|
||||
return AllTileEntities.CHUTE.create();
|
||||
}
|
||||
|
||||
public ChuteBlock(Properties p_i48440_1_) {
|
||||
super(p_i48440_1_);
|
||||
setDefaultState(getDefaultState().with(SHAPE, Shape.NORMAL)
|
||||
|
@ -48,10 +69,34 @@ public class ChuteBlock extends Block implements IWrenchable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState p_220082_4_, boolean p_220082_5_) {
|
||||
if (p_220082_5_)
|
||||
public void onLanded(IBlockReader worldIn, Entity entityIn) {
|
||||
super.onLanded(worldIn, entityIn);
|
||||
if (!(entityIn instanceof ItemEntity))
|
||||
return;
|
||||
if (entityIn.world.isRemote)
|
||||
return;
|
||||
DirectBeltInputBehaviour input = TileEntityBehaviour.get(entityIn.world, new BlockPos(entityIn.getPositionVec()
|
||||
.add(0, 0.5f, 0)).down(), DirectBeltInputBehaviour.TYPE);
|
||||
if (input == null)
|
||||
return;
|
||||
if (!input.canInsertFromSide(Direction.UP))
|
||||
return;
|
||||
|
||||
ItemEntity itemEntity = (ItemEntity) entityIn;
|
||||
ItemStack toInsert = itemEntity.getItem();
|
||||
ItemStack remainder = input.handleInsertion(toInsert, Direction.UP, false);
|
||||
|
||||
if (remainder.isEmpty())
|
||||
itemEntity.remove();
|
||||
if (remainder.getCount() < toInsert.getCount())
|
||||
itemEntity.setItem(remainder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockAdded(BlockState state, World world, BlockPos pos, BlockState p_220082_4_, boolean p_220082_5_) {
|
||||
withTileEntityDo(world, pos, ChuteTileEntity::onAdded);
|
||||
if (p_220082_5_)
|
||||
return;
|
||||
updateDiagonalNeighbour(state, world, pos);
|
||||
}
|
||||
|
||||
|
@ -72,6 +117,7 @@ public class ChuteBlock extends Block implements IWrenchable {
|
|||
public void onReplaced(BlockState state, World world, BlockPos pos, BlockState p_196243_4_, boolean p_196243_5_) {
|
||||
boolean differentBlock = state.getBlock() != p_196243_4_.getBlock();
|
||||
if (state.hasTileEntity() && (differentBlock || !p_196243_4_.hasTileEntity())) {
|
||||
withTileEntityDo(world, pos, c -> c.onRemoved(state));
|
||||
world.removeTileEntity(pos);
|
||||
}
|
||||
if (p_196243_5_ || !differentBlock)
|
||||
|
@ -175,4 +221,33 @@ public class ChuteBlock extends Block implements IWrenchable {
|
|||
super.fillStateContainer(p_206840_1_.add(SHAPE, FACING));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<ChuteTileEntity> getTileEntityClass() {
|
||||
return ChuteTileEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player, Hand hand,
|
||||
BlockRayTraceResult p_225533_6_) {
|
||||
if (!player.getHeldItem(hand)
|
||||
.isEmpty())
|
||||
return ActionResultType.PASS;
|
||||
if (world.isRemote)
|
||||
return ActionResultType.SUCCESS;
|
||||
try {
|
||||
ChuteTileEntity te = getTileEntity(world, pos);
|
||||
if (te == null)
|
||||
return ActionResultType.PASS;
|
||||
if (te.item.isEmpty())
|
||||
return ActionResultType.PASS;
|
||||
player.inventory.placeItemBackInInventory(world, te.item);
|
||||
te.setItem(ItemStack.EMPTY);
|
||||
return ActionResultType.SUCCESS;
|
||||
|
||||
} catch (TileEntityException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package com.simibubi.create.content.logistics.block.chute;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class ChuteItemHandler implements IItemHandler {
|
||||
|
||||
private ChuteTileEntity te;
|
||||
|
||||
public ChuteItemHandler(ChuteTileEntity te) {
|
||||
this.te = te;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlots() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int slot) {
|
||||
return te.item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
|
||||
if (!te.item.isEmpty())
|
||||
return stack;
|
||||
if (!simulate)
|
||||
te.setItem(stack);
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
ItemStack remainder = te.item.copy();
|
||||
ItemStack split = remainder.split(amount);
|
||||
if (!simulate)
|
||||
te.setItem(remainder);
|
||||
return split;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSlotLimit(int slot) {
|
||||
return Math.min(64, getStackInSlot(slot).getMaxStackSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.simibubi.create.content.logistics.block.chute;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.content.logistics.block.chute.ChuteBlock.Shape;
|
||||
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
|
||||
import com.simibubi.create.foundation.utility.MatrixStacker;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.ItemRenderer;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||
import net.minecraft.util.Direction;
|
||||
|
||||
public class ChuteRenderer extends SafeTileEntityRenderer<ChuteTileEntity> {
|
||||
|
||||
public ChuteRenderer(TileEntityRendererDispatcher dispatcher) {
|
||||
super(dispatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderSafe(ChuteTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||
int light, int overlay) {
|
||||
if (te.item.isEmpty())
|
||||
return;
|
||||
BlockState blockState = te.getBlockState();
|
||||
if (blockState.get(ChuteBlock.FACING) != Direction.DOWN)
|
||||
return;
|
||||
if (blockState.get(ChuteBlock.SHAPE) != Shape.WINDOW_STRAIGHT)
|
||||
return;
|
||||
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance()
|
||||
.getItemRenderer();
|
||||
MatrixStacker msr = MatrixStacker.of(ms);
|
||||
ms.push();
|
||||
msr.centre();
|
||||
float itemScale = .5f;
|
||||
float itemPosition = te.itemPosition.get(partialTicks);
|
||||
ms.translate(0, -.5 + itemPosition, 0);
|
||||
ms.scale(itemScale, itemScale, itemScale);
|
||||
msr.rotateX(itemPosition * 180);
|
||||
msr.rotateY(itemPosition * 180);
|
||||
itemRenderer.renderItem(te.item, TransformType.FIXED, light, overlay, ms, buffer);
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,465 @@
|
|||
package com.simibubi.create.content.logistics.block.chute;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.components.fan.EncasedFanBlock;
|
||||
import com.simibubi.create.content.contraptions.components.fan.EncasedFanTileEntity;
|
||||
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
|
||||
import com.simibubi.create.content.logistics.block.chute.ChuteBlock.Shape;
|
||||
import com.simibubi.create.content.logistics.block.realityFunnel.ChuteFunnelBlock;
|
||||
import com.simibubi.create.content.logistics.block.realityFunnel.RealityFunnelBlock;
|
||||
import com.simibubi.create.foundation.gui.widgets.InterpolatedValue;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.inventory.InventoryHelper;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.particles.ItemParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInformation {
|
||||
|
||||
float pull;
|
||||
float push;
|
||||
|
||||
ItemStack item;
|
||||
InterpolatedValue itemPosition;
|
||||
ChuteItemHandler itemHandler;
|
||||
LazyOptional<IItemHandler> lazyHandler;
|
||||
boolean canPickUpItems;
|
||||
|
||||
public ChuteTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||
super(tileEntityTypeIn);
|
||||
item = ItemStack.EMPTY;
|
||||
itemPosition = new InterpolatedValue();
|
||||
itemHandler = new ChuteItemHandler(this);
|
||||
lazyHandler = LazyOptional.of(() -> itemHandler);
|
||||
canPickUpItems = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen((d) -> canDirectlyInsertCached()));
|
||||
}
|
||||
|
||||
// Cached per-tick, useful when a lot of items are waiting on top of it
|
||||
public boolean canDirectlyInsertCached() {
|
||||
return canPickUpItems;
|
||||
}
|
||||
|
||||
private boolean canDirectlyInsert() {
|
||||
BlockState blockState = getBlockState();
|
||||
BlockState blockStateAbove = world.getBlockState(pos.up());
|
||||
if (!AllBlocks.CHUTE.has(blockState))
|
||||
return false;
|
||||
if (AllBlocks.CHUTE.has(blockStateAbove) && blockStateAbove.get(ChuteBlock.FACING) == Direction.DOWN)
|
||||
return false;
|
||||
if (getItemMotion() > 0 && getInputChutes().isEmpty())
|
||||
return false;
|
||||
return blockState.get(ChuteBlock.FACING) == Direction.DOWN || blockState.get(ChuteBlock.SHAPE) == Shape.START;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
canPickUpItems = canDirectlyInsert();
|
||||
if (item.isEmpty())
|
||||
return;
|
||||
float itemMotion = getItemMotion();
|
||||
float nextOffset = itemPosition.value + itemMotion;
|
||||
|
||||
if (itemMotion < 0) {
|
||||
if (nextOffset < .5f) {
|
||||
if (handleSideOutput())
|
||||
return;
|
||||
boolean success = handleDownwardOutput(true);
|
||||
if (!success)
|
||||
nextOffset = .5f;
|
||||
else if (nextOffset < 0) {
|
||||
handleDownwardOutput(world.isRemote);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itemMotion > 0) {
|
||||
if (nextOffset > .5f) {
|
||||
if (handleSideOutput())
|
||||
return;
|
||||
boolean success = handleUpwardOutput(true);
|
||||
if (!success)
|
||||
nextOffset = .5f;
|
||||
else if (nextOffset > 1) {
|
||||
handleUpwardOutput(world.isRemote);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
itemPosition.set(nextOffset);
|
||||
}
|
||||
|
||||
private boolean handleDownwardOutput(boolean simulate) {
|
||||
BlockState blockState = getBlockState();
|
||||
ChuteTileEntity targetChute = getTargetChute(blockState);
|
||||
|
||||
if (targetChute != null) {
|
||||
boolean canInsert = targetChute.item.isEmpty();
|
||||
if (!simulate && canInsert) {
|
||||
targetChute.setItem(item, 1);
|
||||
setItem(ItemStack.EMPTY);
|
||||
}
|
||||
return canInsert;
|
||||
}
|
||||
|
||||
// Diagonal chutes can only insert into other chutes
|
||||
if (blockState.get(ChuteBlock.FACING)
|
||||
.getAxis()
|
||||
.isHorizontal())
|
||||
return false;
|
||||
|
||||
BlockState stateBelow = world.getBlockState(pos.down());
|
||||
if (AllBlocks.REALITY_FUNNEL.has(stateBelow)) {
|
||||
if (stateBelow.get(RealityFunnelBlock.POWERED))
|
||||
return false;
|
||||
if (stateBelow.get(RealityFunnelBlock.FACING) != Direction.UP)
|
||||
return false;
|
||||
ItemStack remainder = RealityFunnelBlock.tryInsert(world, pos.down(), item, simulate);
|
||||
if (!simulate)
|
||||
setItem(remainder);
|
||||
return remainder.isEmpty();
|
||||
}
|
||||
|
||||
DirectBeltInputBehaviour directInput =
|
||||
TileEntityBehaviour.get(world, pos.down(), DirectBeltInputBehaviour.TYPE);
|
||||
if (directInput != null) {
|
||||
if (!directInput.canInsertFromSide(Direction.UP))
|
||||
return false;
|
||||
ItemStack remainder = directInput.handleInsertion(item, Direction.UP, simulate);
|
||||
if (!simulate)
|
||||
setItem(remainder);
|
||||
return remainder.isEmpty();
|
||||
}
|
||||
|
||||
if (Block.hasSolidSideOnTop(world, pos.down()))
|
||||
return false;
|
||||
|
||||
if (!simulate) {
|
||||
Vec3d dropVec = VecHelper.getCenterOf(pos)
|
||||
.add(0, -12 / 16f, 0);
|
||||
ItemEntity dropped = new ItemEntity(world, dropVec.x, dropVec.y, dropVec.z, item.copy());
|
||||
dropped.setDefaultPickupDelay();
|
||||
dropped.setMotion(0, -.25f, 0);
|
||||
world.addEntity(dropped);
|
||||
setItem(ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean handleUpwardOutput(boolean simulate) {
|
||||
BlockState stateAbove = world.getBlockState(pos.up());
|
||||
if (AllBlocks.REALITY_FUNNEL.has(stateAbove)) {
|
||||
if (!stateAbove.get(RealityFunnelBlock.POWERED)
|
||||
&& stateAbove.get(RealityFunnelBlock.FACING) == Direction.DOWN) {
|
||||
ItemStack remainder = RealityFunnelBlock.tryInsert(world, pos.up(), item, simulate);
|
||||
if (remainder.isEmpty()) {
|
||||
if (!simulate)
|
||||
setItem(remainder);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ChuteTileEntity bestOutput = null;
|
||||
List<ChuteTileEntity> inputChutes = getInputChutes();
|
||||
for (ChuteTileEntity targetChute : inputChutes) {
|
||||
if (!targetChute.item.isEmpty())
|
||||
continue;
|
||||
float itemMotion = targetChute.getItemMotion();
|
||||
if (itemMotion < 0)
|
||||
continue;
|
||||
if (bestOutput == null || bestOutput.getItemMotion() < itemMotion) {
|
||||
bestOutput = targetChute;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestOutput != null) {
|
||||
if (!simulate) {
|
||||
bestOutput.setItem(item, 0);
|
||||
setItem(ItemStack.EMPTY);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Block.hasSolidSide(stateAbove, world, pos.up(), Direction.DOWN))
|
||||
return false;
|
||||
if (!inputChutes.isEmpty())
|
||||
return false;
|
||||
|
||||
if (!simulate) {
|
||||
Vec3d dropVec = VecHelper.getCenterOf(pos)
|
||||
.add(0, 8 / 16f, 0);
|
||||
ItemEntity dropped = new ItemEntity(world, dropVec.x, dropVec.y, dropVec.z, item.copy());
|
||||
dropped.setDefaultPickupDelay();
|
||||
dropped.setMotion(0, getItemMotion() * 2, 0);
|
||||
world.addEntity(dropped);
|
||||
setItem(ItemStack.EMPTY);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean handleSideOutput() {
|
||||
if (world.isRemote)
|
||||
return false;
|
||||
for (Direction direction : Iterate.horizontalDirections) {
|
||||
BlockPos funnelPos = pos.offset(direction);
|
||||
BlockState funnelState = world.getBlockState(funnelPos);
|
||||
if (AllBlocks.CHUTE_FUNNEL.has(funnelState)) {
|
||||
if (funnelState.get(ChuteFunnelBlock.POWERED))
|
||||
continue;
|
||||
if (funnelState.get(ChuteFunnelBlock.HORIZONTAL_FACING) != direction.getOpposite())
|
||||
continue;
|
||||
if (funnelState.get(ChuteFunnelBlock.PUSHING))
|
||||
continue;
|
||||
ItemStack remainder = RealityFunnelBlock.tryInsert(world, funnelPos, item.copy(), world.isRemote);
|
||||
if (remainder.getCount() != item.getCount() && !world.isRemote)
|
||||
setItem(remainder);
|
||||
}
|
||||
}
|
||||
return item.isEmpty();
|
||||
}
|
||||
|
||||
public void setItem(ItemStack stack) {
|
||||
setItem(stack, getItemMotion() < 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
public void setItem(ItemStack stack, float insertionPos) {
|
||||
item = stack;
|
||||
itemPosition.lastValue = itemPosition.value = insertionPos;
|
||||
markDirty();
|
||||
sendData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
super.remove();
|
||||
if (lazyHandler != null)
|
||||
lazyHandler.invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound.put("Item", item.serializeNBT());
|
||||
compound.putFloat("ItemPosition", itemPosition.value);
|
||||
compound.putFloat("Pull", pull);
|
||||
compound.putFloat("Push", push);
|
||||
return super.write(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
ItemStack previousItem = item;
|
||||
item = ItemStack.read(compound.getCompound("Item"));
|
||||
itemPosition.lastValue = itemPosition.value = compound.getFloat("ItemPosition");
|
||||
pull = compound.getFloat("Pull");
|
||||
push = compound.getFloat("Push");
|
||||
super.read(compound);
|
||||
|
||||
if (hasWorld() && world.isRemote && !previousItem.equals(item, false) && !item.isEmpty()) {
|
||||
if (world.rand.nextInt(3) != 0)
|
||||
return;
|
||||
Vec3d p = VecHelper.getCenterOf(pos);
|
||||
p = VecHelper.offsetRandomly(p, world.rand, .5f);
|
||||
Vec3d m = Vec3d.ZERO;
|
||||
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, item), p.x, p.y, p.z, m.x, m.y, m.z);
|
||||
}
|
||||
}
|
||||
|
||||
public float getItemMotion() {
|
||||
// Chutes per second
|
||||
final float fanSpeedModifier = 1 / 64f;
|
||||
final float maxUpwardItemSpeed = 20f;
|
||||
final float gravity = 4f;
|
||||
|
||||
float upwardMotion = (push + pull) * fanSpeedModifier;
|
||||
return (upwardMotion == 0 ? -gravity : MathHelper.clamp(upwardMotion, 0, maxUpwardItemSpeed)) / 20f;
|
||||
}
|
||||
|
||||
public void onRemoved(BlockState chuteState) {
|
||||
ChuteTileEntity targetChute = getTargetChute(chuteState);
|
||||
List<ChuteTileEntity> inputChutes = getInputChutes();
|
||||
if (!item.isEmpty())
|
||||
InventoryHelper.spawnItemStack(world, pos.getX(), pos.getY(), pos.getZ(), item);
|
||||
super.remove();
|
||||
if (targetChute != null) {
|
||||
targetChute.updatePull();
|
||||
targetChute.propagatePush();
|
||||
}
|
||||
inputChutes.forEach(c -> c.updatePush(inputChutes.size()));
|
||||
}
|
||||
|
||||
public void onAdded() {
|
||||
updateContainingBlockInfo();
|
||||
updatePull();
|
||||
ChuteTileEntity targetChute = getTargetChute(getBlockState());
|
||||
if (targetChute != null)
|
||||
targetChute.propagatePush();
|
||||
else
|
||||
updatePush(1);
|
||||
}
|
||||
|
||||
public void updatePull() {
|
||||
float totalPull = calculatePull();
|
||||
if (pull == totalPull)
|
||||
return;
|
||||
pull = totalPull;
|
||||
sendData();
|
||||
ChuteTileEntity targetChute = getTargetChute(getBlockState());
|
||||
if (targetChute != null)
|
||||
targetChute.updatePull();
|
||||
}
|
||||
|
||||
public void updatePush(int branchCount) {
|
||||
float totalPush = calculatePush(branchCount);
|
||||
if (push == totalPush)
|
||||
return;
|
||||
push = totalPush;
|
||||
sendData();
|
||||
propagatePush();
|
||||
}
|
||||
|
||||
public void propagatePush() {
|
||||
List<ChuteTileEntity> inputs = getInputChutes();
|
||||
inputs.forEach(c -> c.updatePush(inputs.size()));
|
||||
}
|
||||
|
||||
protected float calculatePull() {
|
||||
BlockState blockStateAbove = world.getBlockState(pos.up());
|
||||
if (AllBlocks.ENCASED_FAN.has(blockStateAbove)
|
||||
&& blockStateAbove.get(EncasedFanBlock.FACING) == Direction.DOWN) {
|
||||
TileEntity te = world.getTileEntity(pos.up());
|
||||
if (te instanceof EncasedFanTileEntity && !te.isRemoved()) {
|
||||
EncasedFanTileEntity fan = (EncasedFanTileEntity) te;
|
||||
return Math.abs(fan.getSpeed());
|
||||
}
|
||||
}
|
||||
|
||||
float totalPull = 0;
|
||||
for (Direction d : Iterate.directions) {
|
||||
ChuteTileEntity inputChute = getInputChute(d);
|
||||
if (inputChute == null)
|
||||
continue;
|
||||
totalPull += inputChute.pull;
|
||||
}
|
||||
return totalPull;
|
||||
}
|
||||
|
||||
protected float calculatePush(int branchCount) {
|
||||
BlockState blockStateBelow = world.getBlockState(pos.down());
|
||||
if (AllBlocks.ENCASED_FAN.has(blockStateBelow) && blockStateBelow.get(EncasedFanBlock.FACING) == Direction.UP) {
|
||||
TileEntity te = world.getTileEntity(pos.down());
|
||||
if (te instanceof EncasedFanTileEntity && !te.isRemoved()) {
|
||||
EncasedFanTileEntity fan = (EncasedFanTileEntity) te;
|
||||
return Math.abs(fan.getSpeed());
|
||||
}
|
||||
}
|
||||
|
||||
ChuteTileEntity targetChute = getTargetChute(getBlockState());
|
||||
if (targetChute == null)
|
||||
return 0;
|
||||
return targetChute.push / branchCount;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ChuteTileEntity getTargetChute(BlockState state) {
|
||||
Direction targetDirection = state.get(ChuteBlock.FACING);
|
||||
BlockPos chutePos = pos.down();
|
||||
if (targetDirection.getAxis()
|
||||
.isHorizontal())
|
||||
chutePos = chutePos.offset(targetDirection.getOpposite());
|
||||
BlockState chuteState = world.getBlockState(chutePos);
|
||||
if (!AllBlocks.CHUTE.has(chuteState))
|
||||
return null;
|
||||
TileEntity te = world.getTileEntity(chutePos);
|
||||
if (te instanceof ChuteTileEntity)
|
||||
return (ChuteTileEntity) te;
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<ChuteTileEntity> getInputChutes() {
|
||||
List<ChuteTileEntity> inputs = new LinkedList<>();
|
||||
for (Direction d : Iterate.directions) {
|
||||
ChuteTileEntity inputChute = getInputChute(d);
|
||||
if (inputChute == null)
|
||||
continue;
|
||||
inputs.add(inputChute);
|
||||
}
|
||||
return inputs;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ChuteTileEntity getInputChute(Direction direction) {
|
||||
if (direction == Direction.DOWN)
|
||||
return null;
|
||||
direction = direction.getOpposite();
|
||||
BlockPos chutePos = pos.up();
|
||||
if (direction.getAxis()
|
||||
.isHorizontal())
|
||||
chutePos = chutePos.offset(direction);
|
||||
BlockState chuteState = world.getBlockState(chutePos);
|
||||
if (!AllBlocks.CHUTE.has(chuteState) || chuteState.get(ChuteBlock.FACING) != direction)
|
||||
return null;
|
||||
TileEntity te = world.getTileEntity(chutePos);
|
||||
if (te instanceof ChuteTileEntity && !te.isRemoved())
|
||||
return (ChuteTileEntity) te;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addToGoggleTooltip(List<String> tooltip, boolean isPlayerSneaking) {
|
||||
tooltip.add(spacing + TextFormatting.GOLD + "Pull: " + TextFormatting.WHITE + pull);
|
||||
tooltip.add(spacing + TextFormatting.GOLD + "Push: " + TextFormatting.WHITE + push);
|
||||
tooltip.add(TextFormatting.YELLOW + "-> Item Motion: " + TextFormatting.WHITE + getItemMotion());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
||||
if (cap == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
|
||||
return lazyHandler.cast();
|
||||
return super.getCapability(cap, side);
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
}
|
|
@ -64,8 +64,9 @@ public class DepotBlock extends Block implements ITE<DepotTileEntity> {
|
|||
return ActionResultType.SUCCESS;
|
||||
|
||||
withTileEntityDo(world, pos, te -> {
|
||||
boolean wasEmptyHanded = player.getHeldItem(hand)
|
||||
.isEmpty();
|
||||
ItemStack heldItem = player.getHeldItem(hand);
|
||||
boolean wasEmptyHanded = heldItem.isEmpty();
|
||||
boolean shouldntPlaceItem = AllBlocks.MECHANICAL_ARM.isIn(heldItem);
|
||||
|
||||
ItemStack mainItemStack = te.getHeldItemStack();
|
||||
if (!mainItemStack.isEmpty()) {
|
||||
|
@ -76,12 +77,12 @@ public class DepotBlock extends Block implements ITE<DepotTileEntity> {
|
|||
for (int i = 0; i < outputs.getSlots(); i++)
|
||||
player.inventory.placeItemBackInInventory(world, outputs.extractItem(i, 64, false));
|
||||
|
||||
if (!wasEmptyHanded) {
|
||||
TransportedItemStack heldItem = new TransportedItemStack(player.getHeldItem(hand));
|
||||
heldItem.insertedFrom = player.getHorizontalFacing();
|
||||
heldItem.prevBeltPosition = .25f;
|
||||
heldItem.beltPosition = .25f;
|
||||
te.setHeldItem(heldItem);
|
||||
if (!wasEmptyHanded && !shouldntPlaceItem) {
|
||||
TransportedItemStack transported = new TransportedItemStack(heldItem);
|
||||
transported.insertedFrom = player.getHorizontalFacing();
|
||||
transported.prevBeltPosition = .25f;
|
||||
transported.beltPosition = .25f;
|
||||
te.setHeldItem(transported);
|
||||
player.setHeldItem(hand, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,16 +3,24 @@ package com.simibubi.create.content.logistics.block.mechanicalArm;
|
|||
import com.simibubi.create.AllShapes;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.content.contraptions.base.KineticBlock;
|
||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.InventoryHelper;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class ArmBlock extends KineticBlock implements ITE<ArmTileEntity> {
|
||||
|
||||
|
@ -24,13 +32,13 @@ public class ArmBlock extends KineticBlock implements ITE<ArmTileEntity> {
|
|||
public boolean hasIntegratedCogwheel(IWorldReader world, BlockPos pos, BlockState state) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState p_220053_1_, IBlockReader p_220053_2_, BlockPos p_220053_3_,
|
||||
ISelectionContext p_220053_4_) {
|
||||
return AllShapes.MECHANICAL_ARM;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Axis getRotationAxis(BlockState state) {
|
||||
return Axis.Y;
|
||||
|
@ -46,4 +54,34 @@ public class ArmBlock extends KineticBlock implements ITE<ArmTileEntity> {
|
|||
return ArmTileEntity.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReplaced(BlockState p_196243_1_, World world, BlockPos pos, BlockState p_196243_4_,
|
||||
boolean p_196243_5_) {
|
||||
if (p_196243_1_.hasTileEntity()
|
||||
&& (p_196243_1_.getBlock() != p_196243_4_.getBlock() || !p_196243_4_.hasTileEntity())) {
|
||||
withTileEntityDo(world, pos, te -> {
|
||||
if (!te.heldItem.isEmpty())
|
||||
InventoryHelper.spawnItemStack(world, pos.getX(), pos.getY(), pos.getZ(), te.heldItem);
|
||||
});
|
||||
world.removeTileEntity(pos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType onUse(BlockState p_225533_1_, World world, BlockPos pos, PlayerEntity player,
|
||||
Hand p_225533_5_, BlockRayTraceResult p_225533_6_) {
|
||||
if (world.isRemote)
|
||||
return ActionResultType.SUCCESS;
|
||||
withTileEntityDo(world, pos, te -> {
|
||||
if (te.heldItem.isEmpty())
|
||||
return;
|
||||
player.inventory.placeItemBackInInventory(world, te.heldItem);
|
||||
te.heldItem = ItemStack.EMPTY;
|
||||
te.phase = Phase.SEARCH_INPUTS;
|
||||
te.markDirty();
|
||||
te.sendData();
|
||||
});
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -147,6 +147,8 @@ public abstract class ArmInteractionPoint {
|
|||
static ArmInteractionPoint deserialize(IBlockReader world, CompoundNBT nbt) {
|
||||
BlockPos pos = NBTUtil.readBlockPos(nbt.getCompound("Pos"));
|
||||
ArmInteractionPoint interactionPoint = createAt(world, pos);
|
||||
if (interactionPoint == null)
|
||||
return null;
|
||||
interactionPoint.mode = NBTHelper.readEnum(nbt, "Mode", Mode.class);
|
||||
return interactionPoint;
|
||||
}
|
||||
|
|
|
@ -172,9 +172,11 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||
|
||||
protected void depositItem() {
|
||||
ArmInteractionPoint armInteractionPoint = getTargetedInteractionPoint();
|
||||
ItemStack toInsert = heldItem.copy();
|
||||
ItemStack remainder = armInteractionPoint.insert(world, toInsert, false);
|
||||
heldItem = remainder;
|
||||
if (armInteractionPoint != null) {
|
||||
ItemStack toInsert = heldItem.copy();
|
||||
ItemStack remainder = armInteractionPoint.insert(world, toInsert, false);
|
||||
heldItem = remainder;
|
||||
}
|
||||
phase = heldItem.isEmpty() ? Phase.SEARCH_INPUTS : Phase.SEARCH_OUTPUTS;
|
||||
chasedPointProgress = 0;
|
||||
chasedPointIndex = -1;
|
||||
|
@ -184,19 +186,20 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||
|
||||
protected void collectItem() {
|
||||
ArmInteractionPoint armInteractionPoint = getTargetedInteractionPoint();
|
||||
for (int i = 0; i < armInteractionPoint.getSlotCount(world); i++) {
|
||||
int amountExtracted = getDistributableAmount(armInteractionPoint, i);
|
||||
if (amountExtracted == 0)
|
||||
continue;
|
||||
|
||||
heldItem = armInteractionPoint.extract(world, i, amountExtracted, false);
|
||||
phase = Phase.SEARCH_OUTPUTS;
|
||||
chasedPointProgress = 0;
|
||||
chasedPointIndex = -1;
|
||||
sendData();
|
||||
markDirty();
|
||||
return;
|
||||
}
|
||||
if (armInteractionPoint != null)
|
||||
for (int i = 0; i < armInteractionPoint.getSlotCount(world); i++) {
|
||||
int amountExtracted = getDistributableAmount(armInteractionPoint, i);
|
||||
if (amountExtracted == 0)
|
||||
continue;
|
||||
|
||||
heldItem = armInteractionPoint.extract(world, i, amountExtracted, false);
|
||||
phase = Phase.SEARCH_OUTPUTS;
|
||||
chasedPointProgress = 0;
|
||||
chasedPointIndex = -1;
|
||||
sendData();
|
||||
markDirty();
|
||||
return;
|
||||
}
|
||||
|
||||
phase = Phase.SEARCH_INPUTS;
|
||||
chasedPointProgress = 0;
|
||||
|
@ -221,6 +224,8 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||
outputs.clear();
|
||||
for (INBT inbt : interactionPointTag) {
|
||||
ArmInteractionPoint point = ArmInteractionPoint.deserialize(world, (CompoundNBT) inbt);
|
||||
if (point == null)
|
||||
continue;
|
||||
if (point.mode == Mode.DEPOSIT)
|
||||
outputs.add(point);
|
||||
if (point.mode == Mode.TAKE)
|
||||
|
|
|
@ -76,21 +76,26 @@ public class RealityFunnelBlock extends ProperDirectionalBlock implements ITE<Re
|
|||
if (projectedDiff < 0 == (direction.getAxisDirection() == AxisDirection.POSITIVE))
|
||||
return;
|
||||
|
||||
FilteringBehaviour filter = TileEntityBehaviour.get(worldIn, pos, FilteringBehaviour.TYPE);
|
||||
InsertingBehaviour inserter = TileEntityBehaviour.get(worldIn, pos, InsertingBehaviour.TYPE);
|
||||
if (inserter == null)
|
||||
return;
|
||||
ItemStack toInsert = itemEntity.getItem();
|
||||
if (filter != null && !filter.test(toInsert))
|
||||
return;
|
||||
|
||||
ItemStack remainder = inserter.insert(toInsert, false);
|
||||
ItemStack remainder = tryInsert(worldIn, pos, toInsert, false);
|
||||
|
||||
if (remainder.isEmpty())
|
||||
itemEntity.remove();
|
||||
if (remainder.getCount() < toInsert.getCount())
|
||||
itemEntity.setItem(remainder);
|
||||
}
|
||||
|
||||
public static ItemStack tryInsert(World worldIn, BlockPos pos, ItemStack toInsert, boolean simulate) {
|
||||
FilteringBehaviour filter = TileEntityBehaviour.get(worldIn, pos, FilteringBehaviour.TYPE);
|
||||
InsertingBehaviour inserter = TileEntityBehaviour.get(worldIn, pos, InsertingBehaviour.TYPE);
|
||||
if (inserter == null)
|
||||
return toInsert;
|
||||
if (filter != null && !filter.test(toInsert))
|
||||
return toInsert;
|
||||
ItemStack remainder = inserter.insert(toInsert, simulate);
|
||||
return remainder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(BlockState state) {
|
||||
return true;
|
||||
|
|
|
@ -8,6 +8,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||
import com.simibubi.create.content.logistics.block.chute.ChuteTileEntity;
|
||||
import com.simibubi.create.content.logistics.block.realityFunnel.BeltFunnelBlock.Shape;
|
||||
import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
|
@ -23,6 +24,7 @@ import net.minecraft.block.BlockState;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -72,6 +74,41 @@ public class RealityFunnelTileEntity extends SmartTileEntity {
|
|||
Mode mode = determineCurrentMode();
|
||||
if (mode == Mode.BELT)
|
||||
tickAsBeltFunnel();
|
||||
if (world.isRemote)
|
||||
return;
|
||||
if (mode == Mode.CHUTE_SIDE)
|
||||
tickAsHorizontalChuteFunnel();
|
||||
if (mode == Mode.CHUTE_END)
|
||||
tickAsVerticalChuteFunnel();
|
||||
}
|
||||
|
||||
public void tickAsHorizontalChuteFunnel() {
|
||||
if (!getBlockState().get(ChuteFunnelBlock.PUSHING))
|
||||
return;
|
||||
BlockPos chutePos = pos.offset(RealityFunnelBlock.getFunnelFacing(getBlockState()));
|
||||
TileEntity te = world.getTileEntity(chutePos);
|
||||
if (!(te instanceof ChuteTileEntity))
|
||||
return;
|
||||
ChuteTileEntity chute = (ChuteTileEntity) te;
|
||||
extracting.setCallback(stack -> chute.setItem(stack, .5f));
|
||||
extracting.withAdditionalFilter(stack -> chute.getItem()
|
||||
.isEmpty());
|
||||
extracting.extract();
|
||||
}
|
||||
|
||||
public void tickAsVerticalChuteFunnel() {
|
||||
Direction funnelFacing = RealityFunnelBlock.getFunnelFacing(getBlockState());
|
||||
BlockPos chutePos = pos.offset(funnelFacing);
|
||||
TileEntity te = world.getTileEntity(chutePos);
|
||||
if (!(te instanceof ChuteTileEntity))
|
||||
return;
|
||||
ChuteTileEntity chute = (ChuteTileEntity) te;
|
||||
if (chute.getItemMotion() > 0 != (funnelFacing == Direction.UP))
|
||||
return;
|
||||
extracting.setCallback(stack -> chute.setItem(stack));
|
||||
extracting.withAdditionalFilter(stack -> chute.getItem()
|
||||
.isEmpty());
|
||||
extracting.extract();
|
||||
}
|
||||
|
||||
public void tickAsBeltFunnel() {
|
||||
|
@ -138,7 +175,7 @@ public class RealityFunnelTileEntity extends SmartTileEntity {
|
|||
filtering = new FilteringBehaviour(this, new FunnelFilterSlotPositioning()).showCountWhen(() -> {
|
||||
BlockState blockState = getBlockState();
|
||||
return blockState.getBlock() instanceof HorizontalInteractionFunnelBlock
|
||||
&& blockState.get(HorizontalInteractionFunnelBlock.PUSHING);
|
||||
&& blockState.get(HorizontalInteractionFunnelBlock.PUSHING) || determineCurrentMode() == Mode.CHUTE_END;
|
||||
});
|
||||
|
||||
behaviours.add(filtering);
|
||||
|
|
|
@ -97,6 +97,14 @@
|
|||
"south": {"uv": [9.5, 4, 14.5, 8], "texture": "#13"},
|
||||
"down": {"uv": [9.5, 7.5, 14.5, 8], "texture": "#13"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [3, 13, 3],
|
||||
"to": [13, 14, 13],
|
||||
"faces": {
|
||||
"up": {"uv": [9.5, 9.5, 14.5, 14.5], "texture": "#13"},
|
||||
"down": {"uv": [9.5, 9.5, 14.5, 14.5], "texture": "#13"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"groups": [
|
||||
|
@ -109,6 +117,5 @@
|
|||
"name": "ChuteBase",
|
||||
"origin": [8, 8, -7],
|
||||
"children": [4, 5, 6, 7]
|
||||
}
|
||||
]
|
||||
}, 8]
|
||||
}
|
|
@ -37,7 +37,7 @@
|
|||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 10, 11, 16], "rotation": 270, "texture": "#2"},
|
||||
"east": {"uv": [13, 0, 16, 11], "texture": "#2"},
|
||||
"east": {"uv": [13, 11, 16, 0], "texture": "#2"},
|
||||
"south": {"uv": [0, 10, 11, 16], "rotation": 270, "texture": "#2"},
|
||||
"west": {"uv": [13, 0, 16, 11], "rotation": 180, "texture": "#2"},
|
||||
"up": {"uv": [5, 10, 11, 13], "rotation": 180, "texture": "#2"}
|
||||
|
|
|
@ -68,8 +68,8 @@
|
|||
"to": [14.1, 10.666, 14.1],
|
||||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"},
|
||||
"east": {"uv": [13, 0, 16, 11], "texture": "#2"},
|
||||
"north": {"uv": [0, 10, 11, 16], "rotation": 270, "texture": "#2"},
|
||||
"east": {"uv": [13, 11, 16, 0], "texture": "#2"},
|
||||
"south": {"uv": [0, 10, 11, 16], "rotation": 270, "texture": "#2"},
|
||||
"west": {"uv": [13, 0, 16, 11], "rotation": 180, "texture": "#2"},
|
||||
"up": {"uv": [5, 10, 11, 13], "rotation": 180, "texture": "#2"}
|
||||
|
@ -81,7 +81,7 @@
|
|||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [1, 3, 11, 10], "rotation": 90, "texture": "#2"},
|
||||
"east": {"uv": [1, 0, 11, 3], "rotation": 270, "texture": "#2"},
|
||||
"east": {"uv": [0, 0, 10, 3], "rotation": 270, "texture": "#2"},
|
||||
"south": {"uv": [1, 3, 11, 10], "rotation": 90, "texture": "#2"},
|
||||
"west": {"uv": [1, 0, 11, 3], "rotation": 90, "texture": "#2"}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@
|
|||
"from": [3, 13, 3],
|
||||
"to": [13, 14, 13],
|
||||
"faces": {
|
||||
"up": {"uv": [11, 11, 16, 16], "rotation": 180, "texture": "#2"}
|
||||
"up": {"uv": [9.5, 9.5, 14.5, 14.5], "rotation": 180, "texture": "#13"}
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"rotation": {"angle": 45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"},
|
||||
"east": {"uv": [13, 0, 16, 11], "texture": "#2"},
|
||||
"east": {"uv": [13, 11, 16, 0], "texture": "#2"},
|
||||
"south": {"uv": [0, 10, 11, 16], "rotation": 270, "texture": "#2"},
|
||||
"west": {"uv": [13, 0, 16, 11], "rotation": 180, "texture": "#2"}
|
||||
}
|
||||
|
|
|
@ -237,8 +237,53 @@
|
|||
"south": {"uv": [0, 7, 6, 9.5], "texture": "#13"},
|
||||
"west": {"uv": [0, 7, 6, 9.5], "texture": "#13"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [3, 13, 3],
|
||||
"to": [13, 14, 13],
|
||||
"faces": {
|
||||
"up": {"uv": [9.5, 9.5, 14.5, 14.5], "texture": "#13"},
|
||||
"down": {"uv": [9.5, 9.5, 14.5, 14.5], "texture": "#13"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"thirdperson_lefthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"rotation": [0, 45, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"firstperson_lefthand": {
|
||||
"rotation": [0, 225, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"ground": {
|
||||
"translation": [0, 3.25, 0],
|
||||
"scale": [0.25, 0.25, 0.25]
|
||||
},
|
||||
"gui": {
|
||||
"rotation": [30, 225, 0],
|
||||
"translation": [0, 1, 0],
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
},
|
||||
"head": {
|
||||
"rotation": [0, 90, 0]
|
||||
},
|
||||
"fixed": {
|
||||
"rotation": [0, 90, 0],
|
||||
"translation": [0, 1.5, 0],
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
}
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"name": "ChuteTop",
|
||||
|
@ -254,6 +299,5 @@
|
|||
"name": "windows",
|
||||
"origin": [8, 8, 8],
|
||||
"children": [16, 17, 18, 19]
|
||||
}
|
||||
]
|
||||
}, 20]
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"13": "create:block/chute",
|
||||
"particle": "create:block/brass_block"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [3, 8, 1],
|
||||
"to": [13, 16, 3],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [11, 16, -3]},
|
||||
"faces": {
|
||||
"north": {"uv": [9.5, 0, 14.5, 4], "texture": "#13"},
|
||||
"south": {"uv": [9.5, 0, 14.5, 4], "texture": "#13"},
|
||||
"up": {"uv": [1, 0, 6, 1], "texture": "#13"},
|
||||
"down": {"uv": [1, 6, 6, 7], "texture": "#13"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [3, 8, 13],
|
||||
"to": [13, 16, 15],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [5, 16, 19]},
|
||||
"faces": {
|
||||
"north": {"uv": [9.5, 0, 14.5, 4], "texture": "#13"},
|
||||
"south": {"uv": [9.5, 0, 14.5, 4], "texture": "#13"},
|
||||
"up": {"uv": [1, 0, 6, 1], "rotation": 180, "texture": "#13"},
|
||||
"down": {"uv": [1, 6, 6, 7], "rotation": 180, "texture": "#13"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1, 8, 1],
|
||||
"to": [3, 16, 15],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [9, 16, 9]},
|
||||
"faces": {
|
||||
"north": {"uv": [14.5, 0, 15.5, 4], "texture": "#13"},
|
||||
"east": {"uv": [8.5, 0, 15.5, 4], "texture": "#13"},
|
||||
"south": {"uv": [8.5, 0, 9.5, 4], "texture": "#13"},
|
||||
"west": {"uv": [8.5, 0, 15.5, 4], "texture": "#13"},
|
||||
"up": {"uv": [0, 0, 1, 7], "texture": "#13"},
|
||||
"down": {"uv": [0, 0, 1, 7], "texture": "#13"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [13, 8, 1],
|
||||
"to": [15, 16, 15],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [7, 16, 7]},
|
||||
"faces": {
|
||||
"north": {"uv": [8.5, 0, 9.5, 4], "texture": "#13"},
|
||||
"east": {"uv": [8.5, 0, 15.5, 4], "texture": "#13"},
|
||||
"south": {"uv": [14.5, 0, 15.5, 4], "texture": "#13"},
|
||||
"west": {"uv": [8.5, 0, 15.5, 4], "texture": "#13"},
|
||||
"up": {"uv": [0, 0, 1, 7], "rotation": 180, "texture": "#13"},
|
||||
"down": {"uv": [0, 0, 1, 7], "rotation": 180, "texture": "#13"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [2, 5.7, 2],
|
||||
"to": [14, 8.7, 14],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -24, 56]},
|
||||
"faces": {
|
||||
"north": {"uv": [7.5, 10, 9, 16], "rotation": 90, "texture": "#13"},
|
||||
"east": {"uv": [7.5, 10, 9, 16], "rotation": 90, "texture": "#13"},
|
||||
"south": {"uv": [9, 10.5, 15, 14.5], "rotation": 180, "texture": "#13"},
|
||||
"west": {"uv": [9, 11, 15, 15], "rotation": 180, "texture": "#13"},
|
||||
"up": {"uv": [9, 9.5, 15, 15.5], "rotation": 180, "texture": "#13"},
|
||||
"down": {"uv": [9, 11, 15, 15], "rotation": 180, "texture": "#13"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [2.1, 4, 2.1],
|
||||
"to": [13.9, 10.666, 13.9],
|
||||
"rotation": {"angle": -45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"},
|
||||
"east": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"},
|
||||
"west": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1.9, -12, 1.9],
|
||||
"to": [14.1, 4, 14.1],
|
||||
"rotation": {"angle": -45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [9, 8, 15, 16], "texture": "#13"},
|
||||
"east": {"uv": [9, 8, 15, 16], "texture": "#13"},
|
||||
"south": {"uv": [9, 8, 15, 16], "texture": "#13"},
|
||||
"west": {"uv": [9, 8, 15, 16], "texture": "#13"},
|
||||
"up": {"uv": [9, 9, 15, 15], "texture": "#13"},
|
||||
"down": {"uv": [9, 9, 15, 15], "texture": "#13"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"thirdperson_lefthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"rotation": [0, 45, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"firstperson_lefthand": {
|
||||
"rotation": [0, 225, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"ground": {
|
||||
"translation": [0, 3.25, 0],
|
||||
"scale": [0.25, 0.25, 0.25]
|
||||
},
|
||||
"gui": {
|
||||
"rotation": [30, 225, 0],
|
||||
"translation": [0, 1, 0],
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
},
|
||||
"head": {
|
||||
"rotation": [0, 90, 0]
|
||||
},
|
||||
"fixed": {
|
||||
"rotation": [0, 90, 0],
|
||||
"translation": [0, 1.5, 0],
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
}
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"name": "group",
|
||||
"origin": [8, 56, -56],
|
||||
"children": [0, 1, 2, 3, 4, 5, 6]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"13": "create:block/chute",
|
||||
"particle": "create:block/brass_block"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [1.9, 4, 1.9],
|
||||
"to": [14.1, 10.666, 14.1],
|
||||
"rotation": {"angle": -45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"},
|
||||
"east": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"},
|
||||
"south": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"},
|
||||
"west": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1.9, -12, 1.9],
|
||||
"to": [14.1, 4, 14.1],
|
||||
"rotation": {"angle": -45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [9, 8, 15, 16], "texture": "#13"},
|
||||
"east": {"uv": [9, 8, 15, 16], "texture": "#13"},
|
||||
"south": {"uv": [9, 8, 15, 16], "texture": "#13"},
|
||||
"west": {"uv": [9, 8, 15, 16], "texture": "#13"},
|
||||
"down": {"uv": [9, 8, 15, 16], "texture": "#13"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"thirdperson_lefthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"rotation": [0, 45, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"firstperson_lefthand": {
|
||||
"rotation": [0, 225, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"ground": {
|
||||
"translation": [0, 3.25, 0],
|
||||
"scale": [0.25, 0.25, 0.25]
|
||||
},
|
||||
"gui": {
|
||||
"rotation": [30, 225, 0],
|
||||
"translation": [0, 1, 0],
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
},
|
||||
"head": {
|
||||
"rotation": [0, 90, 0]
|
||||
},
|
||||
"fixed": {
|
||||
"rotation": [0, 90, 0],
|
||||
"translation": [0, 1.5, 0],
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
}
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"name": "group",
|
||||
"origin": [8, 8, -8],
|
||||
"children": [0, 1]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
{
|
||||
"credit": "Made with Blockbench",
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"13": "create:block/chute",
|
||||
"particle": "create:block/brass_block"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [2, 8, 2],
|
||||
"to": [14, 16, 14],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 40]},
|
||||
"faces": {
|
||||
"north": {"uv": [9, 11, 15, 15], "rotation": 180, "texture": "#13"},
|
||||
"east": {"uv": [9, 10.5, 15, 14.5], "rotation": 180, "texture": "#13"},
|
||||
"south": {"uv": [9, 10.5, 15, 14.5], "rotation": 180, "texture": "#13"},
|
||||
"west": {"uv": [9, 11, 15, 15], "rotation": 180, "texture": "#13"},
|
||||
"up": {"uv": [9, 9, 15, 15], "rotation": 180, "texture": "#13"},
|
||||
"down": {"uv": [9, 11, 15, 15], "rotation": 180, "texture": "#13"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1.9, 4, 1.9],
|
||||
"to": [14.1, 10.666, 14.1],
|
||||
"rotation": {"angle": -45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"},
|
||||
"east": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"},
|
||||
"south": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"},
|
||||
"west": {"uv": [6, 10, 9, 16], "rotation": 90, "texture": "#13"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1.9, -12, 1.9],
|
||||
"to": [14.1, 4, 14.1],
|
||||
"rotation": {"angle": -45, "axis": "x", "origin": [8, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [9, 8, 15, 16], "texture": "#13"},
|
||||
"east": {"uv": [9, 8, 15, 16], "texture": "#13"},
|
||||
"south": {"uv": [9, 8, 15, 16], "texture": "#13"},
|
||||
"west": {"uv": [9, 8, 15, 16], "texture": "#13"},
|
||||
"down": {"uv": [9, 9, 15, 15], "texture": "#13"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"thirdperson_lefthand": {
|
||||
"rotation": [75, 45, 0],
|
||||
"translation": [0, 2.5, 0],
|
||||
"scale": [0.375, 0.375, 0.375]
|
||||
},
|
||||
"firstperson_righthand": {
|
||||
"rotation": [0, 45, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"firstperson_lefthand": {
|
||||
"rotation": [0, 225, 0],
|
||||
"scale": [0.4, 0.4, 0.4]
|
||||
},
|
||||
"ground": {
|
||||
"translation": [0, 3.25, 0],
|
||||
"scale": [0.25, 0.25, 0.25]
|
||||
},
|
||||
"gui": {
|
||||
"rotation": [30, 225, 0],
|
||||
"translation": [0, 1, 0],
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
},
|
||||
"head": {
|
||||
"rotation": [0, 90, 0]
|
||||
},
|
||||
"fixed": {
|
||||
"rotation": [0, 90, 0],
|
||||
"translation": [0, 1.5, 0],
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
}
|
||||
},
|
||||
"groups": [
|
||||
{
|
||||
"name": "group",
|
||||
"origin": [8, 24, -24],
|
||||
"children": [0, 1, 2]
|
||||
}
|
||||
]
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -5,8 +5,8 @@
|
|||
"3": "create:block/belt_funnel_push_off",
|
||||
"4": "create:block/funnel_plating",
|
||||
"13": "create:block/chute",
|
||||
"3_particle": "create:block/brass_block",
|
||||
"particle": "create:block/brass_block",
|
||||
"3_particle": "create:block/brass_block",
|
||||
"1_2": "create:block/funnel_back"
|
||||
},
|
||||
"elements": [
|
||||
|
@ -138,8 +138,8 @@
|
|||
},
|
||||
{
|
||||
"name": "Back",
|
||||
"from": [1.1, 1.1, -2.9],
|
||||
"to": [14.9, 14.9, 2.1],
|
||||
"from": [1.1, 1.1, -3.1],
|
||||
"to": [14.9, 14.9, 2],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 6]},
|
||||
"faces": {
|
||||
"north": {"uv": [8.5, 8.5, 15.5, 15.5], "texture": "#13"},
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
Loading…
Reference in a new issue