mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-23 03:17:53 +01:00
Reworked belt processing and interfacing
- Removed the IBeltAttachment system - Item processing on belts is now a TE behaviour - Added TE behaviour for allowing belts (and similar) to directly insert items - Massive refactor to the Belts' inventory - Fixed fast moving items missing their processing step - Saws, Basins, Crushing Wheels, Belts and Crafters now interact through the new behaviour rather than hard-coded interactions - Fixed items (visually) disappearing on saws while queueing up - Items on belts now back up a little further away from the end of the belt
This commit is contained in:
parent
69dd19cd58
commit
9fe1d85199
34 changed files with 753 additions and 1068 deletions
|
@ -5,6 +5,7 @@ import static com.simibubi.create.content.contraptions.base.HorizontalKineticBlo
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
@ -13,8 +14,8 @@ import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.crafter.ConnectedInputHandler.ConnectedInput;
|
import com.simibubi.create.content.contraptions.components.crafter.ConnectedInputHandler.ConnectedInput;
|
||||||
import com.simibubi.create.content.contraptions.components.crafter.RecipeGridHandler.GroupedItems;
|
import com.simibubi.create.content.contraptions.components.crafter.RecipeGridHandler.GroupedItems;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.edgeInteraction.EdgeInteractionBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.edgeInteraction.EdgeInteractionBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InsertingBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InsertingBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InventoryManagementBehaviour.Attachments;
|
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InventoryManagementBehaviour.Attachments;
|
||||||
|
@ -27,7 +28,6 @@ import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.particles.ItemParticleData;
|
import net.minecraft.particles.ItemParticleData;
|
||||||
import net.minecraft.particles.ParticleTypes;
|
import net.minecraft.particles.ParticleTypes;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -337,13 +337,13 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isTargetingBelt() {
|
protected boolean isTargetingBelt() {
|
||||||
|
DirectBeltInputBehaviour behaviour = getTargetingBelt();
|
||||||
|
return behaviour != null && behaviour.canInsertFromSide(getTargetFacing());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected DirectBeltInputBehaviour getTargetingBelt() {
|
||||||
BlockPos targetPos = pos.offset(getTargetFacing());
|
BlockPos targetPos = pos.offset(getTargetFacing());
|
||||||
if (!AllBlocks.BELT.has(world.getBlockState(targetPos)))
|
return TileEntityBehaviour.get(world, targetPos, DirectBeltInputBehaviour.TYPE);
|
||||||
return false;
|
|
||||||
TileEntity te = world.getTileEntity(targetPos);
|
|
||||||
if (!(te instanceof BeltTileEntity))
|
|
||||||
return false;
|
|
||||||
return ((KineticTileEntity) te).getSpeed() != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tryInsert() {
|
public void tryInsert() {
|
||||||
|
@ -355,22 +355,21 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
||||||
boolean chagedPhase = phase != Phase.INSERTING;
|
boolean chagedPhase = phase != Phase.INSERTING;
|
||||||
final List<Pair<Integer, Integer>> inserted = new LinkedList<>();
|
final List<Pair<Integer, Integer>> inserted = new LinkedList<>();
|
||||||
|
|
||||||
groupedItems.grid.forEach((pair, stack) -> {
|
DirectBeltInputBehaviour behaviour = getTargetingBelt();
|
||||||
if (isTargetingBelt()) {
|
for (Entry<Pair<Integer, Integer>, ItemStack> entry : groupedItems.grid.entrySet()) {
|
||||||
|
Pair<Integer, Integer> pair = entry.getKey();
|
||||||
|
ItemStack stack = entry.getValue();
|
||||||
Direction facing = getTargetFacing();
|
Direction facing = getTargetFacing();
|
||||||
BlockPos targetPos = pos.offset(facing);
|
|
||||||
BeltTileEntity te = (BeltTileEntity) world.getTileEntity(targetPos);
|
ItemStack remainder = behaviour == null ? inserting.insert(stack.copy(), false)
|
||||||
if (te.tryInsertingFromSide(facing, stack, false))
|
: behaviour.handleInsertion(stack, facing, false);
|
||||||
inserted.add(pair);
|
if (!remainder.isEmpty()) {
|
||||||
return;
|
stack.setCount(remainder.getCount());
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemStack remainder = inserting.insert(stack.copy(), false);
|
|
||||||
if (!remainder.isEmpty())
|
|
||||||
stack.setCount(remainder.getCount());
|
|
||||||
else
|
|
||||||
inserted.add(pair);
|
inserted.add(pair);
|
||||||
});
|
}
|
||||||
|
|
||||||
inserted.forEach(groupedItems.grid::remove);
|
inserted.forEach(groupedItems.grid::remove);
|
||||||
if (groupedItems.grid.isEmpty())
|
if (groupedItems.grid.isEmpty())
|
||||||
|
|
|
@ -11,7 +11,9 @@ import com.simibubi.create.content.contraptions.processing.ProcessingInventory;
|
||||||
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
|
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
import com.simibubi.create.foundation.item.ItemHelper;
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
import com.simibubi.create.foundation.tileEntity.SyncedTileEntity;
|
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.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
@ -24,7 +26,6 @@ import net.minecraft.particles.BlockParticleData;
|
||||||
import net.minecraft.particles.IParticleData;
|
import net.minecraft.particles.IParticleData;
|
||||||
import net.minecraft.particles.ItemParticleData;
|
import net.minecraft.particles.ItemParticleData;
|
||||||
import net.minecraft.particles.ParticleTypes;
|
import net.minecraft.particles.ParticleTypes;
|
||||||
import net.minecraft.tileentity.ITickableTileEntity;
|
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
@ -36,7 +37,7 @@ import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
import net.minecraftforge.items.IItemHandlerModifiable;
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||||
|
|
||||||
public class CrushingWheelControllerTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
public class CrushingWheelControllerTileEntity extends SmartTileEntity {
|
||||||
|
|
||||||
public Entity processingEntity;
|
public Entity processingEntity;
|
||||||
private UUID entityUUID;
|
private UUID entityUUID;
|
||||||
|
@ -60,8 +61,14 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
wrapper = new RecipeWrapper(inventory);
|
wrapper = new RecipeWrapper(inventory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||||
|
behaviours.add(new DirectBeltInputBehaviour(this));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
|
super.tick();
|
||||||
if (isFrozen())
|
if (isFrozen())
|
||||||
return;
|
return;
|
||||||
if (searchForEntity) {
|
if (searchForEntity) {
|
||||||
|
@ -84,9 +91,9 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
|
|
||||||
if (!hasEntity()) {
|
if (!hasEntity()) {
|
||||||
|
|
||||||
float processingSpeed = MathHelper.clamp(
|
float processingSpeed =
|
||||||
(speed) / (!inventory.appliedRecipe ? MathHelper.log2(inventory.getStackInSlot(0).getCount()) : 1),
|
MathHelper.clamp((speed) / (!inventory.appliedRecipe ? MathHelper.log2(inventory.getStackInSlot(0)
|
||||||
.25f, 20);
|
.getCount()) : 1), .25f, 20);
|
||||||
inventory.remainingTime -= processingSpeed;
|
inventory.remainingTime -= processingSpeed;
|
||||||
spawnParticles(inventory.getStackInSlot(0));
|
spawnParticles(inventory.getStackInSlot(0));
|
||||||
|
|
||||||
|
@ -107,7 +114,8 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
continue;
|
continue;
|
||||||
ItemEntity entityIn = new ItemEntity(world, outPos.x, outPos.y, outPos.z, stack);
|
ItemEntity entityIn = new ItemEntity(world, outPos.x, outPos.y, outPos.z, stack);
|
||||||
entityIn.setMotion(Vec3d.ZERO);
|
entityIn.setMotion(Vec3d.ZERO);
|
||||||
entityIn.getPersistentData().put("BypassCrushingWheel", NBTUtil.writeBlockPos(pos));
|
entityIn.getPersistentData()
|
||||||
|
.put("BypassCrushingWheel", NBTUtil.writeBlockPos(pos));
|
||||||
world.addEntity(entityIn);
|
world.addEntity(entityIn);
|
||||||
}
|
}
|
||||||
inventory.clear();
|
inventory.clear();
|
||||||
|
@ -118,8 +126,8 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!processingEntity.isAlive()
|
if (!processingEntity.isAlive() || !processingEntity.getBoundingBox()
|
||||||
|| !processingEntity.getBoundingBox().intersects(new AxisAlignedBB(pos).grow(.5f))) {
|
.intersects(new AxisAlignedBB(pos).grow(.5f))) {
|
||||||
clear();
|
clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -147,7 +155,8 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
itemEntity.setPickupDelay(20);
|
itemEntity.setPickupDelay(20);
|
||||||
if (processingEntity.getY() < pos.getY() + .25f) {
|
if (processingEntity.getY() < pos.getY() + .25f) {
|
||||||
inventory.clear();
|
inventory.clear();
|
||||||
inventory.setStackInSlot(0, itemEntity.getItem().copy());
|
inventory.setStackInSlot(0, itemEntity.getItem()
|
||||||
|
.copy());
|
||||||
itemInserted(inventory.getStackInSlot(0));
|
itemInserted(inventory.getStackInSlot(0));
|
||||||
itemEntity.remove();
|
itemEntity.remove();
|
||||||
world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), 2 | 16);
|
world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), 2 | 16);
|
||||||
|
@ -161,8 +170,8 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
|
|
||||||
IParticleData particleData = null;
|
IParticleData particleData = null;
|
||||||
if (stack.getItem() instanceof BlockItem)
|
if (stack.getItem() instanceof BlockItem)
|
||||||
particleData =
|
particleData = new BlockParticleData(ParticleTypes.BLOCK, ((BlockItem) stack.getItem()).getBlock()
|
||||||
new BlockParticleData(ParticleTypes.BLOCK, ((BlockItem) stack.getItem()).getBlock().getDefaultState());
|
.getDefaultState());
|
||||||
else
|
else
|
||||||
particleData = new ItemParticleData(ParticleTypes.ITEM, stack);
|
particleData = new ItemParticleData(ParticleTypes.ITEM, stack);
|
||||||
|
|
||||||
|
@ -177,10 +186,12 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
|
|
||||||
List<ItemStack> list = new ArrayList<>();
|
List<ItemStack> list = new ArrayList<>();
|
||||||
if (recipe.isPresent()) {
|
if (recipe.isPresent()) {
|
||||||
int rolls = inventory.getStackInSlot(0).getCount();
|
int rolls = inventory.getStackInSlot(0)
|
||||||
|
.getCount();
|
||||||
inventory.clear();
|
inventory.clear();
|
||||||
for (int roll = 0; roll < rolls; roll++) {
|
for (int roll = 0; roll < rolls; roll++) {
|
||||||
List<ItemStack> rolledResults = recipe.get().rollResults();
|
List<ItemStack> rolledResults = recipe.get()
|
||||||
|
.rollResults();
|
||||||
for (int i = 0; i < rolledResults.size(); i++) {
|
for (int i = 0; i < rolledResults.size(); i++) {
|
||||||
ItemStack stack = rolledResults.get(i);
|
ItemStack stack = rolledResults.get(i);
|
||||||
ItemHelper.addToList(stack, list);
|
ItemHelper.addToList(stack, list);
|
||||||
|
@ -195,10 +206,11 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<ProcessingRecipe<RecipeWrapper>> findRecipe() {
|
public Optional<ProcessingRecipe<RecipeWrapper>> findRecipe() {
|
||||||
Optional<ProcessingRecipe<RecipeWrapper>> crushingRecipe =
|
Optional<ProcessingRecipe<RecipeWrapper>> crushingRecipe = world.getRecipeManager()
|
||||||
world.getRecipeManager().getRecipe(AllRecipeTypes.CRUSHING.getType(), wrapper, world);
|
.getRecipe(AllRecipeTypes.CRUSHING.getType(), wrapper, world);
|
||||||
if (!crushingRecipe.isPresent())
|
if (!crushingRecipe.isPresent())
|
||||||
crushingRecipe = world.getRecipeManager().getRecipe(AllRecipeTypes.MILLING.getType(), wrapper, world);
|
crushingRecipe = world.getRecipeManager()
|
||||||
|
.getRecipe(AllRecipeTypes.MILLING.getType(), wrapper, world);
|
||||||
return crushingRecipe;
|
return crushingRecipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +243,8 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
||||||
|
|
||||||
private void itemInserted(ItemStack stack) {
|
private void itemInserted(ItemStack stack) {
|
||||||
Optional<ProcessingRecipe<RecipeWrapper>> recipe = findRecipe();
|
Optional<ProcessingRecipe<RecipeWrapper>> recipe = findRecipe();
|
||||||
inventory.remainingTime = recipe.isPresent() ? recipe.get().getProcessingDuration() : 100;
|
inventory.remainingTime = recipe.isPresent() ? recipe.get()
|
||||||
|
.getProcessingDuration() : 100;
|
||||||
inventory.appliedRecipe = false;
|
inventory.appliedRecipe = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.simibubi.create.content.contraptions.components.press;
|
||||||
|
|
||||||
|
import static com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult.HOLD;
|
||||||
|
import static com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult.PASS;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity.Mode;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltInventory;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||||
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
public class BeltPressingCallbacks {
|
||||||
|
|
||||||
|
static ProcessingResult onItemReceived(TransportedItemStack transported, BeltInventory beltInventory,
|
||||||
|
MechanicalPressTileEntity press) {
|
||||||
|
if (press.getSpeed() == 0 || press.running)
|
||||||
|
return PASS;
|
||||||
|
if (!press.getRecipe(transported.stack)
|
||||||
|
.isPresent())
|
||||||
|
return PASS;
|
||||||
|
|
||||||
|
press.start(Mode.BELT);
|
||||||
|
return HOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ProcessingResult whenItemHeld(TransportedItemStack transportedStack, BeltInventory beltInventory,
|
||||||
|
MechanicalPressTileEntity pressTe) {
|
||||||
|
|
||||||
|
if (pressTe.getSpeed() == 0)
|
||||||
|
return PASS;
|
||||||
|
if (!pressTe.running)
|
||||||
|
return PASS;
|
||||||
|
if (pressTe.runningTicks != 30)
|
||||||
|
return HOLD;
|
||||||
|
|
||||||
|
Optional<PressingRecipe> recipe = pressTe.getRecipe(transportedStack.stack);
|
||||||
|
pressTe.pressedItems.clear();
|
||||||
|
pressTe.pressedItems.add(transportedStack.stack);
|
||||||
|
|
||||||
|
if (!recipe.isPresent())
|
||||||
|
return PASS;
|
||||||
|
|
||||||
|
ItemStack out = recipe.get()
|
||||||
|
.getRecipeOutput()
|
||||||
|
.copy();
|
||||||
|
List<ItemStack> multipliedOutput = ItemHelper.multipliedOutput(transportedStack.stack, out);
|
||||||
|
if (multipliedOutput.isEmpty())
|
||||||
|
transportedStack.stack = ItemStack.EMPTY;
|
||||||
|
transportedStack.stack = multipliedOutput.get(0);
|
||||||
|
pressTe.sendData();
|
||||||
|
return HOLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,28 +1,16 @@
|
||||||
package com.simibubi.create.content.contraptions.components.press;
|
package com.simibubi.create.content.contraptions.components.press;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllShapes;
|
import com.simibubi.create.AllShapes;
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock;
|
import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock;
|
||||||
import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity.Mode;
|
import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity.Mode;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Slope;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
|
||||||
import com.simibubi.create.foundation.block.ITE;
|
import com.simibubi.create.foundation.block.ITE;
|
||||||
import com.simibubi.create.foundation.item.ItemHelper;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.BlockItemUseContext;
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
@ -30,12 +18,11 @@ import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||||
import net.minecraft.util.math.shapes.VoxelShape;
|
import net.minecraft.util.math.shapes.VoxelShape;
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.IWorld;
|
|
||||||
import net.minecraft.world.IWorldReader;
|
import net.minecraft.world.IWorldReader;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class MechanicalPressBlock extends HorizontalKineticBlock
|
public class MechanicalPressBlock extends HorizontalKineticBlock
|
||||||
implements ITE<MechanicalPressTileEntity>, IBeltAttachment {
|
implements ITE<MechanicalPressTileEntity> {
|
||||||
|
|
||||||
public MechanicalPressBlock(Properties properties) {
|
public MechanicalPressBlock(Properties properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
|
@ -93,95 +80,6 @@ public class MechanicalPressBlock extends HorizontalKineticBlock
|
||||||
return face.getAxis() == state.get(HORIZONTAL_FACING).getAxis();
|
return face.getAxis() == state.get(HORIZONTAL_FACING).getAxis();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
|
||||||
onAttachmentPlaced(worldIn, pos, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<BlockPos> getPotentialAttachmentPositions(IWorld world, BlockPos pos, BlockState beltState) {
|
|
||||||
return Arrays.asList(pos.up(2));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
|
||||||
onAttachmentRemoved(worldIn, pos, state);
|
|
||||||
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
|
||||||
worldIn.removeTileEntity(pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockPos getBeltPositionForAttachment(IWorld world, BlockPos pos, BlockState state) {
|
|
||||||
return pos.down(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAttachedCorrectly(IWorld world, BlockPos attachmentPos, BlockPos beltPos,
|
|
||||||
BlockState attachmentState, BlockState beltState) {
|
|
||||||
return AllBlocks.BELT.has(beltState) && beltState.get(BeltBlock.SLOPE) == Slope.HORIZONTAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean startProcessingItem(BeltTileEntity belt, TransportedItemStack transported,
|
|
||||||
BeltAttachmentState state) {
|
|
||||||
try {
|
|
||||||
MechanicalPressTileEntity pressTe = getTileEntity(belt.getWorld(), state.attachmentPos);
|
|
||||||
if (pressTe.getSpeed() == 0)
|
|
||||||
return false;
|
|
||||||
if (pressTe.running)
|
|
||||||
return false;
|
|
||||||
if (!pressTe.getRecipe(transported.stack).isPresent())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
state.processingDuration = 1;
|
|
||||||
pressTe.start(Mode.BELT);
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} catch (TileEntityException e) {}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean processItem(BeltTileEntity belt, TransportedItemStack transportedStack, BeltAttachmentState state) {
|
|
||||||
try {
|
|
||||||
MechanicalPressTileEntity pressTe = getTileEntity(belt.getWorld(), state.attachmentPos);
|
|
||||||
|
|
||||||
// Not powered
|
|
||||||
if (pressTe.getSpeed() == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Running
|
|
||||||
if (!pressTe.running)
|
|
||||||
return false;
|
|
||||||
if (pressTe.runningTicks != 30)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
Optional<PressingRecipe> recipe = pressTe.getRecipe(transportedStack.stack);
|
|
||||||
|
|
||||||
pressTe.pressedItems.clear();
|
|
||||||
pressTe.pressedItems.add(transportedStack.stack);
|
|
||||||
|
|
||||||
if (!recipe.isPresent())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ItemStack out = recipe.get().getRecipeOutput().copy();
|
|
||||||
List<ItemStack> multipliedOutput = ItemHelper.multipliedOutput(transportedStack.stack, out);
|
|
||||||
if (multipliedOutput.isEmpty())
|
|
||||||
transportedStack.stack = ItemStack.EMPTY;
|
|
||||||
transportedStack.stack = multipliedOutput.get(0);
|
|
||||||
|
|
||||||
BeltTileEntity controllerTE = belt.getControllerTE();
|
|
||||||
if (controllerTE != null)
|
|
||||||
controllerTE.sendData();
|
|
||||||
pressTe.sendData();
|
|
||||||
return true;
|
|
||||||
|
|
||||||
} catch (TileEntityException e) {}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<MechanicalPressTileEntity> getTileEntityClass() {
|
public Class<MechanicalPressTileEntity> getTileEntityClass() {
|
||||||
return MechanicalPressTileEntity.class;
|
return MechanicalPressTileEntity.class;
|
||||||
|
|
|
@ -11,6 +11,8 @@ import com.simibubi.create.content.contraptions.processing.BasinTileEntity.Basin
|
||||||
import com.simibubi.create.content.logistics.InWorldProcessing;
|
import com.simibubi.create.content.logistics.InWorldProcessing;
|
||||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||||
import com.simibubi.create.foundation.item.ItemHelper;
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
|
@ -59,6 +61,8 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static PressingInv pressingInv = new PressingInv();
|
private static PressingInv pressingInv = new PressingInv();
|
||||||
|
public BeltProcessingBehaviour processingBehaviour;
|
||||||
|
|
||||||
public int runningTicks;
|
public int runningTicks;
|
||||||
public boolean running;
|
public boolean running;
|
||||||
public Mode mode;
|
public Mode mode;
|
||||||
|
@ -69,6 +73,15 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
||||||
mode = Mode.WORLD;
|
mode = Mode.WORLD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||||
|
super.addBehaviours(behaviours);
|
||||||
|
processingBehaviour =
|
||||||
|
new BeltProcessingBehaviour(this).whenItemEnters((s, i) -> BeltPressingCallbacks.onItemReceived(s, i, this))
|
||||||
|
.whileItemHeld((s, i) -> BeltPressingCallbacks.whenItemHeld(s, i, this));
|
||||||
|
behaviours.add(processingBehaviour);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(CompoundNBT compound) {
|
public void read(CompoundNBT compound) {
|
||||||
running = compound.getBoolean("Running");
|
running = compound.getBoolean("Running");
|
||||||
|
@ -105,7 +118,8 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AxisAlignedBB getRenderBoundingBox() {
|
public AxisAlignedBB getRenderBoundingBox() {
|
||||||
return new AxisAlignedBB(pos).expand(0, -1.5, 0).expand(0, 1, 0);
|
return new AxisAlignedBB(pos).expand(0, -1.5, 0)
|
||||||
|
.expand(0, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getRenderedHeadOffset(float partialTicks) {
|
public float getRenderedHeadOffset(float partialTicks) {
|
||||||
|
@ -180,7 +194,8 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
||||||
if (basinInv.isPresent() && orElse instanceof BasinInventory) {
|
if (basinInv.isPresent() && orElse instanceof BasinInventory) {
|
||||||
BasinInventory inv = (BasinInventory) orElse;
|
BasinInventory inv = (BasinInventory) orElse;
|
||||||
|
|
||||||
for (int slot = 0; slot < inv.getInputHandler().getSlots(); slot++) {
|
for (int slot = 0; slot < inv.getInputHandler()
|
||||||
|
.getSlots(); slot++) {
|
||||||
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
||||||
if (stackInSlot.isEmpty())
|
if (stackInSlot.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
@ -229,12 +244,12 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
||||||
pressedItems.forEach(stack -> makeCompactingParticleEffect(VecHelper.getCenterOf(pos.down(2)), stack));
|
pressedItems.forEach(stack -> makeCompactingParticleEffect(VecHelper.getCenterOf(pos.down(2)), stack));
|
||||||
}
|
}
|
||||||
if (mode == Mode.BELT) {
|
if (mode == Mode.BELT) {
|
||||||
pressedItems.forEach(
|
pressedItems.forEach(stack -> makePressingParticleEffect(VecHelper.getCenterOf(pos.down(2))
|
||||||
stack -> makePressingParticleEffect(VecHelper.getCenterOf(pos.down(2)).add(0, 8 / 16f, 0), stack));
|
.add(0, 8 / 16f, 0), stack));
|
||||||
}
|
}
|
||||||
if (mode == Mode.WORLD) {
|
if (mode == Mode.WORLD) {
|
||||||
pressedItems.forEach(
|
pressedItems.forEach(stack -> makePressingParticleEffect(VecHelper.getCenterOf(pos.down(1))
|
||||||
stack -> makePressingParticleEffect(VecHelper.getCenterOf(pos.down(1)).add(0, -1 / 4f, 0), stack));
|
.add(0, -1 / 4f, 0), stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
pressedItems.clear();
|
pressedItems.clear();
|
||||||
|
@ -243,7 +258,8 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
||||||
public void makePressingParticleEffect(Vec3d pos, ItemStack stack) {
|
public void makePressingParticleEffect(Vec3d pos, ItemStack stack) {
|
||||||
if (world.isRemote) {
|
if (world.isRemote) {
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .125f).mul(1, 0, 1);
|
Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .125f)
|
||||||
|
.mul(1, 0, 1);
|
||||||
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), pos.x, pos.y - .25f, pos.z, motion.x,
|
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), pos.x, pos.y - .25f, pos.z, motion.x,
|
||||||
motion.y + .125f, motion.z);
|
motion.y + .125f, motion.z);
|
||||||
}
|
}
|
||||||
|
@ -253,7 +269,8 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
||||||
public void makeCompactingParticleEffect(Vec3d pos, ItemStack stack) {
|
public void makeCompactingParticleEffect(Vec3d pos, ItemStack stack) {
|
||||||
if (world.isRemote) {
|
if (world.isRemote) {
|
||||||
for (int i = 0; i < 20; i++) {
|
for (int i = 0; i < 20; i++) {
|
||||||
Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .175f).mul(1, 0, 1);
|
Vec3d motion = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .175f)
|
||||||
|
.mul(1, 0, 1);
|
||||||
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), pos.x, pos.y, pos.z, motion.x,
|
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), pos.x, pos.y, pos.z, motion.x,
|
||||||
motion.y + .25f, motion.z);
|
motion.y + .25f, motion.z);
|
||||||
}
|
}
|
||||||
|
@ -262,14 +279,14 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
||||||
|
|
||||||
public Optional<PressingRecipe> getRecipe(ItemStack item) {
|
public Optional<PressingRecipe> getRecipe(ItemStack item) {
|
||||||
pressingInv.setInventorySlotContents(0, item);
|
pressingInv.setInventorySlotContents(0, item);
|
||||||
Optional<PressingRecipe> recipe =
|
Optional<PressingRecipe> recipe = world.getRecipeManager()
|
||||||
world.getRecipeManager().getRecipe(AllRecipeTypes.PRESSING.getType(), pressingInv, world);
|
.getRecipe(AllRecipeTypes.PRESSING.getType(), pressingInv, world);
|
||||||
return recipe;
|
return recipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean canCompress(NonNullList<Ingredient> ingredients) {
|
public static boolean canCompress(NonNullList<Ingredient> ingredients) {
|
||||||
return (ingredients.size() == 4 || ingredients.size() == 9)
|
return (ingredients.size() == 4 || ingredients.size() == 9) && ItemHelper.condenseIngredients(ingredients)
|
||||||
&& ItemHelper.condenseIngredients(ingredients).size() == 1;
|
.size() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -283,7 +300,8 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
NonNullList<Ingredient> ingredients = recipe.getIngredients();
|
NonNullList<Ingredient> ingredients = recipe.getIngredients();
|
||||||
if (!ingredients.stream().allMatch(Ingredient::isSimple))
|
if (!ingredients.stream()
|
||||||
|
.allMatch(Ingredient::isSimple))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
List<ItemStack> remaining = new ArrayList<>();
|
List<ItemStack> remaining = new ArrayList<>();
|
||||||
|
|
|
@ -61,7 +61,11 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> {
|
||||||
if (te.getSpeed() < 0 ^ alongZ)
|
if (te.getSpeed() < 0 ^ alongZ)
|
||||||
offset = 1 - offset;
|
offset = 1 - offset;
|
||||||
|
|
||||||
ItemStack stack = te.inventory.getStackInSlot(0);
|
for (int i = 0; i < te.inventory.getSlots(); i++) {
|
||||||
|
ItemStack stack = te.inventory.getStackInSlot(i);
|
||||||
|
if (stack.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
||||||
IBakedModel modelWithOverrides = itemRenderer.getItemModelWithOverrides(stack, te.getWorld(), null);
|
IBakedModel modelWithOverrides = itemRenderer.getItemModelWithOverrides(stack, te.getWorld(), null);
|
||||||
boolean blockItem = modelWithOverrides.isGui3d();
|
boolean blockItem = modelWithOverrides.isGui3d();
|
||||||
|
@ -73,6 +77,9 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> {
|
||||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(90));
|
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(90));
|
||||||
ms.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(90));
|
ms.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(90));
|
||||||
itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED, light, overlay, ms, buffer);
|
itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED, light, overlay, ms, buffer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
ms.pop();
|
ms.pop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,12 @@ import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
|
||||||
import com.simibubi.create.AllRecipeTypes;
|
import com.simibubi.create.AllRecipeTypes;
|
||||||
import com.simibubi.create.content.contraptions.components.actors.BlockBreakingKineticTileEntity;
|
import com.simibubi.create.content.contraptions.components.actors.BlockBreakingKineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.processing.ProcessingInventory;
|
import com.simibubi.create.content.contraptions.processing.ProcessingInventory;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
|
||||||
import com.simibubi.create.foundation.item.ItemHelper;
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.BlockHelper;
|
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||||
import com.simibubi.create.foundation.utility.TreeCutter;
|
import com.simibubi.create.foundation.utility.TreeCutter;
|
||||||
|
@ -44,7 +43,6 @@ import net.minecraft.particles.IParticleData;
|
||||||
import net.minecraft.particles.ItemParticleData;
|
import net.minecraft.particles.ItemParticleData;
|
||||||
import net.minecraft.particles.ParticleTypes;
|
import net.minecraft.particles.ParticleTypes;
|
||||||
import net.minecraft.tags.BlockTags;
|
import net.minecraft.tags.BlockTags;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
@ -78,6 +76,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
||||||
super.addBehaviours(behaviours);
|
super.addBehaviours(behaviours);
|
||||||
filtering = new FilteringBehaviour(this, new SawFilterSlot());
|
filtering = new FilteringBehaviour(this, new SawFilterSlot());
|
||||||
behaviours.add(filtering);
|
behaviours.add(filtering);
|
||||||
|
behaviours.add(new DirectBeltInputBehaviour(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -142,65 +141,39 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
||||||
|
|
||||||
Vec3d itemMovement = getItemMovementVec();
|
Vec3d itemMovement = getItemMovementVec();
|
||||||
Direction itemMovementFacing = Direction.getFacingFromVector(itemMovement.x, itemMovement.y, itemMovement.z);
|
Direction itemMovementFacing = Direction.getFacingFromVector(itemMovement.x, itemMovement.y, itemMovement.z);
|
||||||
Vec3d outPos = VecHelper.getCenterOf(pos).add(itemMovement.scale(.5f).add(0, .5, 0));
|
if (inventory.remainingTime > 0)
|
||||||
Vec3d outMotion = itemMovement.scale(.0625).add(0, .125, 0);
|
return;
|
||||||
|
inventory.remainingTime = 0;
|
||||||
|
|
||||||
if (inventory.remainingTime <= 0) {
|
|
||||||
|
|
||||||
// Try moving items onto the belt
|
|
||||||
BlockPos nextPos = pos.add(itemMovement.x, itemMovement.y, itemMovement.z);
|
BlockPos nextPos = pos.add(itemMovement.x, itemMovement.y, itemMovement.z);
|
||||||
if (AllBlocks.BELT.has(world.getBlockState(nextPos))) {
|
DirectBeltInputBehaviour behaviour = TileEntityBehaviour.get(world, nextPos, DirectBeltInputBehaviour.TYPE);
|
||||||
TileEntity te = world.getTileEntity(nextPos);
|
if (behaviour != null) {
|
||||||
if (te != null && te instanceof BeltTileEntity) {
|
boolean changed = false;
|
||||||
|
if (!behaviour.canInsertFromSide(itemMovementFacing))
|
||||||
|
return;
|
||||||
for (int slot = 0; slot < inventory.getSlots(); slot++) {
|
for (int slot = 0; slot < inventory.getSlots(); slot++) {
|
||||||
ItemStack stack = inventory.getStackInSlot(slot);
|
ItemStack stack = inventory.getStackInSlot(slot);
|
||||||
if (stack.isEmpty())
|
if (stack.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
ItemStack remainder = behaviour.handleInsertion(stack, itemMovementFacing, false);
|
||||||
if (((BeltTileEntity) te).tryInsertingFromSide(itemMovementFacing, stack, false))
|
if (remainder.equals(stack, false))
|
||||||
inventory.setStackInSlot(slot, ItemStack.EMPTY);
|
|
||||||
else {
|
|
||||||
inventory.remainingTime = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
inventory.clear();
|
|
||||||
inventory.remainingTime = -1;
|
|
||||||
sendData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try moving items onto next saw
|
|
||||||
if (AllBlocks.MECHANICAL_SAW.has(world.getBlockState(nextPos))) {
|
|
||||||
TileEntity te = world.getTileEntity(nextPos);
|
|
||||||
if (te != null && te instanceof SawTileEntity) {
|
|
||||||
SawTileEntity sawTileEntity = (SawTileEntity) te;
|
|
||||||
Vec3d otherMovement = sawTileEntity.getItemMovementVec();
|
|
||||||
if (Direction.getFacingFromVector(otherMovement.x, otherMovement.y,
|
|
||||||
otherMovement.z) != itemMovementFacing.getOpposite()) {
|
|
||||||
for (int slot = 0; slot < inventory.getSlots(); slot++) {
|
|
||||||
ItemStack stack = inventory.getStackInSlot(slot);
|
|
||||||
if (stack.isEmpty())
|
|
||||||
continue;
|
continue;
|
||||||
|
inventory.setStackInSlot(slot, remainder);
|
||||||
ProcessingInventory sawInv = sawTileEntity.inventory;
|
changed = true;
|
||||||
if (sawInv.isEmpty()) {
|
|
||||||
sawInv.insertItem(0, stack, false);
|
|
||||||
inventory.setStackInSlot(slot, ItemStack.EMPTY);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
inventory.remainingTime = 0;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
if (changed) {
|
||||||
inventory.clear();
|
markDirty();
|
||||||
inventory.remainingTime = -1;
|
|
||||||
sendData();
|
sendData();
|
||||||
}
|
}
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eject Items
|
// Eject Items
|
||||||
|
Vec3d outPos = VecHelper.getCenterOf(pos)
|
||||||
|
.add(itemMovement.scale(.5f)
|
||||||
|
.add(0, .5, 0));
|
||||||
|
Vec3d outMotion = itemMovement.scale(.0625)
|
||||||
|
.add(0, .125, 0);
|
||||||
for (int slot = 0; slot < inventory.getSlots(); slot++) {
|
for (int slot = 0; slot < inventory.getSlots(); slot++) {
|
||||||
ItemStack stack = inventory.getStackInSlot(slot);
|
ItemStack stack = inventory.getStackInSlot(slot);
|
||||||
if (stack.isEmpty())
|
if (stack.isEmpty())
|
||||||
|
@ -213,10 +186,6 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
||||||
world.updateComparatorOutputLevel(pos, getBlockState().getBlock());
|
world.updateComparatorOutputLevel(pos, getBlockState().getBlock());
|
||||||
inventory.remainingTime = -1;
|
inventory.remainingTime = -1;
|
||||||
sendData();
|
sendData();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -240,8 +209,8 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
||||||
IParticleData particleData = null;
|
IParticleData particleData = null;
|
||||||
float speed = 1;
|
float speed = 1;
|
||||||
if (stack.getItem() instanceof BlockItem)
|
if (stack.getItem() instanceof BlockItem)
|
||||||
particleData =
|
particleData = new BlockParticleData(ParticleTypes.BLOCK, ((BlockItem) stack.getItem()).getBlock()
|
||||||
new BlockParticleData(ParticleTypes.BLOCK, ((BlockItem) stack.getItem()).getBlock().getDefaultState());
|
.getDefaultState());
|
||||||
else {
|
else {
|
||||||
particleData = new ItemParticleData(ParticleTypes.ITEM, stack);
|
particleData = new ItemParticleData(ParticleTypes.ITEM, stack);
|
||||||
speed = .125f;
|
speed = .125f;
|
||||||
|
@ -271,7 +240,8 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
||||||
|
|
||||||
IRecipe<?> recipe = recipes.get(recipeIndex);
|
IRecipe<?> recipe = recipes.get(recipeIndex);
|
||||||
|
|
||||||
int rolls = inventory.getStackInSlot(0).getCount();
|
int rolls = inventory.getStackInSlot(0)
|
||||||
|
.getCount();
|
||||||
inventory.clear();
|
inventory.clear();
|
||||||
|
|
||||||
List<ItemStack> list = new ArrayList<>();
|
List<ItemStack> list = new ArrayList<>();
|
||||||
|
@ -280,7 +250,8 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
||||||
if (recipe instanceof CuttingRecipe)
|
if (recipe instanceof CuttingRecipe)
|
||||||
results = ((CuttingRecipe) recipe).rollResults();
|
results = ((CuttingRecipe) recipe).rollResults();
|
||||||
else if (recipe instanceof StonecuttingRecipe)
|
else if (recipe instanceof StonecuttingRecipe)
|
||||||
results.add(recipe.getRecipeOutput().copy());
|
results.add(recipe.getRecipeOutput()
|
||||||
|
.copy());
|
||||||
|
|
||||||
for (int i = 0; i < results.size(); i++) {
|
for (int i = 0; i < results.size(); i++) {
|
||||||
ItemStack stack = results.get(i);
|
ItemStack stack = results.get(i);
|
||||||
|
@ -295,7 +266,8 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
||||||
private List<? extends IRecipe<?>> getRecipes() {
|
private List<? extends IRecipe<?>> getRecipes() {
|
||||||
List<IRecipe<?>> startedSearch = RecipeFinder.get(cuttingRecipesKey, world,
|
List<IRecipe<?>> startedSearch = RecipeFinder.get(cuttingRecipesKey, world,
|
||||||
RecipeConditions.isOfType(IRecipeType.STONECUTTING, AllRecipeTypes.CUTTING.getType()));
|
RecipeConditions.isOfType(IRecipeType.STONECUTTING, AllRecipeTypes.CUTTING.getType()));
|
||||||
return startedSearch.stream().filter(RecipeConditions.outputMatchesFilter(filtering))
|
return startedSearch.stream()
|
||||||
|
.filter(RecipeConditions.outputMatchesFilter(filtering))
|
||||||
.filter(RecipeConditions.firstIngredientMatches(inventory.getStackInSlot(0)))
|
.filter(RecipeConditions.firstIngredientMatches(inventory.getStackInSlot(0)))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
@ -309,7 +281,8 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
inventory.clear();
|
inventory.clear();
|
||||||
inventory.insertItem(0, entity.getItem().copy(), false);
|
inventory.insertItem(0, entity.getItem()
|
||||||
|
.copy(), false);
|
||||||
entity.remove();
|
entity.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +330,9 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldRun() {
|
protected boolean shouldRun() {
|
||||||
return getBlockState().get(SawBlock.FACING).getAxis().isHorizontal();
|
return getBlockState().get(SawBlock.FACING)
|
||||||
|
.getAxis()
|
||||||
|
.isHorizontal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package com.simibubi.create.content.contraptions.processing;
|
package com.simibubi.create.content.contraptions.processing;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.tileEntity.SyncedTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
@ -19,7 +22,7 @@ import net.minecraftforge.items.ItemStackHandler;
|
||||||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||||
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||||
|
|
||||||
public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
public class BasinTileEntity extends SmartTileEntity implements ITickableTileEntity {
|
||||||
|
|
||||||
public boolean contentsChanged;
|
public boolean contentsChanged;
|
||||||
|
|
||||||
|
@ -97,6 +100,11 @@ public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEn
|
||||||
recipeInventory = new BasinInputInventory();
|
recipeInventory = new BasinInputInventory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||||
|
behaviours.add(new DirectBeltInputBehaviour(this));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(CompoundNBT compound) {
|
public void read(CompoundNBT compound) {
|
||||||
super.read(compound);
|
super.read(compound);
|
||||||
|
|
|
@ -1,202 +0,0 @@
|
||||||
package com.simibubi.create.content.contraptions.relays.belt;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
|
||||||
import com.simibubi.create.Create;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
|
||||||
import net.minecraft.nbt.INBT;
|
|
||||||
import net.minecraft.nbt.ListNBT;
|
|
||||||
import net.minecraft.nbt.NBTUtil;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.world.IWorld;
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
|
|
||||||
public enum AllBeltAttachments { //TODO rework this nonsense
|
|
||||||
|
|
||||||
BELT_FUNNEL(AllBlocks.FUNNEL.get()),
|
|
||||||
BELT_OBSERVER(AllBlocks.BELT_OBSERVER.get()),
|
|
||||||
MECHANICAL_PRESS(AllBlocks.MECHANICAL_PRESS.get()),
|
|
||||||
LOGISTICAL_ATTACHABLES(AllBlocks.EXTRACTOR.get()),
|
|
||||||
|
|
||||||
;
|
|
||||||
|
|
||||||
IBeltAttachment attachment;
|
|
||||||
|
|
||||||
private AllBeltAttachments(Block attachment) {
|
|
||||||
this.attachment = (IBeltAttachment) attachment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IBeltAttachment {
|
|
||||||
|
|
||||||
public List<BlockPos> getPotentialAttachmentPositions(IWorld world, BlockPos pos, BlockState beltState);
|
|
||||||
|
|
||||||
public BlockPos getBeltPositionForAttachment(IWorld world, BlockPos pos, BlockState state);
|
|
||||||
|
|
||||||
default boolean isAttachedCorrectly(IWorld world, BlockPos attachmentPos, BlockPos beltPos,
|
|
||||||
BlockState attachmentState, BlockState beltState) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean processEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported,
|
|
||||||
BeltAttachmentState state) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default void onAttachmentPlaced(IWorld world, BlockPos pos, BlockState state) {
|
|
||||||
BlockPos beltPos = getBeltPositionForAttachment(world, pos, state);
|
|
||||||
BeltTileEntity belt = BeltHelper.getSegmentTE(world, beltPos);
|
|
||||||
|
|
||||||
if (belt == null)
|
|
||||||
return;
|
|
||||||
if (!isAttachedCorrectly(world, pos, beltPos, state, world.getBlockState(beltPos)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
belt.attachmentTracker.addAttachment(world, pos);
|
|
||||||
belt.markDirty();
|
|
||||||
belt.sendData();
|
|
||||||
}
|
|
||||||
|
|
||||||
default void onAttachmentRemoved(IWorld world, BlockPos pos, BlockState state) {
|
|
||||||
BlockPos beltPos = getBeltPositionForAttachment(world, pos, state);
|
|
||||||
BeltTileEntity belt = BeltHelper.getSegmentTE(world, beltPos);
|
|
||||||
|
|
||||||
if (belt == null)
|
|
||||||
return;
|
|
||||||
if (!isAttachedCorrectly(world, pos, beltPos, state, world.getBlockState(beltPos)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
belt.attachmentTracker.removeAttachment(pos);
|
|
||||||
belt.markDirty();
|
|
||||||
belt.sendData();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class BeltAttachmentState {
|
|
||||||
public IBeltAttachment attachment;
|
|
||||||
public BlockPos attachmentPos;
|
|
||||||
public int processingDuration;
|
|
||||||
public Entity processingEntity;
|
|
||||||
public TransportedItemStack processingStack;
|
|
||||||
|
|
||||||
public BeltAttachmentState(IBeltAttachment attachment, BlockPos attachmentPos) {
|
|
||||||
this.attachment = attachment;
|
|
||||||
this.attachmentPos = attachmentPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Tracker {
|
|
||||||
public List<BeltAttachmentState> attachments;
|
|
||||||
private BeltTileEntity te;
|
|
||||||
|
|
||||||
public Tracker(BeltTileEntity te) {
|
|
||||||
attachments = new LinkedList<>();
|
|
||||||
this.te = te;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void findAttachments(BeltTileEntity belt) {
|
|
||||||
for (AllBeltAttachments ba : AllBeltAttachments.values()) {
|
|
||||||
World world = belt.getWorld();
|
|
||||||
BlockPos beltPos = belt.getPos();
|
|
||||||
BlockState beltState = belt.getBlockState();
|
|
||||||
List<BlockPos> attachmentPositions =
|
|
||||||
ba.attachment.getPotentialAttachmentPositions(world, beltPos, beltState);
|
|
||||||
|
|
||||||
for (BlockPos potentialPos : attachmentPositions) {
|
|
||||||
if (!world.isBlockPresent(potentialPos))
|
|
||||||
continue;
|
|
||||||
BlockState state = world.getBlockState(potentialPos);
|
|
||||||
if (!(state.getBlock() instanceof IBeltAttachment))
|
|
||||||
continue;
|
|
||||||
IBeltAttachment attachment = (IBeltAttachment) state.getBlock();
|
|
||||||
if (!attachment.getBeltPositionForAttachment(world, potentialPos, state).equals(beltPos))
|
|
||||||
continue;
|
|
||||||
if (!attachment.isAttachedCorrectly(world, potentialPos, beltPos, state, beltState))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
addAttachment(world, potentialPos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public BeltAttachmentState addAttachment(IWorld world, BlockPos pos) {
|
|
||||||
BlockState state = world.getBlockState(pos);
|
|
||||||
removeAttachment(pos);
|
|
||||||
if (!(state.getBlock() instanceof IBeltAttachment)) {
|
|
||||||
Create.logger.warn("Missing belt attachment for Belt at " + pos.toString());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
BeltAttachmentState newAttachmentState = new BeltAttachmentState((IBeltAttachment) state.getBlock(), pos);
|
|
||||||
attachments.add(newAttachmentState);
|
|
||||||
te.markDirty();
|
|
||||||
return newAttachmentState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeAttachment(BlockPos pos) {
|
|
||||||
BeltAttachmentState toRemove = null;
|
|
||||||
for (BeltAttachmentState atState : attachments)
|
|
||||||
if (atState.attachmentPos.equals(pos))
|
|
||||||
toRemove = atState;
|
|
||||||
if (toRemove != null)
|
|
||||||
attachments.remove(toRemove);
|
|
||||||
te.markDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void forEachAttachment(Consumer<BeltAttachmentState> consumer) {
|
|
||||||
attachments.forEach(consumer::accept);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void readAndSearch(CompoundNBT nbt, BeltTileEntity belt) {
|
|
||||||
attachments.clear();
|
|
||||||
if (!nbt.contains("HasAttachments")) {
|
|
||||||
findAttachments(belt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (nbt.contains("AttachmentData")) {
|
|
||||||
ListNBT list = (ListNBT) nbt.get("AttachmentData");
|
|
||||||
for (INBT data : list) {
|
|
||||||
CompoundNBT stateNBT = (CompoundNBT) data;
|
|
||||||
BlockPos attachmentPos = NBTUtil.readBlockPos(stateNBT.getCompound("Position"));
|
|
||||||
BeltAttachmentState atState = addAttachment(belt.getWorld(), attachmentPos);
|
|
||||||
if (atState == null)
|
|
||||||
continue;
|
|
||||||
atState.processingDuration = stateNBT.getInt("Duration");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(CompoundNBT nbt) {
|
|
||||||
if (!attachments.isEmpty()) {
|
|
||||||
nbt.putBoolean("HasAttachments", true);
|
|
||||||
ListNBT list = new ListNBT();
|
|
||||||
forEachAttachment(atState -> {
|
|
||||||
CompoundNBT stateNBT = new CompoundNBT();
|
|
||||||
stateNBT.put("Position", NBTUtil.writeBlockPos(atState.attachmentPos));
|
|
||||||
stateNBT.putInt("Duration", atState.processingDuration);
|
|
||||||
list.add(stateNBT);
|
|
||||||
});
|
|
||||||
nbt.put("AttachmentData", list);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -210,9 +210,6 @@ public class BeltBlock extends HorizontalKineticBlock implements ITE<BeltTileEnt
|
||||||
@Override
|
@Override
|
||||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||||
updateNeighbouringTunnel(worldIn, pos, state);
|
updateNeighbouringTunnel(worldIn, pos, state);
|
||||||
withTileEntityDo(worldIn, pos, te -> {
|
|
||||||
te.attachmentTracker.findAttachments(te);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -109,7 +109,7 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
|
||||||
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
|
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
|
||||||
boolean slopeAlongX = te.getBeltFacing().getAxis() == Axis.X;
|
boolean slopeAlongX = te.getBeltFacing().getAxis() == Axis.X;
|
||||||
|
|
||||||
for (TransportedItemStack transported : te.getInventory().getItems()) {
|
for (TransportedItemStack transported : te.getInventory().getTransportedItems()) {
|
||||||
ms.push();
|
ms.push();
|
||||||
MatrixStacker.of(ms).nudge(transported.angle);
|
MatrixStacker.of(ms).nudge(transported.angle);
|
||||||
float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition);
|
float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition);
|
||||||
|
|
|
@ -15,13 +15,15 @@ import java.util.Map;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.AllBeltAttachments.Tracker;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Part;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Part;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Slope;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Slope;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltInventory;
|
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltInventory;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltMovementHandler;
|
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltMovementHandler;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltMovementHandler.TransportedEntityInfo;
|
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltMovementHandler.TransportedEntityInfo;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.transport.ItemHandlerBeltSegment;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
@ -46,7 +48,6 @@ import net.minecraftforge.items.IItemHandler;
|
||||||
public class BeltTileEntity extends KineticTileEntity {
|
public class BeltTileEntity extends KineticTileEntity {
|
||||||
|
|
||||||
public Map<Entity, TransportedEntityInfo> passengers;
|
public Map<Entity, TransportedEntityInfo> passengers;
|
||||||
public AllBeltAttachments.Tracker attachmentTracker;
|
|
||||||
public int color;
|
public int color;
|
||||||
public int beltLength;
|
public int beltLength;
|
||||||
public int index;
|
public int index;
|
||||||
|
@ -61,11 +62,18 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
public BeltTileEntity(TileEntityType<? extends BeltTileEntity> type) {
|
public BeltTileEntity(TileEntityType<? extends BeltTileEntity> type) {
|
||||||
super(type);
|
super(type);
|
||||||
controller = BlockPos.ZERO;
|
controller = BlockPos.ZERO;
|
||||||
attachmentTracker = new Tracker(this);
|
|
||||||
itemHandler = LazyOptional.empty();
|
itemHandler = LazyOptional.empty();
|
||||||
color = -1;
|
color = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||||
|
super.addBehaviours(behaviours);
|
||||||
|
behaviours.add(new DirectBeltInputBehaviour(this)
|
||||||
|
.onlyInsertWhen(d -> getSpeed() != 0 && getMovementFacing() != d.getOpposite())
|
||||||
|
.setInsertionHandler(this::tryInsertingFromSide));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
super.tick();
|
super.tick();
|
||||||
|
@ -75,12 +83,6 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
BeltBlock.initBelt(world, pos);
|
BeltBlock.initBelt(world, pos);
|
||||||
if (!AllBlocks.BELT.has(world.getBlockState(pos)))
|
if (!AllBlocks.BELT.has(world.getBlockState(pos)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Initialize Belt Attachments
|
|
||||||
if (world != null && trackerUpdateTag != null) {
|
|
||||||
attachmentTracker.readAndSearch(trackerUpdateTag, this);
|
|
||||||
trackerUpdateTag = null;
|
|
||||||
}
|
|
||||||
if (getSpeed() == 0)
|
if (getSpeed() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -136,7 +138,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
BeltInventory inventory = ((BeltTileEntity) te).getInventory();
|
BeltInventory inventory = ((BeltTileEntity) te).getInventory();
|
||||||
if (inventory == null)
|
if (inventory == null)
|
||||||
return;
|
return;
|
||||||
IItemHandler handler = inventory.createHandlerForSegment(index);
|
IItemHandler handler = new ItemHandlerBeltSegment(inventory, index);
|
||||||
itemHandler = LazyOptional.of(() -> handler);
|
itemHandler = LazyOptional.of(() -> handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,8 +165,6 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundNBT write(CompoundNBT compound) {
|
public CompoundNBT write(CompoundNBT compound) {
|
||||||
attachmentTracker.write(compound);
|
|
||||||
|
|
||||||
if (controller != null)
|
if (controller != null)
|
||||||
compound.put("Controller", NBTUtil.writeBlockPos(controller));
|
compound.put("Controller", NBTUtil.writeBlockPos(controller));
|
||||||
compound.putBoolean("IsController", isController());
|
compound.putBoolean("IsController", isController());
|
||||||
|
@ -246,7 +246,8 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getDirectionAwareBeltMovementSpeed() {
|
public float getDirectionAwareBeltMovementSpeed() {
|
||||||
int offset = getBeltFacing().getAxisDirection().getOffset();
|
int offset = getBeltFacing().getAxisDirection()
|
||||||
|
.getOffset();
|
||||||
if (getBeltFacing().getAxis() == Axis.X)
|
if (getBeltFacing().getAxis() == Axis.X)
|
||||||
offset *= -1;
|
offset *= -1;
|
||||||
return getBeltMovementSpeed() * offset;
|
return getBeltMovementSpeed() * offset;
|
||||||
|
@ -270,8 +271,8 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
if (part == MIDDLE)
|
if (part == MIDDLE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
boolean movingPositively =
|
boolean movingPositively = (getSpeed() > 0 == (direction.getAxisDirection()
|
||||||
(getSpeed() > 0 == (direction.getAxisDirection().getOffset() == 1)) ^ direction.getAxis() == Axis.X;
|
.getOffset() == 1)) ^ direction.getAxis() == Axis.X;
|
||||||
return part == Part.START ^ movingPositively;
|
return part == Part.START ^ movingPositively;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,8 +312,8 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
|
|
||||||
public Direction getMovementFacing() {
|
public Direction getMovementFacing() {
|
||||||
Axis axis = getBeltFacing().getAxis();
|
Axis axis = getBeltFacing().getAxis();
|
||||||
return Direction
|
return Direction.getFacingFromAxisDirection(axis,
|
||||||
.getFacingFromAxisDirection(axis, getBeltMovementSpeed() < 0 ^ axis == Axis.X ? NEGATIVE : POSITIVE);
|
getBeltMovementSpeed() < 0 ^ axis == Axis.X ? NEGATIVE : POSITIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Direction getBeltFacing() {
|
protected Direction getBeltFacing() {
|
||||||
|
@ -332,29 +333,39 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* always target a DirectBeltInsertionBehaviour
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public boolean tryInsertingFromSide(Direction side, ItemStack stack, boolean simulate) {
|
public boolean tryInsertingFromSide(Direction side, ItemStack stack, boolean simulate) {
|
||||||
return tryInsertingFromSide(side, new TransportedItemStack(stack), simulate);
|
return tryInsertingFromSide(new TransportedItemStack(stack), side, simulate).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean tryInsertingFromSide(Direction side, TransportedItemStack transportedStack, boolean simulate) {
|
private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) {
|
||||||
BeltTileEntity nextBeltController = getControllerTE();
|
BeltTileEntity nextBeltController = getControllerTE();
|
||||||
|
ItemStack inserted = transportedStack.stack;
|
||||||
|
ItemStack empty = ItemStack.EMPTY;
|
||||||
|
|
||||||
if (nextBeltController == null)
|
if (nextBeltController == null)
|
||||||
return false;
|
return inserted;
|
||||||
BeltInventory nextInventory = nextBeltController.getInventory();
|
BeltInventory nextInventory = nextBeltController.getInventory();
|
||||||
|
|
||||||
if (getSpeed() == 0)
|
if (getSpeed() == 0)
|
||||||
return false;
|
return inserted;
|
||||||
if (!nextInventory.canInsertFrom(index, side))
|
if (!nextInventory.canInsertAtFromSide(index, side))
|
||||||
return false;
|
return inserted;
|
||||||
if (simulate)
|
if (simulate)
|
||||||
return true;
|
return empty;
|
||||||
|
|
||||||
|
transportedStack = transportedStack.copy();
|
||||||
transportedStack.beltPosition = index + .5f - Math.signum(getDirectionAwareBeltMovementSpeed()) / 16f;
|
transportedStack.beltPosition = index + .5f - Math.signum(getDirectionAwareBeltMovementSpeed()) / 16f;
|
||||||
|
|
||||||
Direction movementFacing = getMovementFacing();
|
Direction movementFacing = getMovementFacing();
|
||||||
if (!side.getAxis().isVertical()) {
|
if (!side.getAxis()
|
||||||
|
.isVertical()) {
|
||||||
if (movementFacing != side) {
|
if (movementFacing != side) {
|
||||||
transportedStack.sideOffset = side.getAxisDirection().getOffset() * .35f;
|
transportedStack.sideOffset = side.getAxisDirection()
|
||||||
|
.getOffset() * .35f;
|
||||||
if (side.getAxis() == Axis.X)
|
if (side.getAxis() == Axis.X)
|
||||||
transportedStack.sideOffset *= -1;
|
transportedStack.sideOffset *= -1;
|
||||||
} else
|
} else
|
||||||
|
@ -368,8 +379,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
||||||
nextInventory.addItem(transportedStack);
|
nextInventory.addItem(transportedStack);
|
||||||
nextBeltController.markDirty();
|
nextBeltController.markDirty();
|
||||||
nextBeltController.sendData();
|
nextBeltController.sendData();
|
||||||
|
return empty;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.simibubi.create.content.contraptions.relays.belt.transport;
|
package com.simibubi.create.content.contraptions.relays.belt.transport;
|
||||||
|
|
||||||
|
import static com.simibubi.create.content.contraptions.relays.belt.transport.BeltTunnelInteractionHandler.flapTunnel;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -8,32 +10,26 @@ import java.util.List;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Slope;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Slope;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
||||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity;
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.BeltProcessingBehaviour.ProcessingResult;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.nbt.ListNBT;
|
import net.minecraft.nbt.ListNBT;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.common.util.Constants.NBT;
|
import net.minecraftforge.common.util.Constants.NBT;
|
||||||
import net.minecraftforge.common.util.LazyOptional;
|
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
|
||||||
import net.minecraftforge.items.ItemHandlerHelper;
|
|
||||||
|
|
||||||
public class BeltInventory {
|
public class BeltInventory {
|
||||||
|
|
||||||
|
@ -52,9 +48,9 @@ public class BeltInventory {
|
||||||
public void tick() {
|
public void tick() {
|
||||||
|
|
||||||
// Reverse item collection if belt just reversed
|
// Reverse item collection if belt just reversed
|
||||||
if (beltMovementPositive != movingPositive()) {
|
if (beltMovementPositive != belt.getDirectionAwareBeltMovementSpeed() > 0) {
|
||||||
beltMovementPositive = movingPositive();
|
beltMovementPositive = !beltMovementPositive;
|
||||||
Collections.reverse(getItems());
|
Collections.reverse(items);
|
||||||
belt.markDirty();
|
belt.markDirty();
|
||||||
belt.sendData();
|
belt.sendData();
|
||||||
}
|
}
|
||||||
|
@ -69,23 +65,31 @@ public class BeltInventory {
|
||||||
|
|
||||||
// Assuming the first entry is furthest on the belt
|
// Assuming the first entry is furthest on the belt
|
||||||
TransportedItemStack stackInFront = null;
|
TransportedItemStack stackInFront = null;
|
||||||
TransportedItemStack current = null;
|
TransportedItemStack currentItem = null;
|
||||||
Iterator<TransportedItemStack> iterator = getItems().iterator();
|
Iterator<TransportedItemStack> iterator = items.iterator();
|
||||||
|
|
||||||
|
// Useful stuff
|
||||||
float beltSpeed = belt.getDirectionAwareBeltMovementSpeed();
|
float beltSpeed = belt.getDirectionAwareBeltMovementSpeed();
|
||||||
Direction movementFacing = belt.getMovementFacing();
|
Direction movementFacing = belt.getMovementFacing();
|
||||||
|
boolean horizontal = belt.getBlockState()
|
||||||
|
.get(BeltBlock.SLOPE) == Slope.HORIZONTAL;
|
||||||
float spacing = 1;
|
float spacing = 1;
|
||||||
boolean onClient = belt.getWorld().isRemote;
|
World world = belt.getWorld();
|
||||||
|
boolean onClient = world.isRemote;
|
||||||
|
|
||||||
Items: while (iterator.hasNext()) {
|
// resolve ending only when items will reach it this tick
|
||||||
stackInFront = current;
|
Ending ending = Ending.UNRESOLVED;
|
||||||
current = iterator.next();
|
|
||||||
current.prevBeltPosition = current.beltPosition;
|
|
||||||
current.prevSideOffset = current.sideOffset;
|
|
||||||
|
|
||||||
if (current.stack.isEmpty()) {
|
// Loop over items
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
stackInFront = currentItem;
|
||||||
|
currentItem = iterator.next();
|
||||||
|
currentItem.prevBeltPosition = currentItem.beltPosition;
|
||||||
|
currentItem.prevSideOffset = currentItem.sideOffset;
|
||||||
|
|
||||||
|
if (currentItem.stack.isEmpty()) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
current = null;
|
currentItem = null;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,12 +97,12 @@ public class BeltInventory {
|
||||||
if (onClient)
|
if (onClient)
|
||||||
movement *= ServerSpeedProvider.get();
|
movement *= ServerSpeedProvider.get();
|
||||||
|
|
||||||
// Don't move if locked
|
// Don't move if held by processing (client)
|
||||||
if (onClient && current.locked)
|
if (onClient && currentItem.locked)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Don't move if other items are waiting in front
|
// Don't move if other items are waiting in front
|
||||||
float currentPos = current.beltPosition;
|
float currentPos = currentItem.beltPosition;
|
||||||
if (stackInFront != null) {
|
if (stackInFront != null) {
|
||||||
float diff = stackInFront.beltPosition - currentPos;
|
float diff = stackInFront.beltPosition - currentPos;
|
||||||
if (Math.abs(diff) <= spacing)
|
if (Math.abs(diff) <= spacing)
|
||||||
|
@ -107,236 +111,182 @@ public class BeltInventory {
|
||||||
beltMovementPositive ? Math.min(movement, diff - spacing) : Math.max(movement, diff + spacing);
|
beltMovementPositive ? Math.min(movement, diff - spacing) : Math.max(movement, diff + spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine current segment
|
|
||||||
int segmentBefore = (int) currentPos;
|
|
||||||
float min = segmentBefore + .5f - (SEGMENT_WINDOW / 2);
|
|
||||||
float max = segmentBefore + .5f + (SEGMENT_WINDOW / 2);
|
|
||||||
if (currentPos < min || currentPos > max)
|
|
||||||
segmentBefore = -1;
|
|
||||||
|
|
||||||
// Don't move beyond the edge
|
// Don't move beyond the edge
|
||||||
float diffToEnd = beltMovementPositive ? belt.beltLength - currentPos : -currentPos;
|
float diffToEnd = beltMovementPositive ? belt.beltLength - currentPos : -currentPos;
|
||||||
|
if (Math.abs(diffToEnd) < Math.abs(movement) + 1) {
|
||||||
|
if (ending == Ending.UNRESOLVED)
|
||||||
|
ending = resolveEnding();
|
||||||
|
diffToEnd += beltMovementPositive ? -ending.margin : ending.margin;
|
||||||
|
}
|
||||||
float limitedMovement =
|
float limitedMovement =
|
||||||
beltMovementPositive ? Math.min(movement, diffToEnd) : Math.max(movement, diffToEnd);
|
beltMovementPositive ? Math.min(movement, diffToEnd) : Math.max(movement, diffToEnd);
|
||||||
float nextOffset = current.beltPosition + limitedMovement;
|
float nextOffset = currentItem.beltPosition + limitedMovement;
|
||||||
|
|
||||||
if (!onClient && segmentBefore != -1) {
|
// Belt item processing
|
||||||
// Don't move if belt attachments want to continue processing
|
if (!onClient && horizontal) {
|
||||||
if (current.locked) {
|
ItemStack item = currentItem.stack;
|
||||||
BeltTileEntity beltSegment = BeltHelper.getBeltAtSegment(belt, segmentBefore);
|
if (handleBeltProcessingAndCheckIfRemoved(currentItem, nextOffset)) {
|
||||||
if (beltSegment != null) {
|
iterator.remove();
|
||||||
|
|
||||||
// wait in case belt isnt initialized yet
|
|
||||||
if (current.locked && beltSegment.trackerUpdateTag != null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
current.locked = false;
|
|
||||||
List<BeltAttachmentState> attachments = beltSegment.attachmentTracker.attachments;
|
|
||||||
for (BeltAttachmentState attachmentState : attachments) {
|
|
||||||
if (attachmentState.attachment.processItem(beltSegment, current, attachmentState))
|
|
||||||
current.locked = true;
|
|
||||||
}
|
|
||||||
if (!current.locked || current.stack.isEmpty()) {
|
|
||||||
if (!attachments.isEmpty())
|
|
||||||
attachments.add(attachments.remove(0));
|
|
||||||
belt.sendData();
|
belt.sendData();
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (item != currentItem.stack)
|
||||||
|
belt.sendData();
|
||||||
|
if (currentItem.locked)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Belt Tunnels
|
||||||
|
BeltTunnelInteractionHandler.flapTunnelsAndCheckIfStuck(this, currentItem, nextOffset);
|
||||||
|
|
||||||
|
// Apply Movement
|
||||||
|
currentItem.beltPosition += limitedMovement;
|
||||||
|
currentItem.sideOffset +=
|
||||||
|
(currentItem.getTargetSideOffset() - currentItem.sideOffset) * Math.abs(limitedMovement) * 2f;
|
||||||
|
currentPos = currentItem.beltPosition;
|
||||||
|
|
||||||
|
// Movement successful
|
||||||
|
if (limitedMovement == movement || onClient)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// End reached
|
||||||
|
int lastOffset = beltMovementPositive ? belt.beltLength - 1 : 0;
|
||||||
|
BlockPos nextPosition = BeltHelper.getPositionForOffset(belt, beltMovementPositive ? belt.beltLength : -1);
|
||||||
|
|
||||||
|
if (ending == Ending.FUNNEL) {
|
||||||
|
// TODO
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ending == Ending.INSERT) {
|
||||||
|
DirectBeltInputBehaviour inputBehaviour =
|
||||||
|
TileEntityBehaviour.get(world, nextPosition, DirectBeltInputBehaviour.TYPE);
|
||||||
|
if (inputBehaviour == null)
|
||||||
|
continue;
|
||||||
|
if (!inputBehaviour.canInsertFromSide(movementFacing))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ItemStack remainder = inputBehaviour.handleInsertion(currentItem, movementFacing, false);
|
||||||
|
if (remainder.equals(currentItem.stack, false))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
currentItem.stack = remainder;
|
||||||
|
if (remainder.isEmpty())
|
||||||
|
iterator.remove();
|
||||||
|
|
||||||
|
flapTunnel(this, lastOffset, movementFacing, false);
|
||||||
|
belt.sendData();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ending == Ending.BLOCKED)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ending == Ending.EJECT) {
|
||||||
|
eject(currentItem);
|
||||||
|
iterator.remove();
|
||||||
|
flapTunnel(this, lastOffset, movementFacing, false);
|
||||||
|
belt.sendData();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean handleBeltProcessingAndCheckIfRemoved(TransportedItemStack currentItem, float nextOffset) {
|
||||||
|
int currentSegment = (int) currentItem.beltPosition;
|
||||||
|
|
||||||
|
// Continue processing if held
|
||||||
|
if (currentItem.locked) {
|
||||||
|
BeltProcessingBehaviour processingBehaviour = getBeltProcessingAtSegment(currentSegment);
|
||||||
|
|
||||||
|
if (processingBehaviour == null) {
|
||||||
|
currentItem.locked = false;
|
||||||
|
belt.sendData();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessingResult result = processingBehaviour.handleHeldItem(currentItem, this);
|
||||||
|
if (result == ProcessingResult.REMOVE)
|
||||||
|
return true;
|
||||||
|
if (result == ProcessingResult.HOLD)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
currentItem.locked = false;
|
||||||
|
belt.sendData();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if any new belt processing catches the item
|
// See if any new belt processing catches the item
|
||||||
if (current.beltPosition > .5f || beltMovementPositive) {
|
if (currentItem.beltPosition > .5f || beltMovementPositive) {
|
||||||
int firstUpcomingSegment = (int) (current.beltPosition + (beltMovementPositive ? .5f : -.5f));
|
int firstUpcomingSegment = (int) (currentItem.beltPosition + (beltMovementPositive ? .5f : -.5f));
|
||||||
|
int step = beltMovementPositive ? 1 : -1;
|
||||||
|
|
||||||
for (int segment = firstUpcomingSegment; beltMovementPositive ? segment + .5f <= nextOffset
|
for (int segment = firstUpcomingSegment; beltMovementPositive ? segment + .5f <= nextOffset
|
||||||
: segment + .5f >= nextOffset; segment += beltMovementPositive ? 1 : -1) {
|
: segment + .5f >= nextOffset; segment += step) {
|
||||||
BeltTileEntity beltSegment = BeltHelper.getBeltAtSegment(belt, segment);
|
|
||||||
if (beltSegment == null)
|
BeltProcessingBehaviour processingBehaviour = getBeltProcessingAtSegment(segment);
|
||||||
break;
|
if (processingBehaviour == null)
|
||||||
for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) {
|
continue;
|
||||||
ItemStack stackBefore = current.stack.copy();
|
|
||||||
if (attachmentState.attachment.startProcessingItem(beltSegment, current, attachmentState)) {
|
ProcessingResult result = processingBehaviour.handleReceivedItem(currentItem, this);
|
||||||
current.beltPosition = segment + .5f + (beltMovementPositive ? 1 / 64f : -1 / 64f);
|
if (result == ProcessingResult.REMOVE)
|
||||||
current.locked = true;
|
return true;
|
||||||
|
|
||||||
|
if (result == ProcessingResult.HOLD) {
|
||||||
|
currentItem.beltPosition = segment + .5f + (beltMovementPositive ? 1 / 64f : -1 / 64f);
|
||||||
|
currentItem.locked = true;
|
||||||
belt.sendData();
|
belt.sendData();
|
||||||
continue Items;
|
return false;
|
||||||
}
|
|
||||||
if (!stackBefore.equals(current.stack, true))
|
|
||||||
belt.sendData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Belt tunnels
|
|
||||||
{
|
|
||||||
int seg1 = (int) current.beltPosition;
|
|
||||||
int seg2 = (int) nextOffset;
|
|
||||||
if (!beltMovementPositive && nextOffset == 0)
|
|
||||||
seg2 = -1;
|
|
||||||
if (seg1 != seg2) {
|
|
||||||
if (stuckAtTunnel(seg2, current.stack, movementFacing)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!onClient) {
|
|
||||||
flapTunnel(seg1, movementFacing, false);
|
|
||||||
flapTunnel(seg2, movementFacing.getOpposite(), true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply Movement
|
return false;
|
||||||
current.beltPosition += limitedMovement;
|
}
|
||||||
current.sideOffset += (current.getTargetSideOffset() - current.sideOffset) * Math.abs(limitedMovement) * 2f;
|
|
||||||
currentPos = current.beltPosition;
|
|
||||||
|
|
||||||
// Determine segment after movement
|
protected BeltProcessingBehaviour getBeltProcessingAtSegment(int segment) {
|
||||||
int segmentAfter = (int) currentPos;
|
return TileEntityBehaviour.get(belt.getWorld(), BeltHelper.getPositionForOffset(belt, segment)
|
||||||
min = segmentAfter + .5f - (SEGMENT_WINDOW / 2);
|
.up(2), BeltProcessingBehaviour.TYPE);
|
||||||
max = segmentAfter + .5f + (SEGMENT_WINDOW / 2);
|
}
|
||||||
if (currentPos < min || currentPos > max)
|
|
||||||
segmentAfter = -1;
|
|
||||||
|
|
||||||
// Item changed segments
|
private enum Ending {
|
||||||
World world = belt.getWorld();
|
UNRESOLVED(0), EJECT(0), INSERT(.25f), FUNNEL(.35f), BLOCKED(.45f);
|
||||||
if (segmentBefore != segmentAfter) {
|
|
||||||
for (int segment : new int[] { segmentBefore, segmentAfter }) {
|
private float margin;
|
||||||
if (segment == -1)
|
|
||||||
continue;
|
Ending(float f) {
|
||||||
if (!world.isRemote)
|
this.margin = f;
|
||||||
world
|
|
||||||
.updateComparatorOutputLevel(BeltHelper.getPositionForOffset(belt, segment),
|
|
||||||
belt.getBlockState().getBlock());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// End reached
|
private Ending resolveEnding() {
|
||||||
if (limitedMovement != movement) {
|
|
||||||
if (world.isRemote)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int lastOffset = beltMovementPositive ? belt.beltLength - 1 : 0;
|
int lastOffset = beltMovementPositive ? belt.beltLength - 1 : 0;
|
||||||
BlockPos nextPosition =
|
World world = belt.getWorld();
|
||||||
BeltHelper.getPositionForOffset(belt, beltMovementPositive ? belt.beltLength : -1);
|
BlockPos lastPosition = BeltHelper.getPositionForOffset(belt, lastOffset);
|
||||||
BlockState state = world.getBlockState(nextPosition);
|
BlockPos nextPosition = BeltHelper.getPositionForOffset(belt, beltMovementPositive ? belt.beltLength : -1);
|
||||||
|
|
||||||
// next block is a basin or a saw
|
if (AllBlocks.BELT_FUNNEL.has(world.getBlockState(lastPosition.up())))
|
||||||
if (AllBlocks.BASIN.has(state) || AllBlocks.MECHANICAL_SAW.has(state)
|
return Ending.FUNNEL;
|
||||||
|| AllBlocks.CRUSHING_WHEEL_CONTROLLER.has(state)) {
|
|
||||||
TileEntity te = world.getTileEntity(nextPosition);
|
|
||||||
if (te != null) {
|
|
||||||
LazyOptional<IItemHandler> optional =
|
|
||||||
te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, Direction.UP);
|
|
||||||
if (optional.isPresent()) {
|
|
||||||
IItemHandler itemHandler = optional.orElse(null);
|
|
||||||
ItemStack remainder =
|
|
||||||
ItemHandlerHelper.insertItemStacked(itemHandler, current.stack.copy(), false);
|
|
||||||
if (remainder.equals(current.stack, false))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
current.stack = remainder;
|
DirectBeltInputBehaviour inputBehaviour =
|
||||||
if (remainder.isEmpty()) {
|
TileEntityBehaviour.get(world, nextPosition, DirectBeltInputBehaviour.TYPE);
|
||||||
iterator.remove();
|
if (inputBehaviour != null)
|
||||||
current = null;
|
return Ending.INSERT;
|
||||||
flapTunnel(lastOffset, movementFacing, false);
|
|
||||||
|
if (Block.hasSolidSide(world.getBlockState(nextPosition), world, nextPosition, belt.getMovementFacing()
|
||||||
|
.getOpposite()))
|
||||||
|
return Ending.BLOCKED;
|
||||||
|
|
||||||
|
return Ending.EJECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
belt.sendData();
|
//
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// next block is not a belt
|
|
||||||
if (!AllBlocks.BELT.has(state) || state.get(BeltBlock.SLOPE) == Slope.VERTICAL) {
|
|
||||||
if (!Block.hasSolidSide(state, world, nextPosition, movementFacing.getOpposite())) {
|
|
||||||
eject(current);
|
|
||||||
iterator.remove();
|
|
||||||
current = null;
|
|
||||||
flapTunnel(lastOffset, movementFacing, false);
|
|
||||||
belt.sendData();
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next block is a belt
|
|
||||||
TileEntity te = world.getTileEntity(nextPosition);
|
|
||||||
if (te == null || !(te instanceof BeltTileEntity))
|
|
||||||
continue;
|
|
||||||
BeltTileEntity nextBelt = (BeltTileEntity) te;
|
|
||||||
Direction nextMovementFacing = nextBelt.getMovementFacing();
|
|
||||||
|
|
||||||
// next belt goes the opposite way
|
|
||||||
if (nextMovementFacing == movementFacing.getOpposite())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Inserting into other belt
|
|
||||||
if (nextBelt.tryInsertingFromSide(movementFacing, current, false)) {
|
|
||||||
iterator.remove();
|
|
||||||
current = null;
|
|
||||||
flapTunnel(lastOffset, movementFacing, false);
|
|
||||||
belt.sendData();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean stuckAtTunnel(int offset, ItemStack stack, Direction movementDirection) {
|
|
||||||
BlockPos pos = BeltHelper.getPositionForOffset(belt, offset).up();
|
|
||||||
if (!AllBlocks.BELT_TUNNEL.has(belt.getWorld().getBlockState(pos)))
|
|
||||||
return false;
|
|
||||||
TileEntity te = belt.getWorld().getTileEntity(pos);
|
|
||||||
if (te == null || !(te instanceof BeltTunnelTileEntity))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Direction flapFacing = movementDirection.getOpposite();
|
|
||||||
|
|
||||||
BeltTunnelTileEntity tunnel = (BeltTunnelTileEntity) te;
|
|
||||||
if (!tunnel.flaps.containsKey(flapFacing))
|
|
||||||
return false;
|
|
||||||
if (!tunnel.syncedFlaps.containsKey(flapFacing))
|
|
||||||
return false;
|
|
||||||
ItemStack heldItem = tunnel.syncedFlaps.get(flapFacing);
|
|
||||||
if (heldItem == null) {
|
|
||||||
tunnel.syncedFlaps.put(flapFacing, ItemStack.EMPTY);
|
|
||||||
belt.sendData();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (heldItem == ItemStack.EMPTY) {
|
|
||||||
tunnel.syncedFlaps.put(flapFacing, stack);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<BeltTunnelTileEntity> group = BeltTunnelBlock.getSynchronizedGroup(belt.getWorld(), pos, flapFacing);
|
|
||||||
for (BeltTunnelTileEntity otherTunnel : group)
|
|
||||||
if (otherTunnel.syncedFlaps.get(flapFacing) == ItemStack.EMPTY)
|
|
||||||
return true;
|
|
||||||
for (BeltTunnelTileEntity otherTunnel : group)
|
|
||||||
otherTunnel.syncedFlaps.put(flapFacing, null);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void flapTunnel(int offset, Direction side, boolean inward) {
|
|
||||||
if (belt.getBlockState().get(BeltBlock.SLOPE) != Slope.HORIZONTAL)
|
|
||||||
return;
|
|
||||||
BlockPos pos = BeltHelper.getPositionForOffset(belt, offset).up();
|
|
||||||
if (!AllBlocks.BELT_TUNNEL.has(belt.getWorld().getBlockState(pos)))
|
|
||||||
return;
|
|
||||||
TileEntity te = belt.getWorld().getTileEntity(pos);
|
|
||||||
if (te == null || !(te instanceof BeltTunnelTileEntity))
|
|
||||||
return;
|
|
||||||
((BeltTunnelTileEntity) te).flap(side, inward ^ side.getAxis() == Axis.Z);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canInsertAt(int segment) {
|
public boolean canInsertAt(int segment) {
|
||||||
return canInsertFrom(segment, Direction.UP);
|
return canInsertAtFromSide(segment, Direction.UP);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canInsertFrom(int segment, Direction side) {
|
public boolean canInsertAtFromSide(int segment, Direction side) {
|
||||||
float segmentPos = segment;
|
float segmentPos = segment;
|
||||||
if (belt.getMovementFacing() == side.getOpposite())
|
if (belt.getMovementFacing() == side.getOpposite())
|
||||||
return false;
|
return false;
|
||||||
|
@ -345,7 +295,7 @@ public class BeltInventory {
|
||||||
else if (!beltMovementPositive)
|
else if (!beltMovementPositive)
|
||||||
segmentPos += 1f;
|
segmentPos += 1f;
|
||||||
|
|
||||||
for (TransportedItemStack stack : getItems())
|
for (TransportedItemStack stack : items)
|
||||||
if (isBlocking(segment, side, segmentPos, stack))
|
if (isBlocking(segment, side, segmentPos, stack))
|
||||||
return false;
|
return false;
|
||||||
for (TransportedItemStack stack : toInsert)
|
for (TransportedItemStack stack : toInsert)
|
||||||
|
@ -368,23 +318,23 @@ public class BeltInventory {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void insert(TransportedItemStack newStack) {
|
private void insert(TransportedItemStack newStack) {
|
||||||
if (getItems().isEmpty())
|
if (items.isEmpty())
|
||||||
getItems().add(newStack);
|
items.add(newStack);
|
||||||
else {
|
else {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (TransportedItemStack stack : getItems()) {
|
for (TransportedItemStack stack : items) {
|
||||||
if (stack.compareTo(newStack) > 0 == beltMovementPositive)
|
if (stack.compareTo(newStack) > 0 == beltMovementPositive)
|
||||||
break;
|
break;
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
getItems().add(index, newStack);
|
items.add(index, newStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransportedItemStack getStackAtOffset(int offset) {
|
public TransportedItemStack getStackAtOffset(int offset) {
|
||||||
float min = offset + .5f - (SEGMENT_WINDOW / 2);
|
float min = offset + .5f - (SEGMENT_WINDOW / 2);
|
||||||
float max = offset + .5f + (SEGMENT_WINDOW / 2);
|
float max = offset + .5f + (SEGMENT_WINDOW / 2);
|
||||||
for (TransportedItemStack stack : getItems()) {
|
for (TransportedItemStack stack : items) {
|
||||||
if (stack.beltPosition > max)
|
if (stack.beltPosition > max)
|
||||||
continue;
|
continue;
|
||||||
if (stack.beltPosition > min)
|
if (stack.beltPosition > min)
|
||||||
|
@ -394,17 +344,16 @@ public class BeltInventory {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void read(CompoundNBT nbt) {
|
public void read(CompoundNBT nbt) {
|
||||||
getItems().clear();
|
items.clear();
|
||||||
nbt
|
nbt.getList("Items", NBT.TAG_COMPOUND)
|
||||||
.getList("Items", NBT.TAG_COMPOUND)
|
.forEach(inbt -> items.add(TransportedItemStack.read((CompoundNBT) inbt)));
|
||||||
.forEach(inbt -> getItems().add(TransportedItemStack.read((CompoundNBT) inbt)));
|
|
||||||
beltMovementPositive = nbt.getBoolean("PositiveOrder");
|
beltMovementPositive = nbt.getBoolean("PositiveOrder");
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompoundNBT write() {
|
public CompoundNBT write() {
|
||||||
CompoundNBT nbt = new CompoundNBT();
|
CompoundNBT nbt = new CompoundNBT();
|
||||||
ListNBT itemsNBT = new ListNBT();
|
ListNBT itemsNBT = new ListNBT();
|
||||||
getItems().forEach(stack -> itemsNBT.add(stack.serializeNBT()));
|
items.forEach(stack -> itemsNBT.add(stack.serializeNBT()));
|
||||||
nbt.put("Items", itemsNBT);
|
nbt.put("Items", itemsNBT);
|
||||||
nbt.putBoolean("PositiveOrder", beltMovementPositive);
|
nbt.putBoolean("PositiveOrder", beltMovementPositive);
|
||||||
return nbt;
|
return nbt;
|
||||||
|
@ -414,33 +363,27 @@ public class BeltInventory {
|
||||||
ItemStack ejected = stack.stack;
|
ItemStack ejected = stack.stack;
|
||||||
Vec3d outPos = BeltHelper.getVectorForOffset(belt, stack.beltPosition);
|
Vec3d outPos = BeltHelper.getVectorForOffset(belt, stack.beltPosition);
|
||||||
float movementSpeed = Math.max(Math.abs(belt.getBeltMovementSpeed()), 1 / 8f);
|
float movementSpeed = Math.max(Math.abs(belt.getBeltMovementSpeed()), 1 / 8f);
|
||||||
Vec3d outMotion = new Vec3d(belt.getBeltChainDirection()).scale(movementSpeed).add(0, 1 / 8f, 0);
|
Vec3d outMotion = new Vec3d(belt.getBeltChainDirection()).scale(movementSpeed)
|
||||||
|
.add(0, 1 / 8f, 0);
|
||||||
outPos.add(outMotion.normalize());
|
outPos.add(outMotion.normalize());
|
||||||
ItemEntity entity = new ItemEntity(belt.getWorld(), outPos.x, outPos.y + 6 / 16f, outPos.z, ejected);
|
ItemEntity entity = new ItemEntity(belt.getWorld(), outPos.x, outPos.y + 6 / 16f, outPos.z, ejected);
|
||||||
entity.setMotion(outMotion);
|
entity.setMotion(outMotion);
|
||||||
entity.setDefaultPickupDelay();
|
entity.setDefaultPickupDelay();
|
||||||
entity.velocityChanged = true;
|
entity.velocityChanged = true;
|
||||||
belt.getWorld().addEntity(entity);
|
belt.getWorld()
|
||||||
|
.addEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ejectAll() {
|
public void ejectAll() {
|
||||||
getItems().forEach(this::eject);
|
items.forEach(this::eject);
|
||||||
getItems().clear();
|
items.clear();
|
||||||
}
|
|
||||||
|
|
||||||
private boolean movingPositive() {
|
|
||||||
return belt.getDirectionAwareBeltMovementSpeed() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IItemHandler createHandlerForSegment(int segment) {
|
|
||||||
return new ItemHandlerBeltSegment(this, segment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void forEachWithin(float position, float distance,
|
public void forEachWithin(float position, float distance,
|
||||||
Function<TransportedItemStack, List<TransportedItemStack>> callback) {
|
Function<TransportedItemStack, List<TransportedItemStack>> callback) {
|
||||||
List<TransportedItemStack> toBeAdded = new ArrayList<>();
|
List<TransportedItemStack> toBeAdded = new ArrayList<>();
|
||||||
boolean dirty = false;
|
boolean dirty = false;
|
||||||
for (Iterator<TransportedItemStack> iterator = getItems().iterator(); iterator.hasNext();) {
|
for (Iterator<TransportedItemStack> iterator = items.iterator(); iterator.hasNext();) {
|
||||||
TransportedItemStack transportedItemStack = iterator.next();
|
TransportedItemStack transportedItemStack = iterator.next();
|
||||||
if (Math.abs(position - transportedItemStack.beltPosition) < distance) {
|
if (Math.abs(position - transportedItemStack.beltPosition) < distance) {
|
||||||
List<TransportedItemStack> apply = callback.apply(transportedItemStack);
|
List<TransportedItemStack> apply = callback.apply(transportedItemStack);
|
||||||
|
@ -458,7 +401,7 @@ public class BeltInventory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<TransportedItemStack> getItems() {
|
public List<TransportedItemStack> getTransportedItems() {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ import java.util.List;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionEntity;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Part;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Part;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Slope;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Slope;
|
||||||
|
@ -99,16 +98,6 @@ public class BeltMovementHandler {
|
||||||
((LivingEntity) entityIn).addPotionEffect(new EffectInstance(Effects.SLOWNESS, 10, 1, false, false));
|
((LivingEntity) entityIn).addPotionEffect(new EffectInstance(Effects.SLOWNESS, 10, 1, false, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
BeltTileEntity belt = (BeltTileEntity) te;
|
|
||||||
|
|
||||||
// Attachment pauses movement
|
|
||||||
for (BeltAttachmentState state : belt.attachmentTracker.attachments) {
|
|
||||||
if (state.attachment.processEntity(belt, entityIn, state)) {
|
|
||||||
info.ticksSinceLastCollision--;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final Direction beltFacing = blockState.get(BlockStateProperties.HORIZONTAL_FACING);
|
final Direction beltFacing = blockState.get(BlockStateProperties.HORIZONTAL_FACING);
|
||||||
final Slope slope = blockState.get(BeltBlock.SLOPE);
|
final Slope slope = blockState.get(BeltBlock.SLOPE);
|
||||||
final Axis axis = beltFacing.getAxis();
|
final Axis axis = beltFacing.getAxis();
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package com.simibubi.create.content.contraptions.relays.belt.transport;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllBlocks;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Slope;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
||||||
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelBlock;
|
||||||
|
import com.simibubi.create.content.logistics.block.belts.tunnel.BeltTunnelTileEntity;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
public class BeltTunnelInteractionHandler {
|
||||||
|
|
||||||
|
public static boolean flapTunnelsAndCheckIfStuck(BeltInventory beltInventory, TransportedItemStack current,
|
||||||
|
float nextOffset) {
|
||||||
|
|
||||||
|
int currentSegment = (int) current.beltPosition;
|
||||||
|
int upcomingSegment = (int) nextOffset;
|
||||||
|
|
||||||
|
Direction movementFacing = beltInventory.belt.getMovementFacing();
|
||||||
|
if (!beltInventory.beltMovementPositive && nextOffset == 0)
|
||||||
|
upcomingSegment = -1;
|
||||||
|
if (currentSegment != upcomingSegment) {
|
||||||
|
if (stuckAtTunnel(beltInventory, upcomingSegment, current.stack, movementFacing))
|
||||||
|
return true;
|
||||||
|
if (!beltInventory.belt.getWorld().isRemote) {
|
||||||
|
flapTunnel(beltInventory, currentSegment, movementFacing, false);
|
||||||
|
flapTunnel(beltInventory, upcomingSegment, movementFacing.getOpposite(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean stuckAtTunnel(BeltInventory beltInventory, int offset, ItemStack stack,
|
||||||
|
Direction movementDirection) {
|
||||||
|
BeltTileEntity belt = beltInventory.belt;
|
||||||
|
BlockPos pos = BeltHelper.getPositionForOffset(belt, offset)
|
||||||
|
.up();
|
||||||
|
if (!AllBlocks.BELT_TUNNEL.has(belt.getWorld()
|
||||||
|
.getBlockState(pos)))
|
||||||
|
return false;
|
||||||
|
TileEntity te = belt.getWorld()
|
||||||
|
.getTileEntity(pos);
|
||||||
|
if (te == null || !(te instanceof BeltTunnelTileEntity))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Direction flapFacing = movementDirection.getOpposite();
|
||||||
|
|
||||||
|
BeltTunnelTileEntity tunnel = (BeltTunnelTileEntity) te;
|
||||||
|
if (!tunnel.flaps.containsKey(flapFacing))
|
||||||
|
return false;
|
||||||
|
if (!tunnel.syncedFlaps.containsKey(flapFacing))
|
||||||
|
return false;
|
||||||
|
ItemStack heldItem = tunnel.syncedFlaps.get(flapFacing);
|
||||||
|
if (heldItem == null) {
|
||||||
|
tunnel.syncedFlaps.put(flapFacing, ItemStack.EMPTY);
|
||||||
|
belt.sendData();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (heldItem == ItemStack.EMPTY) {
|
||||||
|
tunnel.syncedFlaps.put(flapFacing, stack);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<BeltTunnelTileEntity> group = BeltTunnelBlock.getSynchronizedGroup(belt.getWorld(), pos, flapFacing);
|
||||||
|
for (BeltTunnelTileEntity otherTunnel : group)
|
||||||
|
if (otherTunnel.syncedFlaps.get(flapFacing) == ItemStack.EMPTY)
|
||||||
|
return true;
|
||||||
|
for (BeltTunnelTileEntity otherTunnel : group)
|
||||||
|
otherTunnel.syncedFlaps.put(flapFacing, null);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void flapTunnel(BeltInventory beltInventory, int offset, Direction side, boolean inward) {
|
||||||
|
BeltTileEntity belt = beltInventory.belt;
|
||||||
|
if (belt.getBlockState()
|
||||||
|
.get(BeltBlock.SLOPE) != Slope.HORIZONTAL)
|
||||||
|
return;
|
||||||
|
BlockPos pos = BeltHelper.getPositionForOffset(belt, offset)
|
||||||
|
.up();
|
||||||
|
if (!AllBlocks.BELT_TUNNEL.has(belt.getWorld()
|
||||||
|
.getBlockState(pos)))
|
||||||
|
return;
|
||||||
|
TileEntity te = belt.getWorld()
|
||||||
|
.getTileEntity(pos);
|
||||||
|
if (te == null || !(te instanceof BeltTunnelTileEntity))
|
||||||
|
return;
|
||||||
|
((BeltTunnelTileEntity) te).flap(side, inward ^ side.getAxis() == Axis.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,93 +1,25 @@
|
||||||
package com.simibubi.create.content.logistics.block.belts;
|
package com.simibubi.create.content.logistics.block.belts;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
|
||||||
import com.simibubi.create.content.logistics.block.AttachedLogisticalBlock;
|
import com.simibubi.create.content.logistics.block.AttachedLogisticalBlock;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.SingleTargetAutoExtractingBehaviour;
|
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.util.Direction;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.world.IWorld;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public abstract class BeltAttachableLogisticalBlock extends AttachedLogisticalBlock implements IBeltAttachment {
|
public abstract class BeltAttachableLogisticalBlock extends AttachedLogisticalBlock {
|
||||||
|
|
||||||
public BeltAttachableLogisticalBlock(Properties properties) {
|
public BeltAttachableLogisticalBlock(Properties properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
|
||||||
onAttachmentPlaced(worldIn, pos, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||||
onAttachmentRemoved(worldIn, pos, state);
|
|
||||||
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
||||||
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
|
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
|
||||||
worldIn.removeTileEntity(pos);
|
worldIn.removeTileEntity(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockPos getBeltPositionForAttachment(IWorld world, BlockPos pos, BlockState state) {
|
|
||||||
return pos.offset(getBlockFacing(state));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<BlockPos> getPotentialAttachmentPositions(IWorld world, BlockPos pos, BlockState beltState) {
|
|
||||||
return Arrays.asList(Direction.values()).stream().filter(d -> d != Direction.UP).map(pos::offset)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
|
||||||
BlockPos pos = state.attachmentPos;
|
|
||||||
World world = te.getWorld();
|
|
||||||
ItemStack stack = transported.stack;
|
|
||||||
|
|
||||||
FilteringBehaviour filtering = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
|
||||||
SingleTargetAutoExtractingBehaviour extracting = TileEntityBehaviour.get(world, pos,
|
|
||||||
SingleTargetAutoExtractingBehaviour.TYPE);
|
|
||||||
|
|
||||||
if (extracting == null)
|
|
||||||
return false;
|
|
||||||
if (filtering != null && (!filtering.test(stack) || stack.getCount() < filtering.getAmount()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
|
||||||
BlockPos pos = state.attachmentPos;
|
|
||||||
World world = te.getWorld();
|
|
||||||
ItemStack stack = transported.stack;
|
|
||||||
|
|
||||||
SingleTargetAutoExtractingBehaviour extracting = TileEntityBehaviour.get(world, pos,
|
|
||||||
SingleTargetAutoExtractingBehaviour.TYPE);
|
|
||||||
|
|
||||||
if (extracting == null)
|
|
||||||
return false;
|
|
||||||
if (extracting.getShouldPause().get())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
FilteringBehaviour filtering = TileEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE);
|
|
||||||
if (filtering != null && (!filtering.test(stack) || stack.getCount() < filtering.getAmount()))
|
|
||||||
return false;
|
|
||||||
if (!extracting.getShouldExtract().get())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return !extracting.extractFromInventory();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +1,21 @@
|
||||||
package com.simibubi.create.content.logistics.block.belts.observer;
|
package com.simibubi.create.content.logistics.block.belts.observer;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Part;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Part;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Slope;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock.Slope;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
|
||||||
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
||||||
import com.simibubi.create.foundation.block.ITE;
|
import com.simibubi.create.foundation.block.ITE;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.HorizontalBlock;
|
import net.minecraft.block.HorizontalBlock;
|
||||||
import net.minecraft.block.material.PushReaction;
|
import net.minecraft.block.material.PushReaction;
|
||||||
import net.minecraft.entity.Entity;
|
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
|
||||||
import net.minecraft.item.BlockItemUseContext;
|
import net.minecraft.item.BlockItemUseContext;
|
||||||
import net.minecraft.item.ItemStack;
|
|
||||||
import net.minecraft.item.ItemUseContext;
|
import net.minecraft.item.ItemUseContext;
|
||||||
import net.minecraft.state.BooleanProperty;
|
import net.minecraft.state.BooleanProperty;
|
||||||
import net.minecraft.state.EnumProperty;
|
import net.minecraft.state.EnumProperty;
|
||||||
|
@ -37,18 +25,13 @@ import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.ActionResultType;
|
import net.minecraft.util.ActionResultType;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.IStringSerializable;
|
import net.minecraft.util.IStringSerializable;
|
||||||
import net.minecraft.util.SoundCategory;
|
|
||||||
import net.minecraft.util.SoundEvents;
|
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.world.IBlockReader;
|
import net.minecraft.world.IBlockReader;
|
||||||
import net.minecraft.world.IWorld;
|
import net.minecraft.world.IWorld;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.server.ServerWorld;
|
|
||||||
|
|
||||||
public class BeltObserverBlock extends HorizontalBlock
|
public class BeltObserverBlock extends HorizontalBlock
|
||||||
implements ITE<BeltObserverTileEntity>, IBeltAttachment, IWrenchable {
|
implements ITE<BeltObserverTileEntity>, IWrenchable {
|
||||||
|
|
||||||
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
|
||||||
public static final BooleanProperty BELT = BooleanProperty.create("belt");
|
public static final BooleanProperty BELT = BooleanProperty.create("belt");
|
||||||
|
@ -138,23 +121,6 @@ public class BeltObserverBlock extends HorizontalBlock
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<BlockPos> getPotentialAttachmentPositions(IWorld world, BlockPos pos, BlockState beltState) {
|
|
||||||
Direction side = beltState.get(BeltBlock.HORIZONTAL_FACING).rotateY();
|
|
||||||
return Arrays.asList(pos.offset(side), pos.offset(side.getOpposite()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockPos getBeltPositionForAttachment(IWorld world, BlockPos pos, BlockState state) {
|
|
||||||
return pos.offset(state.get(HORIZONTAL_FACING));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAttachedCorrectly(IWorld world, BlockPos attachmentPos, BlockPos beltPos,
|
|
||||||
BlockState attachmentState, BlockState beltState) {
|
|
||||||
return attachmentState.get(BELT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canProvidePower(BlockState state) {
|
public boolean canProvidePower(BlockState state) {
|
||||||
return state.get(POWERED);
|
return state.get(POWERED);
|
||||||
|
@ -172,118 +138,12 @@ public class BeltObserverBlock extends HorizontalBlock
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||||
if (newState.getBlock() != this || newState.with(POWERED, false) != state.with(POWERED, false))
|
|
||||||
onAttachmentRemoved(worldIn, pos, state);
|
|
||||||
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
||||||
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
|
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
|
||||||
worldIn.removeTileEntity(pos);
|
worldIn.removeTileEntity(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
|
||||||
if (oldState.getBlock() != this || oldState.with(POWERED, false) != state.with(POWERED, false))
|
|
||||||
onAttachmentPlaced(worldIn, pos, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
|
||||||
World world = te.getWorld();
|
|
||||||
BlockState blockState = world.getBlockState(state.attachmentPos);
|
|
||||||
if (blockState.get(MODE) == Mode.DETECT)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
FilteringBehaviour behaviour =
|
|
||||||
TileEntityBehaviour.get(te.getWorld(), state.attachmentPos, FilteringBehaviour.TYPE);
|
|
||||||
if (behaviour != null && !behaviour.test(transported.stack))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
world.setBlockState(state.attachmentPos, blockState.with(POWERED, true));
|
|
||||||
world.notifyNeighborsOfStateChange(state.attachmentPos, this);
|
|
||||||
withTileEntityDo(world, state.attachmentPos, BeltObserverTileEntity::resetTurnOffCooldown);
|
|
||||||
|
|
||||||
Mode mode = blockState.get(MODE);
|
|
||||||
if (mode == Mode.EJECT || mode == Mode.SPLIT) {
|
|
||||||
ItemStack copy = transported.stack.copy();
|
|
||||||
ItemStack toEject = mode == Mode.EJECT ? transported.stack : copy.split(transported.stack.getCount() / 2);
|
|
||||||
|
|
||||||
if (!toEject.isEmpty()) {
|
|
||||||
if (!eject(world, toEject, state.attachmentPos, blockState.get(HORIZONTAL_FACING)))
|
|
||||||
return true;
|
|
||||||
transported.stack = mode == Mode.EJECT ? ItemStack.EMPTY : copy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
|
||||||
World world = te.getWorld();
|
|
||||||
BlockState blockState = world.getBlockState(state.attachmentPos);
|
|
||||||
withTileEntityDo(world, state.attachmentPos, BeltObserverTileEntity::resetTurnOffCooldown);
|
|
||||||
|
|
||||||
Mode mode = blockState.get(MODE);
|
|
||||||
if (mode == Mode.EJECT || mode == Mode.SPLIT) {
|
|
||||||
ItemStack copy = transported.stack.copy();
|
|
||||||
ItemStack toEject = mode == Mode.EJECT ? transported.stack : copy.split(transported.stack.getCount() / 2);
|
|
||||||
|
|
||||||
if (!eject(world, toEject, state.attachmentPos, blockState.get(HORIZONTAL_FACING)))
|
|
||||||
return true;
|
|
||||||
transported.stack = mode == Mode.EJECT ? ItemStack.EMPTY : copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean eject(World world, ItemStack stack, BlockPos observerPos, Direction facing) {
|
|
||||||
BlockPos potentialBeltPos = observerPos.offset(facing, 2);
|
|
||||||
TileEntity tileEntity = world.getTileEntity(potentialBeltPos);
|
|
||||||
if (tileEntity instanceof BeltTileEntity) {
|
|
||||||
BeltTileEntity belt = (BeltTileEntity) tileEntity;
|
|
||||||
return belt.tryInsertingFromSide(facing, stack, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean empty = world.getBlockState(potentialBeltPos).getCollisionShape(world, potentialBeltPos).isEmpty();
|
|
||||||
float yOffset = empty ? 0 : .5f;
|
|
||||||
AxisAlignedBB bb = new AxisAlignedBB(empty ? potentialBeltPos : potentialBeltPos.up());
|
|
||||||
if (!world.getEntitiesWithinAABBExcludingEntity(null, bb).isEmpty())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Vec3d motion = new Vec3d(facing.getDirectionVec()).scale(1 / 16f);
|
|
||||||
Vec3d entityPos = VecHelper.getCenterOf(potentialBeltPos).add(0, yOffset + .25f, 0).subtract(motion);
|
|
||||||
ItemEntity entity = new ItemEntity(world, entityPos.x, entityPos.y, entityPos.z, stack);
|
|
||||||
entity.setMotion(motion);
|
|
||||||
entity.setPickupDelay(5);
|
|
||||||
world.playSound(null, observerPos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .125f, .1f);
|
|
||||||
world.addEntity(entity);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean processEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) {
|
|
||||||
if (te.getWorld().isRemote)
|
|
||||||
return false;
|
|
||||||
if (entity.getPositionVec().distanceTo(VecHelper.getCenterOf(te.getPos())) > .5f)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
World world = te.getWorld();
|
|
||||||
BlockState blockState = world.getBlockState(state.attachmentPos);
|
|
||||||
if (blockState.get(POWERED))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
world.setBlockState(state.attachmentPos, blockState.with(POWERED, true));
|
|
||||||
world.notifyNeighborsOfStateChange(state.attachmentPos, this);
|
|
||||||
withTileEntityDo(te.getWorld(), state.attachmentPos, BeltObserverTileEntity::resetTurnOffCooldown);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void scheduledTick(BlockState state, ServerWorld worldIn, BlockPos pos, Random random) {
|
|
||||||
worldIn.setBlockState(pos, state.with(POWERED, false), 2);
|
|
||||||
worldIn.notifyNeighborsOfStateChange(pos, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||||
World world = context.getWorld();
|
World world = context.getWorld();
|
||||||
|
|
|
@ -106,7 +106,7 @@ public class ExtractorTileEntity extends SmartTileEntity {
|
||||||
BeltInventory inventory = controller.getInventory();
|
BeltInventory inventory = controller.getInventory();
|
||||||
if (inventory == null)
|
if (inventory == null)
|
||||||
return false;
|
return false;
|
||||||
if (!inventory.canInsertFrom(belt.index, Direction.UP))
|
if (!inventory.canInsertAtFromSide(belt.index, Direction.UP))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,14 @@
|
||||||
package com.simibubi.create.content.logistics.block.funnel;
|
package com.simibubi.create.content.logistics.block.funnel;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllShapes;
|
import com.simibubi.create.AllShapes;
|
||||||
import com.simibubi.create.AllTileEntities;
|
import com.simibubi.create.AllTileEntities;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.IPortableBlock;
|
import com.simibubi.create.content.contraptions.components.structureMovement.IPortableBlock;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment;
|
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
|
||||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
|
||||||
import com.simibubi.create.content.logistics.block.AttachedLogisticalBlock;
|
import com.simibubi.create.content.logistics.block.AttachedLogisticalBlock;
|
||||||
import com.simibubi.create.foundation.block.ITE;
|
import com.simibubi.create.foundation.block.ITE;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
@ -41,7 +36,7 @@ import net.minecraft.world.IWorld;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class FunnelBlock extends AttachedLogisticalBlock
|
public class FunnelBlock extends AttachedLogisticalBlock
|
||||||
implements IBeltAttachment, ITE<FunnelTileEntity>, IPortableBlock {
|
implements ITE<FunnelTileEntity>, IPortableBlock {
|
||||||
|
|
||||||
public static final BooleanProperty BELT = BooleanProperty.create("belt");
|
public static final BooleanProperty BELT = BooleanProperty.create("belt");
|
||||||
public static final MovementBehaviour MOVEMENT = new FunnelMovementBehaviour();
|
public static final MovementBehaviour MOVEMENT = new FunnelMovementBehaviour();
|
||||||
|
@ -131,7 +126,6 @@ public class FunnelBlock extends AttachedLogisticalBlock
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||||
onAttachmentPlaced(worldIn, pos, state);
|
|
||||||
if (worldIn.isRemote)
|
if (worldIn.isRemote)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -153,42 +147,12 @@ public class FunnelBlock extends AttachedLogisticalBlock
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
|
||||||
onAttachmentRemoved(worldIn, pos, state);
|
|
||||||
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) {
|
||||||
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
|
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
|
||||||
worldIn.removeTileEntity(pos);
|
worldIn.removeTileEntity(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<BlockPos> getPotentialAttachmentPositions(IWorld world, BlockPos pos, BlockState beltState) {
|
|
||||||
return Arrays.asList(pos.up());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockPos getBeltPositionForAttachment(IWorld world, BlockPos pos, BlockState state) {
|
|
||||||
return pos.down();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean startProcessingItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
|
||||||
return process(te, transported, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAttachedCorrectly(IWorld world, BlockPos attachmentPos, BlockPos beltPos,
|
|
||||||
BlockState attachmentState, BlockState beltState) {
|
|
||||||
return !isVertical(attachmentState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean processItem(BeltTileEntity te, TransportedItemStack transported, BeltAttachmentState state) {
|
|
||||||
Direction movementFacing = te.getMovementFacing();
|
|
||||||
if (movementFacing != te.getWorld().getBlockState(state.attachmentPos).get(HORIZONTAL_FACING))
|
|
||||||
return false;
|
|
||||||
return process(te, transported, state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||||
BlockRayTraceResult hit) {
|
BlockRayTraceResult hit) {
|
||||||
|
@ -207,16 +171,6 @@ public class FunnelBlock extends AttachedLogisticalBlock
|
||||||
return ActionResultType.PASS;
|
return ActionResultType.PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean process(BeltTileEntity belt, TransportedItemStack transported, BeltAttachmentState state) {
|
|
||||||
TileEntity te = belt.getWorld().getTileEntity(state.attachmentPos);
|
|
||||||
if (!(te instanceof FunnelTileEntity))
|
|
||||||
return false;
|
|
||||||
FunnelTileEntity funnel = (FunnelTileEntity) te;
|
|
||||||
ItemStack stack = funnel.tryToInsert(transported.stack);
|
|
||||||
transported.stack = stack;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Vertical extends FunnelBlock {
|
public static class Vertical extends FunnelBlock {
|
||||||
public Vertical(Properties properties) {
|
public Vertical(Properties properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
|
|
|
@ -6,7 +6,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.tileentity.ITickableTileEntity;
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
|
@ -14,7 +14,7 @@ import net.minecraft.tileentity.TileEntityType;
|
||||||
|
|
||||||
public abstract class SmartTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
public abstract class SmartTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
||||||
|
|
||||||
private Map<IBehaviourType<?>, TileEntityBehaviour> behaviours;
|
private Map<BehaviourType<?>, TileEntityBehaviour> behaviours;
|
||||||
private boolean initialized;
|
private boolean initialized;
|
||||||
private boolean firstNbtRead;
|
private boolean firstNbtRead;
|
||||||
private int lazyTickRate;
|
private int lazyTickRate;
|
||||||
|
@ -120,14 +120,14 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka
|
||||||
behaviour.initialize();
|
behaviour.initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void removeBehaviour(IBehaviourType<?> type) {
|
protected void removeBehaviour(BehaviourType<?> type) {
|
||||||
TileEntityBehaviour remove = behaviours.remove(type);
|
TileEntityBehaviour remove = behaviours.remove(type);
|
||||||
if (remove != null)
|
if (remove != null)
|
||||||
remove.remove();
|
remove.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <T extends TileEntityBehaviour> T getBehaviour(IBehaviourType<T> type) {
|
protected <T extends TileEntityBehaviour> T getBehaviour(BehaviourType<T> type) {
|
||||||
if (behaviours.containsKey(type))
|
if (behaviours.containsKey(type))
|
||||||
return (T) behaviours.get(type);
|
return (T) behaviours.get(type);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.simibubi.create.foundation.tileEntity;
|
package com.simibubi.create.foundation.tileEntity;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
@ -23,7 +23,7 @@ public abstract class TileEntityBehaviour {
|
||||||
setLazyTickRate(10);
|
setLazyTickRate(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract IBehaviourType<?> getType();
|
public abstract BehaviourType<?> getType();
|
||||||
|
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
|
||||||
|
@ -91,18 +91,18 @@ public abstract class TileEntityBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends TileEntityBehaviour> T get(ILightReader reader, BlockPos pos,
|
public static <T extends TileEntityBehaviour> T get(ILightReader reader, BlockPos pos,
|
||||||
IBehaviourType<T> type) {
|
BehaviourType<T> type) {
|
||||||
return get(reader.getTileEntity(pos), type);
|
return get(reader.getTileEntity(pos), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends TileEntityBehaviour> void destroy(ILightReader reader, BlockPos pos,
|
public static <T extends TileEntityBehaviour> void destroy(ILightReader reader, BlockPos pos,
|
||||||
IBehaviourType<T> type) {
|
BehaviourType<T> type) {
|
||||||
T behaviour = get(reader.getTileEntity(pos), type);
|
T behaviour = get(reader.getTileEntity(pos), type);
|
||||||
if (behaviour != null)
|
if (behaviour != null)
|
||||||
behaviour.destroy();
|
behaviour.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends TileEntityBehaviour> T get(TileEntity te, IBehaviourType<T> type) {
|
public static <T extends TileEntityBehaviour> T get(TileEntity te, BehaviourType<T> type) {
|
||||||
if (te == null)
|
if (te == null)
|
||||||
return null;
|
return null;
|
||||||
if (!(te instanceof SmartTileEntity))
|
if (!(te instanceof SmartTileEntity))
|
||||||
|
|
|
@ -2,6 +2,6 @@ package com.simibubi.create.foundation.tileEntity.behaviour;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
|
||||||
public interface IBehaviourType<T extends TileEntityBehaviour> {
|
public class BehaviourType<T extends TileEntityBehaviour> {
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.simibubi.create.foundation.tileEntity.behaviour.belt;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.transport.BeltInventory;
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Behaviour for TileEntities which can process items on belts or depots beneath them.
|
||||||
|
* Currently only supports placement location 2 spaces above the belt block.
|
||||||
|
* Example use: Mechanical Press
|
||||||
|
*/
|
||||||
|
public class BeltProcessingBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
|
public static BehaviourType<BeltProcessingBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
|
||||||
|
public static enum ProcessingResult {
|
||||||
|
PASS, HOLD, REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProcessingCallback onItemEnter;
|
||||||
|
private ProcessingCallback continueProcessing;
|
||||||
|
|
||||||
|
public BeltProcessingBehaviour(SmartTileEntity te) {
|
||||||
|
super(te);
|
||||||
|
onItemEnter = (s, i) -> ProcessingResult.PASS;
|
||||||
|
continueProcessing = (s, i) -> ProcessingResult.PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeltProcessingBehaviour whenItemEnters(ProcessingCallback callback) {
|
||||||
|
onItemEnter = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BeltProcessingBehaviour whileItemHeld(ProcessingCallback callback) {
|
||||||
|
continueProcessing = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BehaviourType<?> getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProcessingResult handleReceivedItem(TransportedItemStack stack, BeltInventory inventory) {
|
||||||
|
return onItemEnter.apply(stack, inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProcessingResult handleHeldItem(TransportedItemStack stack, BeltInventory inventory) {
|
||||||
|
return continueProcessing.apply(stack, inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ProcessingCallback {
|
||||||
|
public ProcessingResult apply(TransportedItemStack stack, BeltInventory inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
package com.simibubi.create.foundation.tileEntity.behaviour.belt;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraftforge.common.util.LazyOptional;
|
||||||
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Behaviour for TileEntities to which belts can transfer items directly in a
|
||||||
|
* backup-friendly manner. Example uses: Basin, Saw, Depot
|
||||||
|
*/
|
||||||
|
public class DirectBeltInputBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
|
public static BehaviourType<DirectBeltInputBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
|
||||||
|
private InsertionCallback tryInsert;
|
||||||
|
private AvailabilityPredicate canInsert;
|
||||||
|
|
||||||
|
public DirectBeltInputBehaviour(SmartTileEntity te) {
|
||||||
|
super(te);
|
||||||
|
tryInsert = this::defaultInsertionCallback;
|
||||||
|
canInsert = d -> true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DirectBeltInputBehaviour onlyInsertWhen(AvailabilityPredicate pred) {
|
||||||
|
canInsert = pred;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DirectBeltInputBehaviour setInsertionHandler(InsertionCallback callback) {
|
||||||
|
tryInsert = callback;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack defaultInsertionCallback(TransportedItemStack inserted, Direction side, boolean simulate) {
|
||||||
|
LazyOptional<IItemHandler> lazy = tileEntity.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, side);
|
||||||
|
if (!lazy.isPresent())
|
||||||
|
return inserted.stack;
|
||||||
|
return ItemHandlerHelper.insertItemStacked(lazy.orElse(null), inserted.stack.copy(), simulate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canInsertFromSide(Direction side) {
|
||||||
|
return canInsert.test(side);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack handleInsertion(ItemStack stack, Direction side, boolean simulate) {
|
||||||
|
return handleInsertion(new TransportedItemStack(stack), side, simulate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack handleInsertion(TransportedItemStack stack, Direction side, boolean simulate) {
|
||||||
|
return tryInsert.apply(stack, side, simulate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BehaviourType<?> getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface InsertionCallback {
|
||||||
|
public ItemStack apply(TransportedItemStack stack, Direction side, boolean simulate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface AvailabilityPredicate {
|
||||||
|
public boolean test(Direction side);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ import java.util.Optional;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
@ -13,8 +13,7 @@ import net.minecraft.world.World;
|
||||||
|
|
||||||
public class EdgeInteractionBehaviour extends TileEntityBehaviour {
|
public class EdgeInteractionBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
public static IBehaviourType<EdgeInteractionBehaviour> TYPE = new IBehaviourType<EdgeInteractionBehaviour>() {
|
public static BehaviourType<EdgeInteractionBehaviour> TYPE = new BehaviourType<>();
|
||||||
};
|
|
||||||
|
|
||||||
ConnectionCallback connectionCallback;
|
ConnectionCallback connectionCallback;
|
||||||
ConnectivityPredicate connectivityPredicate;
|
ConnectivityPredicate connectivityPredicate;
|
||||||
|
@ -38,7 +37,7 @@ public class EdgeInteractionBehaviour extends TileEntityBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import com.simibubi.create.content.logistics.item.filter.FilterItem;
|
||||||
import com.simibubi.create.foundation.networking.AllPackets;
|
import com.simibubi.create.foundation.networking.AllPackets;
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
|
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
@ -20,8 +20,7 @@ import net.minecraft.world.World;
|
||||||
|
|
||||||
public class FilteringBehaviour extends TileEntityBehaviour {
|
public class FilteringBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
public static IBehaviourType<FilteringBehaviour> TYPE = new IBehaviourType<FilteringBehaviour>() {
|
public static BehaviourType<FilteringBehaviour> TYPE = new BehaviourType<>();
|
||||||
};
|
|
||||||
|
|
||||||
ValueBoxTransform slotPositioning;
|
ValueBoxTransform slotPositioning;
|
||||||
boolean showCount;
|
boolean showCount;
|
||||||
|
@ -152,7 +151,7 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import java.util.function.Supplier;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
@ -15,8 +15,7 @@ import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public class AutoExtractingBehaviour extends ExtractingBehaviour {
|
public class AutoExtractingBehaviour extends ExtractingBehaviour {
|
||||||
|
|
||||||
public static IBehaviourType<AutoExtractingBehaviour> TYPE = new IBehaviourType<AutoExtractingBehaviour>() {
|
public static BehaviourType<AutoExtractingBehaviour> TYPE = new BehaviourType<>();
|
||||||
};
|
|
||||||
|
|
||||||
private int delay;
|
private int delay;
|
||||||
private int timer;
|
private int timer;
|
||||||
|
@ -85,7 +84,7 @@ public class AutoExtractingBehaviour extends ExtractingBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
import com.simibubi.create.foundation.item.ItemHelper;
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
@ -21,8 +21,7 @@ import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
public class ExtractingBehaviour extends InventoryManagementBehaviour {
|
public class ExtractingBehaviour extends InventoryManagementBehaviour {
|
||||||
|
|
||||||
public static IBehaviourType<ExtractingBehaviour> TYPE = new IBehaviourType<ExtractingBehaviour>() {
|
public static BehaviourType<ExtractingBehaviour> TYPE = new BehaviourType<>();
|
||||||
};
|
|
||||||
|
|
||||||
private Function<ItemStack, Integer> customAmountFilter;
|
private Function<ItemStack, Integer> customAmountFilter;
|
||||||
private Predicate<ItemStack> customFilter;
|
private Predicate<ItemStack> customFilter;
|
||||||
|
@ -90,7 +89,7 @@ public class ExtractingBehaviour extends InventoryManagementBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import java.util.function.Supplier;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
|
@ -16,8 +16,7 @@ import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
public class InsertingBehaviour extends InventoryManagementBehaviour {
|
public class InsertingBehaviour extends InventoryManagementBehaviour {
|
||||||
|
|
||||||
public static IBehaviourType<InsertingBehaviour> TYPE = new IBehaviourType<InsertingBehaviour>() {
|
public static BehaviourType<InsertingBehaviour> TYPE = new BehaviourType<>();
|
||||||
};
|
|
||||||
|
|
||||||
public InsertingBehaviour(SmartTileEntity te, Supplier<List<Pair<BlockPos, Direction>>> attachments) {
|
public InsertingBehaviour(SmartTileEntity te, Supplier<List<Pair<BlockPos, Direction>>> attachments) {
|
||||||
super(te, attachments);
|
super(te, attachments);
|
||||||
|
@ -33,7 +32,7 @@ public class InsertingBehaviour extends InventoryManagementBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
@ -28,8 +28,7 @@ public class InventoryManagementBehaviour extends TileEntityBehaviour {
|
||||||
private Supplier<List<Pair<BlockPos, Direction>>> attachments;
|
private Supplier<List<Pair<BlockPos, Direction>>> attachments;
|
||||||
private List<IItemHandler> activeHandlers;
|
private List<IItemHandler> activeHandlers;
|
||||||
|
|
||||||
public static IBehaviourType<InventoryManagementBehaviour> TYPE = new IBehaviourType<InventoryManagementBehaviour>() {
|
public static BehaviourType<InventoryManagementBehaviour> TYPE = new BehaviourType<>();
|
||||||
};
|
|
||||||
|
|
||||||
public InventoryManagementBehaviour(SmartTileEntity te, Supplier<List<Pair<BlockPos, Direction>>> attachments) {
|
public InventoryManagementBehaviour(SmartTileEntity te, Supplier<List<Pair<BlockPos, Direction>>> attachments) {
|
||||||
super(te);
|
super(te);
|
||||||
|
@ -98,7 +97,7 @@ public class InventoryManagementBehaviour extends TileEntityBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
@ -13,9 +13,7 @@ import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
public class SingleTargetAutoExtractingBehaviour extends AutoExtractingBehaviour {
|
public class SingleTargetAutoExtractingBehaviour extends AutoExtractingBehaviour {
|
||||||
|
|
||||||
public static IBehaviourType<SingleTargetAutoExtractingBehaviour> TYPE =
|
public static BehaviourType<SingleTargetAutoExtractingBehaviour> TYPE = new BehaviourType<>();
|
||||||
new IBehaviourType<SingleTargetAutoExtractingBehaviour>() {
|
|
||||||
};
|
|
||||||
|
|
||||||
private Supplier<Direction> attachmentDirection;
|
private Supplier<Direction> attachmentDirection;
|
||||||
boolean synced;
|
boolean synced;
|
||||||
|
@ -49,7 +47,8 @@ public class SingleTargetAutoExtractingBehaviour extends AutoExtractingBehaviour
|
||||||
@Override
|
@Override
|
||||||
public boolean extract() {
|
public boolean extract() {
|
||||||
if (synced) {
|
if (synced) {
|
||||||
BlockPos invPos = tileEntity.getPos().offset(attachmentDirection.get());
|
BlockPos invPos = tileEntity.getPos()
|
||||||
|
.offset(attachmentDirection.get());
|
||||||
return SynchronizedExtraction.extractSynchronized(getWorld(), invPos);
|
return SynchronizedExtraction.extractSynchronized(getWorld(), invPos);
|
||||||
} else
|
} else
|
||||||
return extractFromInventory();
|
return extractFromInventory();
|
||||||
|
@ -60,7 +59,7 @@ public class SingleTargetAutoExtractingBehaviour extends AutoExtractingBehaviour
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import com.simibubi.create.content.logistics.RedstoneLinkNetworkHandler;
|
||||||
import com.simibubi.create.content.logistics.RedstoneLinkNetworkHandler.Frequency;
|
import com.simibubi.create.content.logistics.RedstoneLinkNetworkHandler.Frequency;
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
|
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
@ -21,8 +21,7 @@ import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public class LinkBehaviour extends TileEntityBehaviour {
|
public class LinkBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
public static IBehaviourType<LinkBehaviour> TYPE = new IBehaviourType<LinkBehaviour>() {
|
public static BehaviourType<LinkBehaviour> TYPE = new BehaviourType<>();
|
||||||
};
|
|
||||||
|
|
||||||
enum Mode {
|
enum Mode {
|
||||||
TRANSMIT, RECEIVE
|
TRANSMIT, RECEIVE
|
||||||
|
@ -162,7 +161,7 @@ public class LinkBehaviour extends TileEntityBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import java.util.function.Function;
|
||||||
import com.simibubi.create.foundation.networking.AllPackets;
|
import com.simibubi.create.foundation.networking.AllPackets;
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
|
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
@ -16,8 +16,7 @@ import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
public class ScrollValueBehaviour extends TileEntityBehaviour {
|
public class ScrollValueBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
public static IBehaviourType<ScrollValueBehaviour> TYPE = new IBehaviourType<ScrollValueBehaviour>() {
|
public static BehaviourType<ScrollValueBehaviour> TYPE = new BehaviourType<>();
|
||||||
};
|
|
||||||
|
|
||||||
ValueBoxTransform slotPositioning;
|
ValueBoxTransform slotPositioning;
|
||||||
Vec3d textShift;
|
Vec3d textShift;
|
||||||
|
@ -162,7 +161,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,13 @@ import java.util.function.Supplier;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.IBehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
|
||||||
public class DeferralBehaviour extends TileEntityBehaviour {
|
public class DeferralBehaviour extends TileEntityBehaviour {
|
||||||
|
|
||||||
public static IBehaviourType<DeferralBehaviour> TYPE = new IBehaviourType<DeferralBehaviour>() {
|
public static BehaviourType<DeferralBehaviour> TYPE = new BehaviourType<>();
|
||||||
};
|
|
||||||
|
|
||||||
private boolean needsUpdate;
|
private boolean needsUpdate;
|
||||||
private Supplier<Boolean> callback;
|
private Supplier<Boolean> callback;
|
||||||
|
@ -45,7 +44,7 @@ public class DeferralBehaviour extends TileEntityBehaviour {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IBehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue