mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-23 21:46:40 +01:00
Filterable Funnels
- Belt funnels can now be assigned filters for better item routing - Fixed items facing the wrong way if moving on a slope in negative directions - Items can now be picked up from belts by right clicking
This commit is contained in:
parent
0bded65338
commit
e742149c8d
8 changed files with 154 additions and 11 deletions
|
@ -44,6 +44,7 @@ import com.simibubi.create.modules.logistics.block.LinkedTileEntityRenderer;
|
|||
import com.simibubi.create.modules.logistics.block.RedstoneBridgeTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.StockswitchTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.belts.BeltFunnelTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.belts.BeltFunnelTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.belts.EntityDetectorTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.belts.EntityDetectorTileEntityRenderer;
|
||||
import com.simibubi.create.modules.logistics.block.belts.ExtractorTileEntity;
|
||||
|
@ -180,6 +181,7 @@ public enum AllTileEntities {
|
|||
bind(RedstoneBridgeTileEntity.class, new LinkedTileEntityRenderer());
|
||||
bind(LinkedExtractorTileEntity.class, new LinkedExtractorTileEntityRenderer());
|
||||
bind(ExtractorTileEntity.class, new ExtractorTileEntityRenderer());
|
||||
bind(BeltFunnelTileEntity.class, new BeltFunnelTileEntityRenderer());
|
||||
bind(EntityDetectorTileEntity.class, new EntityDetectorTileEntityRenderer());
|
||||
bind(MechanicalPressTileEntity.class, new MechanicalPressTileEntityRenderer());
|
||||
bind(FlexpeaterTileEntity.class, new FlexpeaterTileEntityRenderer());
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.modules.contraptions.relays.belt;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -114,6 +115,8 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
BeltTileEntity belt = null;
|
||||
belt = (BeltTileEntity) worldIn.getTileEntity(pos);
|
||||
|
||||
if (state.get(SLOPE) == Slope.VERTICAL)
|
||||
return;
|
||||
if (entityIn instanceof PlayerEntity && entityIn.isSneaking())
|
||||
return;
|
||||
if (belt == null || belt.getSpeed() == 0)
|
||||
|
@ -162,6 +165,7 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
boolean isShaft = heldItem.getItem() == AllBlocks.SHAFT.get().asItem();
|
||||
boolean isCasing = heldItem.getItem() == AllBlocks.LOGISTICAL_CASING.get().asItem();
|
||||
boolean isDye = Tags.Items.DYES.contains(heldItem.getItem());
|
||||
boolean isHand = heldItem.isEmpty() && handIn == Hand.MAIN_HAND;
|
||||
|
||||
if (isDye) {
|
||||
if (worldIn.isRemote)
|
||||
|
@ -182,6 +186,25 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
return false;
|
||||
BeltTileEntity belt = (BeltTileEntity) te;
|
||||
|
||||
if (isHand) {
|
||||
TileEntity controllerTe = worldIn.getTileEntity(belt.getController());
|
||||
if (controllerTe == null || !(controllerTe instanceof BeltTileEntity))
|
||||
return false;
|
||||
if (worldIn.isRemote)
|
||||
return true;
|
||||
BeltTileEntity controllerBelt = (BeltTileEntity) controllerTe;
|
||||
for (Iterator<TransportedItemStack> iterator = controllerBelt.getInventory().items.iterator(); iterator
|
||||
.hasNext();) {
|
||||
TransportedItemStack transportedItemStack = iterator.next();
|
||||
if (Math.abs(belt.index + .5 - transportedItemStack.beltPosition) < .75f) {
|
||||
player.inventory.placeItemBackInInventory(worldIn, transportedItemStack.stack);
|
||||
iterator.remove();
|
||||
controllerBelt.markDirty();
|
||||
controllerBelt.sendData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isShaft) {
|
||||
if (state.get(PART) != Part.MIDDLE)
|
||||
return false;
|
||||
|
@ -255,7 +278,7 @@ public class BeltBlock extends HorizontalKineticBlock implements IWithoutBlockIt
|
|||
public PathNodeType getAiPathNodeType(BlockState state, IBlockReader world, BlockPos pos, MobEntity entity) {
|
||||
return PathNodeType.DANGER_OTHER;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VoxelShape getShape(BlockState state, IBlockReader worldIn, BlockPos pos, ISelectionContext context) {
|
||||
return VoxelShapes.or(BeltShapes.getShape(state), BeltShapes.getCasingShape(state));
|
||||
|
|
|
@ -121,8 +121,8 @@ public class BeltInventory {
|
|||
// See if any new belt processing catches the item
|
||||
int upcomingSegment = (int) (current.beltPosition + (beltMovementPositive ? .5f : -.5f));
|
||||
for (int segment = upcomingSegment; beltMovementPositive
|
||||
? segment <= current.beltPosition + limitedMovement
|
||||
: segment >= current.beltPosition + limitedMovement; segment += beltMovementPositive ? 1 : -1) {
|
||||
? segment + .5f <= current.beltPosition + limitedMovement
|
||||
: segment + .5f >= current.beltPosition + limitedMovement; segment += beltMovementPositive ? 1 : -1) {
|
||||
BeltTileEntity beltSegment = getBeltSegment(segmentBefore);
|
||||
if (beltSegment == null)
|
||||
break;
|
||||
|
|
|
@ -263,7 +263,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
return new Vec3i(movement.getX(), movingUp ? 1 : -1, movement.getZ());
|
||||
}
|
||||
|
||||
protected Direction getMovementFacing() {
|
||||
public Direction getMovementFacing() {
|
||||
return Direction.getFacingFromAxisDirection(getBeltFacing().getAxis(),
|
||||
getBeltMovementSpeed() < 0 ? POSITIVE : NEGATIVE);
|
||||
}
|
||||
|
|
|
@ -64,7 +64,8 @@ public class BeltTileEntityRenderer extends TileEntityRenderer<BeltTileEntity> {
|
|||
boolean onSlope = slope != Slope.HORIZONTAL
|
||||
&& MathHelper.clamp(offset, .5f, te.beltLength - .5f) == offset;
|
||||
float slopeAngle = onSlope
|
||||
? slope == Slope.DOWNWARD ^ te.getDirectionAwareBeltMovementSpeed() > 0 ? -45 : 45
|
||||
? slope == Slope.DOWNWARD ^ te.getDirectionAwareBeltMovementSpeed() > 0
|
||||
^ te.getBeltMovementSpeed() < 0 ? -45 : 45
|
||||
: 0;
|
||||
|
||||
GlStateManager.translated(offsetVec.x, offsetVec.y, offsetVec.z);
|
||||
|
@ -150,5 +151,5 @@ public class BeltTileEntityRenderer extends TileEntityRenderer<BeltTileEntity> {
|
|||
buffer.putBulkData(((BeltModelAnimator) KineticTileEntityRenderer.cachedBuffers
|
||||
.get(te.getBlockState().with(BeltBlock.CASING, false))).getTransformed(te, x, y, z, te.color));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,27 +1,35 @@
|
|||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.foundation.block.IWithTileEntity;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltInventory.TransportedItemStack;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltInventory.TransportedItemStack;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||
import com.simibubi.create.modules.logistics.block.IBlockWithFilter;
|
||||
import com.simibubi.create.modules.logistics.block.IInventoryManipulator;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.state.StateContainer.Builder;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
|
@ -30,7 +38,8 @@ import net.minecraft.world.IWorld;
|
|||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment, IWithTileEntity<BeltFunnelTileEntity> {
|
||||
public class BeltFunnelBlock extends HorizontalBlock
|
||||
implements IBeltAttachment, IWithTileEntity<BeltFunnelTileEntity>, IBlockWithFilter {
|
||||
|
||||
public static final VoxelShape SHAPE_NORTH = makeCuboidShape(3, -4, -1, 13, 8, 5),
|
||||
SHAPE_SOUTH = makeCuboidShape(3, -4, 11, 13, 8, 17), SHAPE_WEST = makeCuboidShape(-1, -4, 3, 5, 8, 13),
|
||||
|
@ -38,6 +47,7 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment,
|
|||
|
||||
public BeltFunnelBlock() {
|
||||
super(Properties.from(Blocks.ANDESITE));
|
||||
cacheItemPositions();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -154,6 +164,12 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment,
|
|||
|
||||
@Override
|
||||
public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
||||
Direction movementFacing = te.getMovementFacing();
|
||||
if (movementFacing.getAxis() == Axis.Z)
|
||||
movementFacing = movementFacing.getOpposite();
|
||||
if (movementFacing != te.getWorld().getBlockState(state.attachmentPos)
|
||||
.get(HORIZONTAL_FACING))
|
||||
return false;
|
||||
return process(te, transported, state);
|
||||
}
|
||||
|
||||
|
@ -167,4 +183,54 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment,
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
return handleActivatedFilterSlots(state, worldIn, pos, player, handIn, hit);
|
||||
}
|
||||
|
||||
private static final List<Vec3d> itemPositions = new ArrayList<>(Direction.values().length);
|
||||
|
||||
private void cacheItemPositions() {
|
||||
itemPositions.clear();
|
||||
|
||||
Vec3d position = Vec3d.ZERO;
|
||||
Vec3d shift = VecHelper.getCenterOf(BlockPos.ZERO);
|
||||
float zFightOffset = 1 / 128f;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
Direction facing = Direction.byHorizontalIndex(i);
|
||||
position = new Vec3d(8f / 16f + zFightOffset, 9f / 16f, 2.25f / 16f);
|
||||
|
||||
float angle = facing.getHorizontalAngle();
|
||||
if (facing.getAxis() == Axis.X)
|
||||
angle = -angle;
|
||||
|
||||
position = VecHelper.rotate(position.subtract(shift), angle, Axis.Y).add(shift);
|
||||
|
||||
itemPositions.add(position);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean showsCount() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getItemHitboxScale() {
|
||||
return 1.76f / 16f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3d getFilterPosition(BlockState state) {
|
||||
Direction facing = state.get(HORIZONTAL_FACING).getOpposite();
|
||||
return itemPositions.get(facing.getHorizontalIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Direction getFilterFacing(BlockState state) {
|
||||
return state.get(HORIZONTAL_FACING).getOpposite();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.simibubi.create.AllTileEntities;
|
|||
import com.simibubi.create.foundation.block.SyncedTileEntity;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltInventory.ItemHandlerSegment;
|
||||
import com.simibubi.create.modules.logistics.block.IHaveFilter;
|
||||
import com.simibubi.create.modules.logistics.block.IInventoryManipulator;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -21,27 +22,32 @@ import net.minecraftforge.common.util.LazyOptional;
|
|||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableTileEntity, IInventoryManipulator {
|
||||
public class BeltFunnelTileEntity extends SyncedTileEntity
|
||||
implements ITickableTileEntity, IInventoryManipulator, IHaveFilter {
|
||||
|
||||
private LazyOptional<IItemHandler> inventory;
|
||||
protected boolean waitingForInventorySpace;
|
||||
private boolean initialize;
|
||||
private ItemStack filter;
|
||||
|
||||
private ItemStack justEaten;
|
||||
|
||||
public BeltFunnelTileEntity() {
|
||||
super(AllTileEntities.BELT_FUNNEL.type);
|
||||
inventory = LazyOptional.empty();
|
||||
filter = ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT compound) {
|
||||
filter = ItemStack.read(compound.getCompound("Filter"));
|
||||
waitingForInventorySpace = compound.getBoolean("Waiting");
|
||||
super.read(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
compound.put("Filter", filter.serializeNBT());
|
||||
compound.putBoolean("Waiting", waitingForInventorySpace);
|
||||
return super.write(compound);
|
||||
}
|
||||
|
@ -109,16 +115,26 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT
|
|||
return stack;
|
||||
if (waitingForInventorySpace && !(inventory.orElse(null) instanceof ItemHandlerSegment))
|
||||
return stack;
|
||||
if (!filter.isEmpty() && !ItemStack.areItemsEqual(filter, stack))
|
||||
return stack;
|
||||
|
||||
IItemHandler inv = inventory.orElse(null);
|
||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(inv, stack.copy(), false);
|
||||
ItemStack inserted = stack.copy();
|
||||
int amountToExtract = Math.min(filter.isEmpty() ? 64 : filter.getCount(), stack.getCount());
|
||||
inserted.setCount(amountToExtract);
|
||||
|
||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(inv, inserted, false);
|
||||
|
||||
if (remainder.isEmpty()) {
|
||||
if (!world.isRemote)
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_GENERIC_EAT, SoundCategory.BLOCKS, .125f, 1f);
|
||||
justEaten = stack;
|
||||
justEaten = stack.copy();
|
||||
remainder = stack.copy();
|
||||
remainder.setCount(stack.getCount() - amountToExtract);
|
||||
|
||||
} else {
|
||||
waitingForInventorySpace = true;
|
||||
remainder.grow(stack.getCount() - amountToExtract);
|
||||
}
|
||||
|
||||
sendData();
|
||||
|
@ -134,4 +150,17 @@ public class BeltFunnelTileEntity extends SyncedTileEntity implements ITickableT
|
|||
1 / 6f, zSpeed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFilter(ItemStack stack) {
|
||||
filter = stack.copy();
|
||||
markDirty();
|
||||
sendData();
|
||||
neighborChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getFilter() {
|
||||
return filter.copy();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package com.simibubi.create.modules.logistics.block.belts;
|
||||
|
||||
import com.simibubi.create.modules.logistics.block.FilteredTileEntityRenderer;
|
||||
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
|
||||
public class BeltFunnelTileEntityRenderer extends TileEntityRenderer<BeltFunnelTileEntity> {
|
||||
|
||||
FilteredTileEntityRenderer filterRenderer;
|
||||
|
||||
public BeltFunnelTileEntityRenderer() {
|
||||
filterRenderer = new FilteredTileEntityRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(BeltFunnelTileEntity tileEntityIn, double x, double y, double z, float partialTicks,
|
||||
int destroyStage) {
|
||||
super.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
filterRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue