mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-11 04:22:00 +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.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
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.components.crafter.ConnectedInputHandler.ConnectedInput;
|
||||
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.behaviour.belt.DirectBeltInputBehaviour;
|
||||
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.InventoryManagementBehaviour.Attachments;
|
||||
|
@ -27,7 +28,6 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.particles.ItemParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -91,9 +91,9 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
setLazyTickRate(20);
|
||||
phase = Phase.IDLE;
|
||||
groupedItemsBeforeCraft = new GroupedItems();
|
||||
|
||||
|
||||
// Does not get serialized due to active checking in tick
|
||||
wasPoweredBefore = true;
|
||||
wasPoweredBefore = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -337,13 +337,13 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
}
|
||||
|
||||
protected boolean isTargetingBelt() {
|
||||
DirectBeltInputBehaviour behaviour = getTargetingBelt();
|
||||
return behaviour != null && behaviour.canInsertFromSide(getTargetFacing());
|
||||
}
|
||||
|
||||
protected DirectBeltInputBehaviour getTargetingBelt() {
|
||||
BlockPos targetPos = pos.offset(getTargetFacing());
|
||||
if (!AllBlocks.BELT.has(world.getBlockState(targetPos)))
|
||||
return false;
|
||||
TileEntity te = world.getTileEntity(targetPos);
|
||||
if (!(te instanceof BeltTileEntity))
|
||||
return false;
|
||||
return ((KineticTileEntity) te).getSpeed() != 0;
|
||||
return TileEntityBehaviour.get(world, targetPos, DirectBeltInputBehaviour.TYPE);
|
||||
}
|
||||
|
||||
public void tryInsert() {
|
||||
|
@ -355,22 +355,21 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
boolean chagedPhase = phase != Phase.INSERTING;
|
||||
final List<Pair<Integer, Integer>> inserted = new LinkedList<>();
|
||||
|
||||
groupedItems.grid.forEach((pair, stack) -> {
|
||||
if (isTargetingBelt()) {
|
||||
Direction facing = getTargetFacing();
|
||||
BlockPos targetPos = pos.offset(facing);
|
||||
BeltTileEntity te = (BeltTileEntity) world.getTileEntity(targetPos);
|
||||
if (te.tryInsertingFromSide(facing, stack, false))
|
||||
inserted.add(pair);
|
||||
return;
|
||||
}
|
||||
DirectBeltInputBehaviour behaviour = getTargetingBelt();
|
||||
for (Entry<Pair<Integer, Integer>, ItemStack> entry : groupedItems.grid.entrySet()) {
|
||||
Pair<Integer, Integer> pair = entry.getKey();
|
||||
ItemStack stack = entry.getValue();
|
||||
Direction facing = getTargetFacing();
|
||||
|
||||
ItemStack remainder = inserting.insert(stack.copy(), false);
|
||||
if (!remainder.isEmpty())
|
||||
ItemStack remainder = behaviour == null ? inserting.insert(stack.copy(), false)
|
||||
: behaviour.handleInsertion(stack, facing, false);
|
||||
if (!remainder.isEmpty()) {
|
||||
stack.setCount(remainder.getCount());
|
||||
else
|
||||
inserted.add(pair);
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
inserted.add(pair);
|
||||
}
|
||||
|
||||
inserted.forEach(groupedItems.grid::remove);
|
||||
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.foundation.config.AllConfigs;
|
||||
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 net.minecraft.entity.Entity;
|
||||
|
@ -24,7 +26,6 @@ import net.minecraft.particles.BlockParticleData;
|
|||
import net.minecraft.particles.IParticleData;
|
||||
import net.minecraft.particles.ItemParticleData;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
|
@ -36,7 +37,7 @@ import net.minecraftforge.items.CapabilityItemHandler;
|
|||
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||
|
||||
public class CrushingWheelControllerTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
||||
public class CrushingWheelControllerTileEntity extends SmartTileEntity {
|
||||
|
||||
public Entity processingEntity;
|
||||
private UUID entityUUID;
|
||||
|
@ -60,14 +61,20 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
wrapper = new RecipeWrapper(inventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
behaviours.add(new DirectBeltInputBehaviour(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (isFrozen())
|
||||
return;
|
||||
if (searchForEntity) {
|
||||
searchForEntity = false;
|
||||
List<Entity> search = world.getEntitiesInAABBexcluding(null, new AxisAlignedBB(getPos()),
|
||||
e -> entityUUID.equals(e.getUniqueID()));
|
||||
e -> entityUUID.equals(e.getUniqueID()));
|
||||
if (search.isEmpty())
|
||||
clear();
|
||||
else
|
||||
|
@ -84,9 +91,9 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
|
||||
if (!hasEntity()) {
|
||||
|
||||
float processingSpeed = MathHelper.clamp(
|
||||
(speed) / (!inventory.appliedRecipe ? MathHelper.log2(inventory.getStackInSlot(0).getCount()) : 1),
|
||||
.25f, 20);
|
||||
float processingSpeed =
|
||||
MathHelper.clamp((speed) / (!inventory.appliedRecipe ? MathHelper.log2(inventory.getStackInSlot(0)
|
||||
.getCount()) : 1), .25f, 20);
|
||||
inventory.remainingTime -= processingSpeed;
|
||||
spawnParticles(inventory.getStackInSlot(0));
|
||||
|
||||
|
@ -107,7 +114,8 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
continue;
|
||||
ItemEntity entityIn = new ItemEntity(world, outPos.x, outPos.y, outPos.z, stack);
|
||||
entityIn.setMotion(Vec3d.ZERO);
|
||||
entityIn.getPersistentData().put("BypassCrushingWheel", NBTUtil.writeBlockPos(pos));
|
||||
entityIn.getPersistentData()
|
||||
.put("BypassCrushingWheel", NBTUtil.writeBlockPos(pos));
|
||||
world.addEntity(entityIn);
|
||||
}
|
||||
inventory.clear();
|
||||
|
@ -118,8 +126,8 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
return;
|
||||
}
|
||||
|
||||
if (!processingEntity.isAlive()
|
||||
|| !processingEntity.getBoundingBox().intersects(new AxisAlignedBB(pos).grow(.5f))) {
|
||||
if (!processingEntity.isAlive() || !processingEntity.getBoundingBox()
|
||||
.intersects(new AxisAlignedBB(pos).grow(.5f))) {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
|
@ -136,7 +144,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
|
||||
if (!(processingEntity instanceof ItemEntity)) {
|
||||
processingEntity.attackEntityFrom(CrushingWheelTileEntity.damageSource,
|
||||
AllConfigs.SERVER.kinetics.crushingDamage.get());
|
||||
AllConfigs.SERVER.kinetics.crushingDamage.get());
|
||||
if (!processingEntity.isAlive()) {
|
||||
processingEntity.setPosition(outPos.x, outPos.y - .75f, outPos.z);
|
||||
}
|
||||
|
@ -147,7 +155,8 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
itemEntity.setPickupDelay(20);
|
||||
if (processingEntity.getY() < pos.getY() + .25f) {
|
||||
inventory.clear();
|
||||
inventory.setStackInSlot(0, itemEntity.getItem().copy());
|
||||
inventory.setStackInSlot(0, itemEntity.getItem()
|
||||
.copy());
|
||||
itemInserted(inventory.getStackInSlot(0));
|
||||
itemEntity.remove();
|
||||
world.notifyBlockUpdate(pos, getBlockState(), getBlockState(), 2 | 16);
|
||||
|
@ -161,15 +170,15 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
|
||||
IParticleData particleData = null;
|
||||
if (stack.getItem() instanceof BlockItem)
|
||||
particleData =
|
||||
new BlockParticleData(ParticleTypes.BLOCK, ((BlockItem) stack.getItem()).getBlock().getDefaultState());
|
||||
particleData = new BlockParticleData(ParticleTypes.BLOCK, ((BlockItem) stack.getItem()).getBlock()
|
||||
.getDefaultState());
|
||||
else
|
||||
particleData = new ItemParticleData(ParticleTypes.ITEM, stack);
|
||||
|
||||
Random r = world.rand;
|
||||
for (int i = 0; i < 4; i++)
|
||||
world.addParticle(particleData, pos.getX() + r.nextFloat(), pos.getY() + r.nextFloat(),
|
||||
pos.getZ() + r.nextFloat(), 0, 0, 0);
|
||||
pos.getZ() + r.nextFloat(), 0, 0, 0);
|
||||
}
|
||||
|
||||
private void applyRecipe() {
|
||||
|
@ -177,10 +186,12 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
|
||||
List<ItemStack> list = new ArrayList<>();
|
||||
if (recipe.isPresent()) {
|
||||
int rolls = inventory.getStackInSlot(0).getCount();
|
||||
int rolls = inventory.getStackInSlot(0)
|
||||
.getCount();
|
||||
inventory.clear();
|
||||
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++) {
|
||||
ItemStack stack = rolledResults.get(i);
|
||||
ItemHelper.addToList(stack, list);
|
||||
|
@ -195,10 +206,11 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
}
|
||||
|
||||
public Optional<ProcessingRecipe<RecipeWrapper>> findRecipe() {
|
||||
Optional<ProcessingRecipe<RecipeWrapper>> crushingRecipe =
|
||||
world.getRecipeManager().getRecipe(AllRecipeTypes.CRUSHING.getType(), wrapper, world);
|
||||
Optional<ProcessingRecipe<RecipeWrapper>> crushingRecipe = world.getRecipeManager()
|
||||
.getRecipe(AllRecipeTypes.CRUSHING.getType(), wrapper, world);
|
||||
if (!crushingRecipe.isPresent())
|
||||
crushingRecipe = world.getRecipeManager().getRecipe(AllRecipeTypes.MILLING.getType(), wrapper, world);
|
||||
crushingRecipe = world.getRecipeManager()
|
||||
.getRecipe(AllRecipeTypes.MILLING.getType(), wrapper, world);
|
||||
return crushingRecipe;
|
||||
}
|
||||
|
||||
|
@ -231,7 +243,8 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen
|
|||
|
||||
private void itemInserted(ItemStack stack) {
|
||||
Optional<ProcessingRecipe<RecipeWrapper>> recipe = findRecipe();
|
||||
inventory.remainingTime = recipe.isPresent() ? recipe.get().getProcessingDuration() : 100;
|
||||
inventory.remainingTime = recipe.isPresent() ? recipe.get()
|
||||
.getProcessingDuration() : 100;
|
||||
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;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllShapes;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.content.contraptions.base.HorizontalKineticBlock;
|
||||
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.item.ItemHelper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
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.VoxelShape;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class MechanicalPressBlock extends HorizontalKineticBlock
|
||||
implements ITE<MechanicalPressTileEntity>, IBeltAttachment {
|
||||
implements ITE<MechanicalPressTileEntity> {
|
||||
|
||||
public MechanicalPressBlock(Properties properties) {
|
||||
super(properties);
|
||||
|
@ -93,95 +80,6 @@ public class MechanicalPressBlock extends HorizontalKineticBlock
|
|||
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
|
||||
public Class<MechanicalPressTileEntity> getTileEntityClass() {
|
||||
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.foundation.advancement.AllTriggers;
|
||||
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 net.minecraft.entity.Entity;
|
||||
|
@ -59,6 +61,8 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
|||
}
|
||||
|
||||
private static PressingInv pressingInv = new PressingInv();
|
||||
public BeltProcessingBehaviour processingBehaviour;
|
||||
|
||||
public int runningTicks;
|
||||
public boolean running;
|
||||
public Mode mode;
|
||||
|
@ -69,6 +73,15 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
|||
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
|
||||
public void read(CompoundNBT compound) {
|
||||
running = compound.getBoolean("Running");
|
||||
|
@ -105,7 +118,8 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
|||
|
||||
@Override
|
||||
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) {
|
||||
|
@ -116,7 +130,7 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
|||
}
|
||||
if (runningTicks >= 40) {
|
||||
return MathHelper.clamp(((60 - runningTicks) + 1 - partialTicks) / 20f * mode.headOffset, 0,
|
||||
mode.headOffset);
|
||||
mode.headOffset);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -180,7 +194,8 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
|||
if (basinInv.isPresent() && orElse instanceof BasinInventory) {
|
||||
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);
|
||||
if (stackInSlot.isEmpty())
|
||||
continue;
|
||||
|
@ -194,9 +209,9 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
|||
|
||||
if (!world.isRemote) {
|
||||
world.playSound(null, getPos(), AllSoundEvents.MECHANICAL_PRESS_ITEM_BREAK.get(), SoundCategory.BLOCKS,
|
||||
.5f, 1f);
|
||||
.5f, 1f);
|
||||
world.playSound(null, getPos(), AllSoundEvents.MECHANICAL_PRESS_ACTIVATION.get(), SoundCategory.BLOCKS,
|
||||
.125f, 1f);
|
||||
.125f, 1f);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,12 +244,12 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
|||
pressedItems.forEach(stack -> makeCompactingParticleEffect(VecHelper.getCenterOf(pos.down(2)), stack));
|
||||
}
|
||||
if (mode == Mode.BELT) {
|
||||
pressedItems.forEach(
|
||||
stack -> makePressingParticleEffect(VecHelper.getCenterOf(pos.down(2)).add(0, 8 / 16f, 0), stack));
|
||||
pressedItems.forEach(stack -> makePressingParticleEffect(VecHelper.getCenterOf(pos.down(2))
|
||||
.add(0, 8 / 16f, 0), stack));
|
||||
}
|
||||
if (mode == Mode.WORLD) {
|
||||
pressedItems.forEach(
|
||||
stack -> makePressingParticleEffect(VecHelper.getCenterOf(pos.down(1)).add(0, -1 / 4f, 0), stack));
|
||||
pressedItems.forEach(stack -> makePressingParticleEffect(VecHelper.getCenterOf(pos.down(1))
|
||||
.add(0, -1 / 4f, 0), stack));
|
||||
}
|
||||
|
||||
pressedItems.clear();
|
||||
|
@ -243,9 +258,10 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
|||
public void makePressingParticleEffect(Vec3d pos, ItemStack stack) {
|
||||
if (world.isRemote) {
|
||||
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,
|
||||
motion.y + .125f, motion.z);
|
||||
motion.y + .125f, motion.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -253,23 +269,24 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
|||
public void makeCompactingParticleEffect(Vec3d pos, ItemStack stack) {
|
||||
if (world.isRemote) {
|
||||
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,
|
||||
motion.y + .25f, motion.z);
|
||||
motion.y + .25f, motion.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<PressingRecipe> getRecipe(ItemStack item) {
|
||||
pressingInv.setInventorySlotContents(0, item);
|
||||
Optional<PressingRecipe> recipe =
|
||||
world.getRecipeManager().getRecipe(AllRecipeTypes.PRESSING.getType(), pressingInv, world);
|
||||
Optional<PressingRecipe> recipe = world.getRecipeManager()
|
||||
.getRecipe(AllRecipeTypes.PRESSING.getType(), pressingInv, world);
|
||||
return recipe;
|
||||
}
|
||||
|
||||
public static boolean canCompress(NonNullList<Ingredient> ingredients) {
|
||||
return (ingredients.size() == 4 || ingredients.size() == 9)
|
||||
&& ItemHelper.condenseIngredients(ingredients).size() == 1;
|
||||
return (ingredients.size() == 4 || ingredients.size() == 9) && ItemHelper.condenseIngredients(ingredients)
|
||||
.size() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -283,7 +300,8 @@ public class MechanicalPressTileEntity extends BasinOperatingTileEntity {
|
|||
return false;
|
||||
|
||||
NonNullList<Ingredient> ingredients = recipe.getIngredients();
|
||||
if (!ingredients.stream().allMatch(Ingredient::isSimple))
|
||||
if (!ingredients.stream()
|
||||
.allMatch(Ingredient::isSimple))
|
||||
return false;
|
||||
|
||||
List<ItemStack> remaining = new ArrayList<>();
|
||||
|
|
|
@ -61,18 +61,25 @@ public class SawRenderer extends SafeTileEntityRenderer<SawTileEntity> {
|
|||
if (te.getSpeed() < 0 ^ alongZ)
|
||||
offset = 1 - offset;
|
||||
|
||||
ItemStack stack = te.inventory.getStackInSlot(0);
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
||||
IBakedModel modelWithOverrides = itemRenderer.getItemModelWithOverrides(stack, te.getWorld(), null);
|
||||
boolean blockItem = modelWithOverrides.isGui3d();
|
||||
|
||||
ms.translate(alongZ ? offset : .5, blockItem ? .925f : 13f / 16f, alongZ ? .5 : offset);
|
||||
|
||||
ms.scale(.5f, .5f, .5f);
|
||||
if (alongZ)
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(90));
|
||||
ms.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(90));
|
||||
itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED, light, overlay, ms, buffer);
|
||||
for (int i = 0; i < te.inventory.getSlots(); i++) {
|
||||
ItemStack stack = te.inventory.getStackInSlot(i);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
|
||||
IBakedModel modelWithOverrides = itemRenderer.getItemModelWithOverrides(stack, te.getWorld(), null);
|
||||
boolean blockItem = modelWithOverrides.isGui3d();
|
||||
|
||||
ms.translate(alongZ ? offset : .5, blockItem ? .925f : 13f / 16f, alongZ ? .5 : offset);
|
||||
|
||||
ms.scale(.5f, .5f, .5f);
|
||||
if (alongZ)
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(90));
|
||||
ms.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(90));
|
||||
itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED, light, overlay, ms, buffer);
|
||||
break;
|
||||
}
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,13 +8,12 @@ import java.util.List;
|
|||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllRecipeTypes;
|
||||
import com.simibubi.create.content.contraptions.components.actors.BlockBreakingKineticTileEntity;
|
||||
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.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.utility.BlockHelper;
|
||||
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.ParticleTypes;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -78,6 +76,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
|||
super.addBehaviours(behaviours);
|
||||
filtering = new FilteringBehaviour(this, new SawFilterSlot());
|
||||
behaviours.add(filtering);
|
||||
behaviours.add(new DirectBeltInputBehaviour(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -142,81 +141,51 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
|||
|
||||
Vec3d itemMovement = getItemMovementVec();
|
||||
Direction itemMovementFacing = Direction.getFacingFromVector(itemMovement.x, itemMovement.y, itemMovement.z);
|
||||
Vec3d outPos = VecHelper.getCenterOf(pos).add(itemMovement.scale(.5f).add(0, .5, 0));
|
||||
Vec3d outMotion = itemMovement.scale(.0625).add(0, .125, 0);
|
||||
if (inventory.remainingTime > 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);
|
||||
if (AllBlocks.BELT.has(world.getBlockState(nextPos))) {
|
||||
TileEntity te = world.getTileEntity(nextPos);
|
||||
if (te != null && te instanceof BeltTileEntity) {
|
||||
for (int slot = 0; slot < inventory.getSlots(); slot++) {
|
||||
ItemStack stack = inventory.getStackInSlot(slot);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
|
||||
if (((BeltTileEntity) te).tryInsertingFromSide(itemMovementFacing, 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;
|
||||
|
||||
ProcessingInventory sawInv = sawTileEntity.inventory;
|
||||
if (sawInv.isEmpty()) {
|
||||
sawInv.insertItem(0, stack, false);
|
||||
inventory.setStackInSlot(slot, ItemStack.EMPTY);
|
||||
|
||||
} else {
|
||||
inventory.remainingTime = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
inventory.clear();
|
||||
inventory.remainingTime = -1;
|
||||
sendData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Eject Items
|
||||
BlockPos nextPos = pos.add(itemMovement.x, itemMovement.y, itemMovement.z);
|
||||
DirectBeltInputBehaviour behaviour = TileEntityBehaviour.get(world, nextPos, DirectBeltInputBehaviour.TYPE);
|
||||
if (behaviour != null) {
|
||||
boolean changed = false;
|
||||
if (!behaviour.canInsertFromSide(itemMovementFacing))
|
||||
return;
|
||||
for (int slot = 0; slot < inventory.getSlots(); slot++) {
|
||||
ItemStack stack = inventory.getStackInSlot(slot);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
ItemEntity entityIn = new ItemEntity(world, outPos.x, outPos.y, outPos.z, stack);
|
||||
entityIn.setMotion(outMotion);
|
||||
world.addEntity(entityIn);
|
||||
ItemStack remainder = behaviour.handleInsertion(stack, itemMovementFacing, false);
|
||||
if (remainder.equals(stack, false))
|
||||
continue;
|
||||
inventory.setStackInSlot(slot, remainder);
|
||||
changed = true;
|
||||
}
|
||||
if (changed) {
|
||||
markDirty();
|
||||
sendData();
|
||||
}
|
||||
inventory.clear();
|
||||
world.updateComparatorOutputLevel(pos, getBlockState().getBlock());
|
||||
inventory.remainingTime = -1;
|
||||
sendData();
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
// 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++) {
|
||||
ItemStack stack = inventory.getStackInSlot(slot);
|
||||
if (stack.isEmpty())
|
||||
continue;
|
||||
ItemEntity entityIn = new ItemEntity(world, outPos.x, outPos.y, outPos.z, stack);
|
||||
entityIn.setMotion(outMotion);
|
||||
world.addEntity(entityIn);
|
||||
}
|
||||
inventory.clear();
|
||||
world.updateComparatorOutputLevel(pos, getBlockState().getBlock());
|
||||
inventory.remainingTime = -1;
|
||||
sendData();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -240,8 +209,8 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
|||
IParticleData particleData = null;
|
||||
float speed = 1;
|
||||
if (stack.getItem() instanceof BlockItem)
|
||||
particleData =
|
||||
new BlockParticleData(ParticleTypes.BLOCK, ((BlockItem) stack.getItem()).getBlock().getDefaultState());
|
||||
particleData = new BlockParticleData(ParticleTypes.BLOCK, ((BlockItem) stack.getItem()).getBlock()
|
||||
.getDefaultState());
|
||||
else {
|
||||
particleData = new ItemParticleData(ParticleTypes.ITEM, stack);
|
||||
speed = .125f;
|
||||
|
@ -253,7 +222,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
|||
float offset = inventory.recipeDuration != 0 ? (float) (inventory.remainingTime) / inventory.recipeDuration : 0;
|
||||
offset -= .5f;
|
||||
world.addParticle(particleData, pos.getX() + -vec.x * offset, pos.getY() + .45f, pos.getZ() + -vec.z * offset,
|
||||
-vec.x * speed, r.nextFloat() * speed, -vec.z * speed);
|
||||
-vec.x * speed, r.nextFloat() * speed, -vec.z * speed);
|
||||
}
|
||||
|
||||
public Vec3d getItemMovementVec() {
|
||||
|
@ -271,7 +240,8 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
|||
|
||||
IRecipe<?> recipe = recipes.get(recipeIndex);
|
||||
|
||||
int rolls = inventory.getStackInSlot(0).getCount();
|
||||
int rolls = inventory.getStackInSlot(0)
|
||||
.getCount();
|
||||
inventory.clear();
|
||||
|
||||
List<ItemStack> list = new ArrayList<>();
|
||||
|
@ -280,7 +250,8 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
|||
if (recipe instanceof CuttingRecipe)
|
||||
results = ((CuttingRecipe) recipe).rollResults();
|
||||
else if (recipe instanceof StonecuttingRecipe)
|
||||
results.add(recipe.getRecipeOutput().copy());
|
||||
results.add(recipe.getRecipeOutput()
|
||||
.copy());
|
||||
|
||||
for (int i = 0; i < results.size(); i++) {
|
||||
ItemStack stack = results.get(i);
|
||||
|
@ -294,10 +265,11 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
|||
|
||||
private List<? extends IRecipe<?>> getRecipes() {
|
||||
List<IRecipe<?>> startedSearch = RecipeFinder.get(cuttingRecipesKey, world,
|
||||
RecipeConditions.isOfType(IRecipeType.STONECUTTING, AllRecipeTypes.CUTTING.getType()));
|
||||
return startedSearch.stream().filter(RecipeConditions.outputMatchesFilter(filtering))
|
||||
.filter(RecipeConditions.firstIngredientMatches(inventory.getStackInSlot(0)))
|
||||
.collect(Collectors.toList());
|
||||
RecipeConditions.isOfType(IRecipeType.STONECUTTING, AllRecipeTypes.CUTTING.getType()));
|
||||
return startedSearch.stream()
|
||||
.filter(RecipeConditions.outputMatchesFilter(filtering))
|
||||
.filter(RecipeConditions.firstIngredientMatches(inventory.getStackInSlot(0)))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void insertItem(ItemEntity entity) {
|
||||
|
@ -309,7 +281,8 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
|||
return;
|
||||
|
||||
inventory.clear();
|
||||
inventory.insertItem(0, entity.getItem().copy(), false);
|
||||
inventory.insertItem(0, entity.getItem()
|
||||
.copy(), false);
|
||||
entity.remove();
|
||||
}
|
||||
|
||||
|
@ -357,7 +330,9 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
|
|||
|
||||
@Override
|
||||
protected boolean shouldRun() {
|
||||
return getBlockState().get(SawBlock.FACING).getAxis().isHorizontal();
|
||||
return getBlockState().get(SawBlock.FACING)
|
||||
.getAxis()
|
||||
.isHorizontal();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package com.simibubi.create.content.contraptions.processing;
|
||||
|
||||
import java.util.List;
|
||||
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.nbt.CompoundNBT;
|
||||
|
@ -19,7 +22,7 @@ import net.minecraftforge.items.ItemStackHandler;
|
|||
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
|
||||
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||
|
||||
public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
||||
public class BasinTileEntity extends SmartTileEntity implements ITickableTileEntity {
|
||||
|
||||
public boolean contentsChanged;
|
||||
|
||||
|
@ -96,7 +99,12 @@ public class BasinTileEntity extends SyncedTileEntity implements ITickableTileEn
|
|||
contentsChanged = true;
|
||||
recipeInventory = new BasinInputInventory();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
behaviours.add(new DirectBeltInputBehaviour(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundNBT 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
|
||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
updateNeighbouringTunnel(worldIn, pos, state);
|
||||
withTileEntityDo(worldIn, pos, te -> {
|
||||
te.attachmentTracker.findAttachments(te);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -109,7 +109,7 @@ public class BeltRenderer extends SafeTileEntityRenderer<BeltTileEntity> {
|
|||
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
|
||||
boolean slopeAlongX = te.getBeltFacing().getAxis() == Axis.X;
|
||||
|
||||
for (TransportedItemStack transported : te.getInventory().getItems()) {
|
||||
for (TransportedItemStack transported : te.getInventory().getTransportedItems()) {
|
||||
ms.push();
|
||||
MatrixStacker.of(ms).nudge(transported.angle);
|
||||
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.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.Slope;
|
||||
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.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.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -46,7 +48,6 @@ import net.minecraftforge.items.IItemHandler;
|
|||
public class BeltTileEntity extends KineticTileEntity {
|
||||
|
||||
public Map<Entity, TransportedEntityInfo> passengers;
|
||||
public AllBeltAttachments.Tracker attachmentTracker;
|
||||
public int color;
|
||||
public int beltLength;
|
||||
public int index;
|
||||
|
@ -61,11 +62,18 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
public BeltTileEntity(TileEntityType<? extends BeltTileEntity> type) {
|
||||
super(type);
|
||||
controller = BlockPos.ZERO;
|
||||
attachmentTracker = new Tracker(this);
|
||||
itemHandler = LazyOptional.empty();
|
||||
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
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
@ -75,12 +83,6 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
BeltBlock.initBelt(world, pos);
|
||||
if (!AllBlocks.BELT.has(world.getBlockState(pos)))
|
||||
return;
|
||||
|
||||
// Initialize Belt Attachments
|
||||
if (world != null && trackerUpdateTag != null) {
|
||||
attachmentTracker.readAndSearch(trackerUpdateTag, this);
|
||||
trackerUpdateTag = null;
|
||||
}
|
||||
if (getSpeed() == 0)
|
||||
return;
|
||||
|
||||
|
@ -136,7 +138,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
BeltInventory inventory = ((BeltTileEntity) te).getInventory();
|
||||
if (inventory == null)
|
||||
return;
|
||||
IItemHandler handler = inventory.createHandlerForSegment(index);
|
||||
IItemHandler handler = new ItemHandlerBeltSegment(inventory, index);
|
||||
itemHandler = LazyOptional.of(() -> handler);
|
||||
}
|
||||
|
||||
|
@ -163,8 +165,6 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
|
||||
@Override
|
||||
public CompoundNBT write(CompoundNBT compound) {
|
||||
attachmentTracker.write(compound);
|
||||
|
||||
if (controller != null)
|
||||
compound.put("Controller", NBTUtil.writeBlockPos(controller));
|
||||
compound.putBoolean("IsController", isController());
|
||||
|
@ -246,7 +246,8 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
}
|
||||
|
||||
public float getDirectionAwareBeltMovementSpeed() {
|
||||
int offset = getBeltFacing().getAxisDirection().getOffset();
|
||||
int offset = getBeltFacing().getAxisDirection()
|
||||
.getOffset();
|
||||
if (getBeltFacing().getAxis() == Axis.X)
|
||||
offset *= -1;
|
||||
return getBeltMovementSpeed() * offset;
|
||||
|
@ -270,8 +271,8 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
if (part == MIDDLE)
|
||||
return false;
|
||||
|
||||
boolean movingPositively =
|
||||
(getSpeed() > 0 == (direction.getAxisDirection().getOffset() == 1)) ^ direction.getAxis() == Axis.X;
|
||||
boolean movingPositively = (getSpeed() > 0 == (direction.getAxisDirection()
|
||||
.getOffset() == 1)) ^ direction.getAxis() == Axis.X;
|
||||
return part == Part.START ^ movingPositively;
|
||||
}
|
||||
|
||||
|
@ -311,8 +312,8 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
|
||||
public Direction getMovementFacing() {
|
||||
Axis axis = getBeltFacing().getAxis();
|
||||
return Direction
|
||||
.getFacingFromAxisDirection(axis, getBeltMovementSpeed() < 0 ^ axis == Axis.X ? NEGATIVE : POSITIVE);
|
||||
return Direction.getFacingFromAxisDirection(axis,
|
||||
getBeltMovementSpeed() < 0 ^ axis == Axis.X ? NEGATIVE : POSITIVE);
|
||||
}
|
||||
|
||||
protected Direction getBeltFacing() {
|
||||
|
@ -332,29 +333,39 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
return inventory;
|
||||
}
|
||||
|
||||
/**
|
||||
* always target a DirectBeltInsertionBehaviour
|
||||
*/
|
||||
@Deprecated
|
||||
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();
|
||||
ItemStack inserted = transportedStack.stack;
|
||||
ItemStack empty = ItemStack.EMPTY;
|
||||
|
||||
if (nextBeltController == null)
|
||||
return false;
|
||||
return inserted;
|
||||
BeltInventory nextInventory = nextBeltController.getInventory();
|
||||
|
||||
if (getSpeed() == 0)
|
||||
return false;
|
||||
if (!nextInventory.canInsertFrom(index, side))
|
||||
return false;
|
||||
return inserted;
|
||||
if (!nextInventory.canInsertAtFromSide(index, side))
|
||||
return inserted;
|
||||
if (simulate)
|
||||
return true;
|
||||
return empty;
|
||||
|
||||
transportedStack = transportedStack.copy();
|
||||
transportedStack.beltPosition = index + .5f - Math.signum(getDirectionAwareBeltMovementSpeed()) / 16f;
|
||||
|
||||
Direction movementFacing = getMovementFacing();
|
||||
if (!side.getAxis().isVertical()) {
|
||||
if (!side.getAxis()
|
||||
.isVertical()) {
|
||||
if (movementFacing != side) {
|
||||
transportedStack.sideOffset = side.getAxisDirection().getOffset() * .35f;
|
||||
transportedStack.sideOffset = side.getAxisDirection()
|
||||
.getOffset() * .35f;
|
||||
if (side.getAxis() == Axis.X)
|
||||
transportedStack.sideOffset *= -1;
|
||||
} else
|
||||
|
@ -368,8 +379,7 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
nextInventory.addItem(transportedStack);
|
||||
nextBeltController.markDirty();
|
||||
nextBeltController.sendData();
|
||||
|
||||
return true;
|
||||
return empty;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
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.Collections;
|
||||
import java.util.Iterator;
|
||||
|
@ -8,32 +10,26 @@ import java.util.List;
|
|||
import java.util.function.Function;
|
||||
|
||||
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.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 com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
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 net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
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 {
|
||||
|
||||
|
@ -52,9 +48,9 @@ public class BeltInventory {
|
|||
public void tick() {
|
||||
|
||||
// Reverse item collection if belt just reversed
|
||||
if (beltMovementPositive != movingPositive()) {
|
||||
beltMovementPositive = movingPositive();
|
||||
Collections.reverse(getItems());
|
||||
if (beltMovementPositive != belt.getDirectionAwareBeltMovementSpeed() > 0) {
|
||||
beltMovementPositive = !beltMovementPositive;
|
||||
Collections.reverse(items);
|
||||
belt.markDirty();
|
||||
belt.sendData();
|
||||
}
|
||||
|
@ -69,23 +65,31 @@ public class BeltInventory {
|
|||
|
||||
// Assuming the first entry is furthest on the belt
|
||||
TransportedItemStack stackInFront = null;
|
||||
TransportedItemStack current = null;
|
||||
Iterator<TransportedItemStack> iterator = getItems().iterator();
|
||||
TransportedItemStack currentItem = null;
|
||||
Iterator<TransportedItemStack> iterator = items.iterator();
|
||||
|
||||
// Useful stuff
|
||||
float beltSpeed = belt.getDirectionAwareBeltMovementSpeed();
|
||||
Direction movementFacing = belt.getMovementFacing();
|
||||
boolean horizontal = belt.getBlockState()
|
||||
.get(BeltBlock.SLOPE) == Slope.HORIZONTAL;
|
||||
float spacing = 1;
|
||||
boolean onClient = belt.getWorld().isRemote;
|
||||
World world = belt.getWorld();
|
||||
boolean onClient = world.isRemote;
|
||||
|
||||
Items: while (iterator.hasNext()) {
|
||||
stackInFront = current;
|
||||
current = iterator.next();
|
||||
current.prevBeltPosition = current.beltPosition;
|
||||
current.prevSideOffset = current.sideOffset;
|
||||
// resolve ending only when items will reach it this tick
|
||||
Ending ending = Ending.UNRESOLVED;
|
||||
|
||||
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();
|
||||
current = null;
|
||||
currentItem = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -93,12 +97,12 @@ public class BeltInventory {
|
|||
if (onClient)
|
||||
movement *= ServerSpeedProvider.get();
|
||||
|
||||
// Don't move if locked
|
||||
if (onClient && current.locked)
|
||||
// Don't move if held by processing (client)
|
||||
if (onClient && currentItem.locked)
|
||||
continue;
|
||||
|
||||
// Don't move if other items are waiting in front
|
||||
float currentPos = current.beltPosition;
|
||||
float currentPos = currentItem.beltPosition;
|
||||
if (stackInFront != null) {
|
||||
float diff = stackInFront.beltPosition - currentPos;
|
||||
if (Math.abs(diff) <= spacing)
|
||||
|
@ -107,236 +111,182 @@ public class BeltInventory {
|
|||
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
|
||||
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 =
|
||||
beltMovementPositive ? Math.min(movement, diffToEnd) : Math.max(movement, diffToEnd);
|
||||
float nextOffset = current.beltPosition + limitedMovement;
|
||||
float nextOffset = currentItem.beltPosition + limitedMovement;
|
||||
|
||||
if (!onClient && segmentBefore != -1) {
|
||||
// Don't move if belt attachments want to continue processing
|
||||
if (current.locked) {
|
||||
BeltTileEntity beltSegment = BeltHelper.getBeltAtSegment(belt, segmentBefore);
|
||||
if (beltSegment != null) {
|
||||
|
||||
// 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();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// See if any new belt processing catches the item
|
||||
if (current.beltPosition > .5f || beltMovementPositive) {
|
||||
int firstUpcomingSegment = (int) (current.beltPosition + (beltMovementPositive ? .5f : -.5f));
|
||||
for (int segment = firstUpcomingSegment; beltMovementPositive ? segment + .5f <= nextOffset
|
||||
: segment + .5f >= nextOffset; segment += beltMovementPositive ? 1 : -1) {
|
||||
BeltTileEntity beltSegment = BeltHelper.getBeltAtSegment(belt, segment);
|
||||
if (beltSegment == null)
|
||||
break;
|
||||
for (BeltAttachmentState attachmentState : beltSegment.attachmentTracker.attachments) {
|
||||
ItemStack stackBefore = current.stack.copy();
|
||||
if (attachmentState.attachment.startProcessingItem(beltSegment, current, attachmentState)) {
|
||||
current.beltPosition = segment + .5f + (beltMovementPositive ? 1 / 64f : -1 / 64f);
|
||||
current.locked = true;
|
||||
belt.sendData();
|
||||
continue Items;
|
||||
}
|
||||
if (!stackBefore.equals(current.stack, true))
|
||||
belt.sendData();
|
||||
}
|
||||
}
|
||||
// Belt item processing
|
||||
if (!onClient && horizontal) {
|
||||
ItemStack item = currentItem.stack;
|
||||
if (handleBeltProcessingAndCheckIfRemoved(currentItem, nextOffset)) {
|
||||
iterator.remove();
|
||||
belt.sendData();
|
||||
continue;
|
||||
}
|
||||
if (item != currentItem.stack)
|
||||
belt.sendData();
|
||||
if (currentItem.locked)
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Belt Tunnels
|
||||
BeltTunnelInteractionHandler.flapTunnelsAndCheckIfStuck(this, currentItem, nextOffset);
|
||||
|
||||
// Apply Movement
|
||||
current.beltPosition += limitedMovement;
|
||||
current.sideOffset += (current.getTargetSideOffset() - current.sideOffset) * Math.abs(limitedMovement) * 2f;
|
||||
currentPos = current.beltPosition;
|
||||
currentItem.beltPosition += limitedMovement;
|
||||
currentItem.sideOffset +=
|
||||
(currentItem.getTargetSideOffset() - currentItem.sideOffset) * Math.abs(limitedMovement) * 2f;
|
||||
currentPos = currentItem.beltPosition;
|
||||
|
||||
// Determine segment after movement
|
||||
int segmentAfter = (int) currentPos;
|
||||
min = segmentAfter + .5f - (SEGMENT_WINDOW / 2);
|
||||
max = segmentAfter + .5f + (SEGMENT_WINDOW / 2);
|
||||
if (currentPos < min || currentPos > max)
|
||||
segmentAfter = -1;
|
||||
|
||||
// Item changed segments
|
||||
World world = belt.getWorld();
|
||||
if (segmentBefore != segmentAfter) {
|
||||
for (int segment : new int[] { segmentBefore, segmentAfter }) {
|
||||
if (segment == -1)
|
||||
continue;
|
||||
if (!world.isRemote)
|
||||
world
|
||||
.updateComparatorOutputLevel(BeltHelper.getPositionForOffset(belt, segment),
|
||||
belt.getBlockState().getBlock());
|
||||
}
|
||||
}
|
||||
// Movement successful
|
||||
if (limitedMovement == movement || onClient)
|
||||
continue;
|
||||
|
||||
// End reached
|
||||
if (limitedMovement != movement) {
|
||||
if (world.isRemote)
|
||||
continue;
|
||||
|
||||
int lastOffset = beltMovementPositive ? belt.beltLength - 1 : 0;
|
||||
BlockPos nextPosition =
|
||||
BeltHelper.getPositionForOffset(belt, beltMovementPositive ? belt.beltLength : -1);
|
||||
BlockState state = world.getBlockState(nextPosition);
|
||||
|
||||
// next block is a basin or a saw
|
||||
if (AllBlocks.BASIN.has(state) || AllBlocks.MECHANICAL_SAW.has(state)
|
||||
|| 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;
|
||||
if (remainder.isEmpty()) {
|
||||
iterator.remove();
|
||||
current = null;
|
||||
flapTunnel(lastOffset, movementFacing, false);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
protected boolean handleBeltProcessingAndCheckIfRemoved(TransportedItemStack currentItem, float nextOffset) {
|
||||
int currentSegment = (int) currentItem.beltPosition;
|
||||
|
||||
Direction flapFacing = movementDirection.getOpposite();
|
||||
// Continue processing if held
|
||||
if (currentItem.locked) {
|
||||
BeltProcessingBehaviour processingBehaviour = getBeltProcessingAtSegment(currentSegment);
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
if (heldItem == ItemStack.EMPTY) {
|
||||
tunnel.syncedFlaps.put(flapFacing, stack);
|
||||
return true;
|
||||
|
||||
// See if any new belt processing catches the item
|
||||
if (currentItem.beltPosition > .5f || beltMovementPositive) {
|
||||
int firstUpcomingSegment = (int) (currentItem.beltPosition + (beltMovementPositive ? .5f : -.5f));
|
||||
int step = beltMovementPositive ? 1 : -1;
|
||||
|
||||
for (int segment = firstUpcomingSegment; beltMovementPositive ? segment + .5f <= nextOffset
|
||||
: segment + .5f >= nextOffset; segment += step) {
|
||||
|
||||
BeltProcessingBehaviour processingBehaviour = getBeltProcessingAtSegment(segment);
|
||||
if (processingBehaviour == null)
|
||||
continue;
|
||||
|
||||
ProcessingResult result = processingBehaviour.handleReceivedItem(currentItem, this);
|
||||
if (result == ProcessingResult.REMOVE)
|
||||
return true;
|
||||
|
||||
if (result == ProcessingResult.HOLD) {
|
||||
currentItem.beltPosition = segment + .5f + (beltMovementPositive ? 1 / 64f : -1 / 64f);
|
||||
currentItem.locked = true;
|
||||
belt.sendData();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
protected BeltProcessingBehaviour getBeltProcessingAtSegment(int segment) {
|
||||
return TileEntityBehaviour.get(belt.getWorld(), BeltHelper.getPositionForOffset(belt, segment)
|
||||
.up(2), BeltProcessingBehaviour.TYPE);
|
||||
}
|
||||
|
||||
private enum Ending {
|
||||
UNRESOLVED(0), EJECT(0), INSERT(.25f), FUNNEL(.35f), BLOCKED(.45f);
|
||||
|
||||
private float margin;
|
||||
|
||||
Ending(float f) {
|
||||
this.margin = f;
|
||||
}
|
||||
}
|
||||
|
||||
private Ending resolveEnding() {
|
||||
int lastOffset = beltMovementPositive ? belt.beltLength - 1 : 0;
|
||||
World world = belt.getWorld();
|
||||
BlockPos lastPosition = BeltHelper.getPositionForOffset(belt, lastOffset);
|
||||
BlockPos nextPosition = BeltHelper.getPositionForOffset(belt, beltMovementPositive ? belt.beltLength : -1);
|
||||
|
||||
if (AllBlocks.BELT_FUNNEL.has(world.getBlockState(lastPosition.up())))
|
||||
return Ending.FUNNEL;
|
||||
|
||||
DirectBeltInputBehaviour inputBehaviour =
|
||||
TileEntityBehaviour.get(world, nextPosition, DirectBeltInputBehaviour.TYPE);
|
||||
if (inputBehaviour != null)
|
||||
return Ending.INSERT;
|
||||
|
||||
if (Block.hasSolidSide(world.getBlockState(nextPosition), world, nextPosition, belt.getMovementFacing()
|
||||
.getOpposite()))
|
||||
return Ending.BLOCKED;
|
||||
|
||||
return Ending.EJECT;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
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;
|
||||
if (belt.getMovementFacing() == side.getOpposite())
|
||||
return false;
|
||||
|
@ -345,7 +295,7 @@ public class BeltInventory {
|
|||
else if (!beltMovementPositive)
|
||||
segmentPos += 1f;
|
||||
|
||||
for (TransportedItemStack stack : getItems())
|
||||
for (TransportedItemStack stack : items)
|
||||
if (isBlocking(segment, side, segmentPos, stack))
|
||||
return false;
|
||||
for (TransportedItemStack stack : toInsert)
|
||||
|
@ -358,7 +308,7 @@ public class BeltInventory {
|
|||
private boolean isBlocking(int segment, Direction side, float segmentPos, TransportedItemStack stack) {
|
||||
float currentPos = stack.beltPosition;
|
||||
if (stack.insertedAt == segment && stack.insertedFrom == side
|
||||
&& (beltMovementPositive ? currentPos <= segmentPos + 1 : currentPos >= segmentPos - 1))
|
||||
&& (beltMovementPositive ? currentPos <= segmentPos + 1 : currentPos >= segmentPos - 1))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -368,23 +318,23 @@ public class BeltInventory {
|
|||
}
|
||||
|
||||
private void insert(TransportedItemStack newStack) {
|
||||
if (getItems().isEmpty())
|
||||
getItems().add(newStack);
|
||||
if (items.isEmpty())
|
||||
items.add(newStack);
|
||||
else {
|
||||
int index = 0;
|
||||
for (TransportedItemStack stack : getItems()) {
|
||||
for (TransportedItemStack stack : items) {
|
||||
if (stack.compareTo(newStack) > 0 == beltMovementPositive)
|
||||
break;
|
||||
index++;
|
||||
}
|
||||
getItems().add(index, newStack);
|
||||
items.add(index, newStack);
|
||||
}
|
||||
}
|
||||
|
||||
public TransportedItemStack getStackAtOffset(int offset) {
|
||||
float min = offset + .5f - (SEGMENT_WINDOW / 2);
|
||||
float max = offset + .5f + (SEGMENT_WINDOW / 2);
|
||||
for (TransportedItemStack stack : getItems()) {
|
||||
for (TransportedItemStack stack : items) {
|
||||
if (stack.beltPosition > max)
|
||||
continue;
|
||||
if (stack.beltPosition > min)
|
||||
|
@ -394,17 +344,16 @@ public class BeltInventory {
|
|||
}
|
||||
|
||||
public void read(CompoundNBT nbt) {
|
||||
getItems().clear();
|
||||
nbt
|
||||
.getList("Items", NBT.TAG_COMPOUND)
|
||||
.forEach(inbt -> getItems().add(TransportedItemStack.read((CompoundNBT) inbt)));
|
||||
items.clear();
|
||||
nbt.getList("Items", NBT.TAG_COMPOUND)
|
||||
.forEach(inbt -> items.add(TransportedItemStack.read((CompoundNBT) inbt)));
|
||||
beltMovementPositive = nbt.getBoolean("PositiveOrder");
|
||||
}
|
||||
|
||||
public CompoundNBT write() {
|
||||
CompoundNBT nbt = new CompoundNBT();
|
||||
ListNBT itemsNBT = new ListNBT();
|
||||
getItems().forEach(stack -> itemsNBT.add(stack.serializeNBT()));
|
||||
items.forEach(stack -> itemsNBT.add(stack.serializeNBT()));
|
||||
nbt.put("Items", itemsNBT);
|
||||
nbt.putBoolean("PositiveOrder", beltMovementPositive);
|
||||
return nbt;
|
||||
|
@ -414,33 +363,27 @@ public class BeltInventory {
|
|||
ItemStack ejected = stack.stack;
|
||||
Vec3d outPos = BeltHelper.getVectorForOffset(belt, stack.beltPosition);
|
||||
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());
|
||||
ItemEntity entity = new ItemEntity(belt.getWorld(), outPos.x, outPos.y + 6 / 16f, outPos.z, ejected);
|
||||
entity.setMotion(outMotion);
|
||||
entity.setDefaultPickupDelay();
|
||||
entity.velocityChanged = true;
|
||||
belt.getWorld().addEntity(entity);
|
||||
belt.getWorld()
|
||||
.addEntity(entity);
|
||||
}
|
||||
|
||||
|
||||
public void ejectAll() {
|
||||
getItems().forEach(this::eject);
|
||||
getItems().clear();
|
||||
}
|
||||
|
||||
private boolean movingPositive() {
|
||||
return belt.getDirectionAwareBeltMovementSpeed() > 0;
|
||||
}
|
||||
|
||||
public IItemHandler createHandlerForSegment(int segment) {
|
||||
return new ItemHandlerBeltSegment(this, segment);
|
||||
items.forEach(this::eject);
|
||||
items.clear();
|
||||
}
|
||||
|
||||
public void forEachWithin(float position, float distance,
|
||||
Function<TransportedItemStack, List<TransportedItemStack>> callback) {
|
||||
Function<TransportedItemStack, List<TransportedItemStack>> callback) {
|
||||
List<TransportedItemStack> toBeAdded = new ArrayList<>();
|
||||
boolean dirty = false;
|
||||
for (Iterator<TransportedItemStack> iterator = getItems().iterator(); iterator.hasNext();) {
|
||||
for (Iterator<TransportedItemStack> iterator = items.iterator(); iterator.hasNext();) {
|
||||
TransportedItemStack transportedItemStack = iterator.next();
|
||||
if (Math.abs(position - transportedItemStack.beltPosition) < distance) {
|
||||
List<TransportedItemStack> apply = callback.apply(transportedItemStack);
|
||||
|
@ -458,7 +401,7 @@ public class BeltInventory {
|
|||
}
|
||||
}
|
||||
|
||||
public List<TransportedItemStack> getItems() {
|
||||
public List<TransportedItemStack> getTransportedItems() {
|
||||
return items;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import java.util.List;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
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.Part;
|
||||
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));
|
||||
}
|
||||
|
||||
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 Slope slope = blockState.get(BeltBlock.SLOPE);
|
||||
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;
|
||||
|
||||
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.foundation.tileEntity.TileEntityBehaviour;
|
||||
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.item.ItemStack;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public abstract class BeltAttachableLogisticalBlock extends AttachedLogisticalBlock implements IBeltAttachment {
|
||||
public abstract class BeltAttachableLogisticalBlock extends AttachedLogisticalBlock {
|
||||
|
||||
public BeltAttachableLogisticalBlock(Properties properties) {
|
||||
super(properties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
onAttachmentPlaced(worldIn, pos, state);
|
||||
}
|
||||
|
||||
@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()) {
|
||||
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
|
||||
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;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
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.Part;
|
||||
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.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.HorizontalBlock;
|
||||
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.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
|
@ -37,18 +25,13 @@ import net.minecraft.tileentity.TileEntity;
|
|||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
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.Vec3d;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
|
||||
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 BELT = BooleanProperty.create("belt");
|
||||
|
@ -138,23 +121,6 @@ public class BeltObserverBlock extends HorizontalBlock
|
|||
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
|
||||
public boolean canProvidePower(BlockState state) {
|
||||
return state.get(POWERED);
|
||||
|
@ -172,118 +138,12 @@ public class BeltObserverBlock extends HorizontalBlock
|
|||
|
||||
@Override
|
||||
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()) {
|
||||
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
|
||||
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
|
||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||
World world = context.getWorld();
|
||||
|
|
|
@ -106,7 +106,7 @@ public class ExtractorTileEntity extends SmartTileEntity {
|
|||
BeltInventory inventory = controller.getInventory();
|
||||
if (inventory == null)
|
||||
return false;
|
||||
if (!inventory.canInsertFrom(belt.index, Direction.UP))
|
||||
if (!inventory.canInsertAtFromSide(belt.index, Direction.UP))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
package com.simibubi.create.content.logistics.block.funnel;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllShapes;
|
||||
import com.simibubi.create.AllTileEntities;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.IPortableBlock;
|
||||
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.BeltTileEntity;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||
import com.simibubi.create.content.logistics.block.AttachedLogisticalBlock;
|
||||
import com.simibubi.create.foundation.block.ITE;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
|
@ -41,7 +36,7 @@ import net.minecraft.world.IWorld;
|
|||
import net.minecraft.world.World;
|
||||
|
||||
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 MovementBehaviour MOVEMENT = new FunnelMovementBehaviour();
|
||||
|
@ -131,7 +126,6 @@ public class FunnelBlock extends AttachedLogisticalBlock
|
|||
|
||||
@Override
|
||||
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||
onAttachmentPlaced(worldIn, pos, state);
|
||||
if (worldIn.isRemote)
|
||||
return;
|
||||
|
||||
|
@ -153,42 +147,12 @@ public class FunnelBlock extends AttachedLogisticalBlock
|
|||
|
||||
@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()) {
|
||||
TileEntityBehaviour.destroy(worldIn, pos, FilteringBehaviour.TYPE);
|
||||
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
|
||||
public ActionResultType onUse(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
|
||||
BlockRayTraceResult hit) {
|
||||
|
@ -207,16 +171,6 @@ public class FunnelBlock extends AttachedLogisticalBlock
|
|||
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 Vertical(Properties properties) {
|
||||
super(properties);
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
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.tileentity.ITickableTileEntity;
|
||||
|
@ -14,7 +14,7 @@ import net.minecraft.tileentity.TileEntityType;
|
|||
|
||||
public abstract class SmartTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
||||
|
||||
private Map<IBehaviourType<?>, TileEntityBehaviour> behaviours;
|
||||
private Map<BehaviourType<?>, TileEntityBehaviour> behaviours;
|
||||
private boolean initialized;
|
||||
private boolean firstNbtRead;
|
||||
private int lazyTickRate;
|
||||
|
@ -120,14 +120,14 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka
|
|||
behaviour.initialize();
|
||||
}
|
||||
|
||||
protected void removeBehaviour(IBehaviourType<?> type) {
|
||||
protected void removeBehaviour(BehaviourType<?> type) {
|
||||
TileEntityBehaviour remove = behaviours.remove(type);
|
||||
if (remove != null)
|
||||
remove.remove();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends TileEntityBehaviour> T getBehaviour(IBehaviourType<T> type) {
|
||||
protected <T extends TileEntityBehaviour> T getBehaviour(BehaviourType<T> type) {
|
||||
if (behaviours.containsKey(type))
|
||||
return (T) behaviours.get(type);
|
||||
return null;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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.nbt.CompoundNBT;
|
||||
|
@ -23,7 +23,7 @@ public abstract class TileEntityBehaviour {
|
|||
setLazyTickRate(10);
|
||||
}
|
||||
|
||||
public abstract IBehaviourType<?> getType();
|
||||
public abstract BehaviourType<?> getType();
|
||||
|
||||
public void initialize() {
|
||||
|
||||
|
@ -91,18 +91,18 @@ public abstract class TileEntityBehaviour {
|
|||
}
|
||||
|
||||
public static <T extends TileEntityBehaviour> T get(ILightReader reader, BlockPos pos,
|
||||
IBehaviourType<T> type) {
|
||||
BehaviourType<T> type) {
|
||||
return get(reader.getTileEntity(pos), type);
|
||||
}
|
||||
|
||||
public static <T extends TileEntityBehaviour> void destroy(ILightReader reader, BlockPos pos,
|
||||
IBehaviourType<T> type) {
|
||||
BehaviourType<T> type) {
|
||||
T behaviour = get(reader.getTileEntity(pos), type);
|
||||
if (behaviour != null)
|
||||
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)
|
||||
return null;
|
||||
if (!(te instanceof SmartTileEntity))
|
||||
|
|
|
@ -2,6 +2,6 @@ package com.simibubi.create.foundation.tileEntity.behaviour;
|
|||
|
||||
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.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.util.Direction;
|
||||
|
@ -13,8 +13,7 @@ import net.minecraft.world.World;
|
|||
|
||||
public class EdgeInteractionBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static IBehaviourType<EdgeInteractionBehaviour> TYPE = new IBehaviourType<EdgeInteractionBehaviour>() {
|
||||
};
|
||||
public static BehaviourType<EdgeInteractionBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
ConnectionCallback connectionCallback;
|
||||
ConnectivityPredicate connectivityPredicate;
|
||||
|
@ -38,7 +37,7 @@ public class EdgeInteractionBehaviour extends TileEntityBehaviour {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBehaviourType<?> getType() {
|
||||
public BehaviourType<?> getType() {
|
||||
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.tileEntity.SmartTileEntity;
|
||||
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.utility.VecHelper;
|
||||
|
||||
|
@ -20,8 +20,7 @@ import net.minecraft.world.World;
|
|||
|
||||
public class FilteringBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static IBehaviourType<FilteringBehaviour> TYPE = new IBehaviourType<FilteringBehaviour>() {
|
||||
};
|
||||
public static BehaviourType<FilteringBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
ValueBoxTransform slotPositioning;
|
||||
boolean showCount;
|
||||
|
@ -152,7 +151,7 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBehaviourType<?> getType() {
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import java.util.function.Supplier;
|
|||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
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.util.Direction;
|
||||
|
@ -15,8 +15,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
|
||||
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 timer;
|
||||
|
@ -85,7 +84,7 @@ public class AutoExtractingBehaviour extends ExtractingBehaviour {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBehaviourType<?> getType() {
|
||||
public BehaviourType<?> getType() {
|
||||
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.item.ItemHelper;
|
||||
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 net.minecraft.item.ItemStack;
|
||||
|
@ -21,8 +21,7 @@ import net.minecraftforge.items.IItemHandler;
|
|||
|
||||
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 Predicate<ItemStack> customFilter;
|
||||
|
@ -90,7 +89,7 @@ public class ExtractingBehaviour extends InventoryManagementBehaviour {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBehaviourType<?> getType() {
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.util.function.Supplier;
|
|||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
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.util.Direction;
|
||||
|
@ -16,8 +16,7 @@ import net.minecraftforge.items.ItemHandlerHelper;
|
|||
|
||||
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) {
|
||||
super(te, attachments);
|
||||
|
@ -33,7 +32,7 @@ public class InsertingBehaviour extends InventoryManagementBehaviour {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBehaviourType<?> getType() {
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
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.tileentity.TileEntity;
|
||||
|
@ -28,8 +28,7 @@ public class InventoryManagementBehaviour extends TileEntityBehaviour {
|
|||
private Supplier<List<Pair<BlockPos, Direction>>> attachments;
|
||||
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) {
|
||||
super(te);
|
||||
|
@ -98,7 +97,7 @@ public class InventoryManagementBehaviour extends TileEntityBehaviour {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBehaviourType<?> getType() {
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import java.util.function.Consumer;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
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.nbt.CompoundNBT;
|
||||
|
@ -13,16 +13,14 @@ import net.minecraft.util.math.BlockPos;
|
|||
|
||||
public class SingleTargetAutoExtractingBehaviour extends AutoExtractingBehaviour {
|
||||
|
||||
public static IBehaviourType<SingleTargetAutoExtractingBehaviour> TYPE =
|
||||
new IBehaviourType<SingleTargetAutoExtractingBehaviour>() {
|
||||
};
|
||||
public static BehaviourType<SingleTargetAutoExtractingBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
private Supplier<Direction> attachmentDirection;
|
||||
boolean synced;
|
||||
boolean advantageOnNextSync;
|
||||
|
||||
public SingleTargetAutoExtractingBehaviour(SmartTileEntity te, Supplier<Direction> attachmentDirection,
|
||||
Consumer<ItemStack> onExtract, int delay) {
|
||||
Consumer<ItemStack> onExtract, int delay) {
|
||||
super(te, Attachments.toward(attachmentDirection), onExtract, delay);
|
||||
this.attachmentDirection = attachmentDirection;
|
||||
synced = true;
|
||||
|
@ -49,7 +47,8 @@ public class SingleTargetAutoExtractingBehaviour extends AutoExtractingBehaviour
|
|||
@Override
|
||||
public boolean extract() {
|
||||
if (synced) {
|
||||
BlockPos invPos = tileEntity.getPos().offset(attachmentDirection.get());
|
||||
BlockPos invPos = tileEntity.getPos()
|
||||
.offset(attachmentDirection.get());
|
||||
return SynchronizedExtraction.extractSynchronized(getWorld(), invPos);
|
||||
} else
|
||||
return extractFromInventory();
|
||||
|
@ -60,7 +59,7 @@ public class SingleTargetAutoExtractingBehaviour extends AutoExtractingBehaviour
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBehaviourType<?> getType() {
|
||||
public BehaviourType<?> getType() {
|
||||
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.foundation.tileEntity.SmartTileEntity;
|
||||
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 net.minecraft.block.BlockState;
|
||||
|
@ -21,8 +21,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
|
||||
public class LinkBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static IBehaviourType<LinkBehaviour> TYPE = new IBehaviourType<LinkBehaviour>() {
|
||||
};
|
||||
public static BehaviourType<LinkBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
enum Mode {
|
||||
TRANSMIT, RECEIVE
|
||||
|
@ -162,7 +161,7 @@ public class LinkBehaviour extends TileEntityBehaviour {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBehaviourType<?> getType() {
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import java.util.function.Function;
|
|||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
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 net.minecraft.block.BlockState;
|
||||
|
@ -16,8 +16,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
|
||||
public class ScrollValueBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static IBehaviourType<ScrollValueBehaviour> TYPE = new IBehaviourType<ScrollValueBehaviour>() {
|
||||
};
|
||||
public static BehaviourType<ScrollValueBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
ValueBoxTransform slotPositioning;
|
||||
Vec3d textShift;
|
||||
|
@ -162,7 +161,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBehaviourType<?> getType() {
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,14 +4,13 @@ import java.util.function.Supplier;
|
|||
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
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;
|
||||
|
||||
public class DeferralBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static IBehaviourType<DeferralBehaviour> TYPE = new IBehaviourType<DeferralBehaviour>() {
|
||||
};
|
||||
public static BehaviourType<DeferralBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
private boolean needsUpdate;
|
||||
private Supplier<Boolean> callback;
|
||||
|
@ -45,7 +44,7 @@ public class DeferralBehaviour extends TileEntityBehaviour {
|
|||
}
|
||||
|
||||
@Override
|
||||
public IBehaviourType<?> getType() {
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue