Funnels for everybody

- Fixed flapfunnels not taking secondary items off depots
- Funnels can now sit horizontally on saws and drains
- Added a recipe from natural to regular scoria
This commit is contained in:
simibubi 2020-11-27 17:19:11 +01:00
parent bbe0914b2f
commit e7a22c96e9
14 changed files with 183 additions and 60 deletions

View file

@ -2096,6 +2096,7 @@ e340721aa78f260c2666214aa149241a37de216e data/create/advancements/recipes/create
070720cc271767b26ad51fa089b4cf2a64d309be data/create/advancements/recipes/create.palettes/smelting/gabbro.json
9a2901f6b918468b0034a8942178d6f3c82aeb6e data/create/advancements/recipes/create.palettes/smelting/limestone.json
c8fb5d555eacec479af4fa6b9042656f1fe49a2e data/create/advancements/recipes/create.palettes/smelting/scoria.json
c4f13a0ff5827570018515109c1eda0b3f2fb3bc data/create/advancements/recipes/create.palettes/smelting/scoria_from_natural.json
459538728b06d4c72d7e65d8f7c98a75a48f3a52 data/create/advancements/recipes/create.palettes/spruce_window.json
6aaf96cdaa845b63ab67ba4b968ea4d811e2fef5 data/create/advancements/recipes/create.palettes/spruce_window_pane.json
ab0cacba05f8def9cc91b993d464c297babf6fc3 data/create/advancements/recipes/create.palettes/tiled_glass_from_glass_colorless_stonecutting.json
@ -3211,6 +3212,7 @@ b032c79090adad2262ae94609e0b3747327d51a2 data/create/recipes/smelting/gold_ingot
fe3e4c244c34aa6948243fabd6b42f04f80d4992 data/create/recipes/smelting/iron_ingot_from_crushed.json
bf0e5df5a88e583e39a4e14b006cbf33b99611e1 data/create/recipes/smelting/limestone.json
2c230522bb0946bde6a51442cb15c5efeea99b15 data/create/recipes/smelting/scoria.json
f5317c85a9e10a5f9346e13aef8bb364a5203346 data/create/recipes/smelting/scoria_from_natural.json
a5d23be4cc959eb47d84b210190abaafcf41f022 data/create/recipes/smelting/zinc_ingot_from_crushed.json
2d8e448bbe841871c5d9a022149c5f34fd5c0df1 data/create/recipes/smelting/zinc_ingot_from_ore.json
ce7c3c6e1da9d6684c9537d1a558423925d89f33 data/create/recipes/smoking/bread.json

View file

@ -0,0 +1,32 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"create:smelting/scoria_from_natural"
]
},
"criteria": {
"has_item": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"item": "create:natural_scoria"
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "create:smelting/scoria_from_natural"
}
}
},
"requirements": [
[
"has_item",
"has_the_recipe"
]
]
}

View file

@ -0,0 +1,9 @@
{
"type": "minecraft:smelting",
"ingredient": {
"item": "create:natural_scoria"
},
"result": "create:scoria",
"experience": 0.0,
"cookingtime": 200
}

View file

@ -61,7 +61,6 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
private int recipeIndex;
private LazyOptional<IItemHandler> invProvider = LazyOptional.empty();
private FilteringBehaviour filtering;
private boolean destroyed;
public SawTileEntity(TileEntityType<? extends SawTileEntity> type) {
super(type);
@ -76,7 +75,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
super.addBehaviours(behaviours);
filtering = new FilteringBehaviour(this, new SawFilterSlot()).forRecipes();
behaviours.add(filtering);
behaviours.add(new DirectBeltInputBehaviour(this));
behaviours.add(new DirectBeltInputBehaviour(this).allowingBeltFunnelsWhen(this::canProcess));
}
@Override
@ -136,6 +135,19 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
return;
inventory.remainingTime = 0;
for (int slot = 0; slot < inventory.getSlots(); slot++) {
ItemStack stack = inventory.getStackInSlot(slot);
if (stack.isEmpty())
continue;
ItemStack tryExportingToBeltFunnel = getBehaviour(DirectBeltInputBehaviour.TYPE)
.tryExportingToBeltFunnel(stack, itemMovementFacing.getOpposite());
if (tryExportingToBeltFunnel.getCount() != stack.getCount()) {
inventory.setStackInSlot(slot, tryExportingToBeltFunnel);
notifyUpdate();
return;
}
}
BlockPos nextPos = pos.add(itemMovement.x, itemMovement.y, itemMovement.z);
DirectBeltInputBehaviour behaviour = TileEntityBehaviour.get(world, nextPos, DirectBeltInputBehaviour.TYPE);
if (behaviour != null) {
@ -182,7 +194,6 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity {
@Override
public void remove() {
invProvider.invalidate();
destroyed = true;
super.remove();
}

View file

@ -47,7 +47,8 @@ public class ItemDrainTileEntity extends SmartTileEntity {
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
behaviours.add(new DirectBeltInputBehaviour(this).setInsertionHandler(this::tryInsertingFromSide));
behaviours.add(new DirectBeltInputBehaviour(this).allowingBeltFunnels()
.setInsertionHandler(this::tryInsertingFromSide));
behaviours.add(internalTank = SmartFluidTankBehaviour.single(this, 1500)
.allowExtraction()
.forbidInsertion());
@ -112,6 +113,18 @@ public class ItemDrainTileEntity extends SmartTileEntity {
return;
Direction side = heldItem.insertedFrom;
ItemStack tryExportingToBeltFunnel = getBehaviour(DirectBeltInputBehaviour.TYPE)
.tryExportingToBeltFunnel(heldItem.stack, side.getOpposite());
if (tryExportingToBeltFunnel.getCount() != heldItem.stack.getCount()) {
if (tryExportingToBeltFunnel.isEmpty())
heldItem = null;
else
heldItem.stack = tryExportingToBeltFunnel;
notifyUpdate();
return;
}
BlockPos nextPosition = pos.offset(side);
DirectBeltInputBehaviour directBeltInputBehaviour =
TileEntityBehaviour.get(world, nextPosition, DirectBeltInputBehaviour.TYPE);

View file

@ -66,6 +66,8 @@ public class DepotTileEntity extends SmartTileEntity {
return;
if (world.isRemote)
return;
if (handleBeltFunnelOutput())
return;
BeltProcessingBehaviour processingBehaviour =
TileEntityBehaviour.get(world, pos.up(2), BeltProcessingBehaviour.TYPE);
@ -74,8 +76,8 @@ public class DepotTileEntity extends SmartTileEntity {
if (!heldItem.locked && BeltProcessingBehaviour.isBlocked(world, pos))
return;
boolean wasLocked = heldItem.locked;
ItemStack previousItem = heldItem.stack;
boolean wasLocked = heldItem.locked;
ProcessingResult result = wasLocked ? processingBehaviour.handleHeldItem(heldItem, transportedHandler)
: processingBehaviour.handleReceivedItem(heldItem, transportedHandler);
if (result == ProcessingResult.REMOVE) {
@ -89,6 +91,35 @@ public class DepotTileEntity extends SmartTileEntity {
sendData();
}
private boolean handleBeltFunnelOutput() {
for (int slot = 0; slot < processingOutputBuffer.getSlots(); slot++) {
ItemStack previousItem = processingOutputBuffer.getStackInSlot(slot);
if (previousItem.isEmpty())
continue;
ItemStack afterInsert =
getBehaviour(DirectBeltInputBehaviour.TYPE).tryExportingToBeltFunnel(previousItem, null);
if (previousItem.getCount() != afterInsert.getCount()) {
processingOutputBuffer.setStackInSlot(slot, afterInsert);
notifyUpdate();
return true;
}
}
ItemStack previousItem = heldItem.stack;
ItemStack afterInsert =
getBehaviour(DirectBeltInputBehaviour.TYPE).tryExportingToBeltFunnel(previousItem, null);
if (previousItem.getCount() != afterInsert.getCount()) {
if (afterInsert.isEmpty())
heldItem = null;
else
heldItem.stack = afterInsert;
notifyUpdate();
return true;
}
return false;
}
@Override
public void remove() {
super.remove();
@ -115,7 +146,8 @@ public class DepotTileEntity extends SmartTileEntity {
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
behaviours.add(new DirectBeltInputBehaviour(this).setInsertionHandler(this::tryInsertingFromSide));
behaviours.add(new DirectBeltInputBehaviour(this).allowingBeltFunnels()
.setInsertionHandler(this::tryInsertingFromSide));
transportedHandler = new TransportedItemStackHandlerBehaviour(this, this::applyToAllItems)
.withStackPlacement(this::getWorldPositionOf);
behaviours.add(transportedHandler);

View file

@ -6,8 +6,8 @@ import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.contraptions.relays.belt.BeltBlock;
import com.simibubi.create.content.contraptions.relays.belt.BeltSlope;
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
import com.simibubi.create.content.logistics.block.depot.DepotBlock;
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.Lang;
@ -172,13 +172,14 @@ public abstract class BeltFunnelBlock extends HorizontalBlock implements IWrench
public static boolean isOnValidBelt(BlockState state, IWorldReader world, BlockPos pos) {
BlockState stateBelow = world.getBlockState(pos.down());
if (stateBelow.getBlock() instanceof DepotBlock)
return true;
if (!(stateBelow.getBlock() instanceof BeltBlock))
if ((stateBelow.getBlock() instanceof BeltBlock))
return BeltBlock.canTransportObjects(stateBelow);
DirectBeltInputBehaviour directBeltInputBehaviour =
TileEntityBehaviour.get(world, pos.down(), DirectBeltInputBehaviour.TYPE);
if (directBeltInputBehaviour == null)
return false;
if (!BeltBlock.canTransportObjects(stateBelow))
return false;
return true;
return directBeltInputBehaviour.canSupportBeltFunnels();
}
@Override
@ -208,7 +209,8 @@ public abstract class BeltFunnelBlock extends HorizontalBlock implements IWrench
else if (shape == Shape.EXTENDED)
newShape = Shape.RETRACTED;
else if (shape == Shape.RETRACTED) {
BlockState belt = world.getBlockState(context.getPos().down());
BlockState belt = world.getBlockState(context.getPos()
.down());
if (belt.getBlock() instanceof BeltBlock && belt.get(BeltBlock.SLOPE) != BeltSlope.HORIZONTAL)
newShape = Shape.RETRACTED;
else
@ -216,8 +218,7 @@ public abstract class BeltFunnelBlock extends HorizontalBlock implements IWrench
}
if (newShape != shape)
world
.setBlockState(context.getPos(), state.with(SHAPE, newShape));
world.setBlockState(context.getPos(), state.with(SHAPE, newShape));
return ActionResultType.SUCCESS;
}

View file

@ -125,12 +125,15 @@ public abstract class FunnelBlock extends ProperDirectionalBlock implements ITE<
return toInsert;
if (simulate)
inserter.simulate();
if (!simulate) {
ItemStack insert = inserter.insert(toInsert);
if (!simulate && insert.getCount() != toInsert.getCount()) {
TileEntity tileEntity = worldIn.getTileEntity(pos);
if (tileEntity instanceof FunnelTileEntity)
((FunnelTileEntity) tileEntity).onTransfer(toInsert);
}
return inserter.insert(toInsert);
return insert;
}
@Override

View file

@ -18,8 +18,6 @@ import com.simibubi.create.foundation.item.TooltipHelper;
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.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour.InterfaceProvider;
@ -94,7 +92,7 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
if (mode == Mode.PAUSED)
extractionCooldown = 0;
if (mode == Mode.TAKING_FROM_BELT)
tickAsPullingBeltFunnel();
return;
if (extractionCooldown > 0) {
extractionCooldown--;
@ -137,17 +135,6 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
startCooldown();
}
private void tickAsPullingBeltFunnel() {
// Belts handle insertion from their side
if (AllBlocks.BELT.has(world.getBlockState(pos.down())))
return;
TransportedItemStackHandlerBehaviour handler =
TileEntityBehaviour.get(world, pos.down(), TransportedItemStackHandlerBehaviour.TYPE);
if (handler == null)
return;
handler.handleCenteredProcessingOnAllItems(1 / 32f, this::collectFromHandler);
}
private void activateExtractingBeltFunnel() {
BlockState blockState = getBlockState();
Direction facing = blockState.get(BeltFunnelBlock.HORIZONTAL_FACING);
@ -183,25 +170,6 @@ public class FunnelTileEntity extends SmartTileEntity implements IHaveHoveringIn
return extractionCooldown = AllConfigs.SERVER.logistics.defaultExtractionTimer.get();
}
private TransportedResult collectFromHandler(TransportedItemStack stack) {
TransportedResult ignore = TransportedResult.doNothing();
ItemStack toInsert = stack.stack.copy();
if (!filtering.test(toInsert))
return ignore;
ItemStack remainder = invManipulation.insert(toInsert);
if (remainder.equals(stack.stack, false))
return ignore;
flap(true);
onTransfer(toInsert);
if (remainder.isEmpty())
return TransportedResult.removeItem();
TransportedItemStack changed = stack.copy();
changed.stack = remainder;
return TransportedResult.convertTo(changed);
}
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
invManipulation = new InvManipulationBehaviour(this, InterfaceProvider.oppositeOfBlockFacing());

View file

@ -219,7 +219,7 @@ public abstract class ArmInteractionPoint {
@Override
boolean isValid(IBlockReader reader, BlockPos pos, BlockState state) {
return AllBlocks.MECHANICAL_SAW.has(state) && state.get(SawBlock.FACING) == Direction.UP
&& ((KineticTileEntity)reader.getTileEntity(pos)).getSpeed() != 0;
&& ((KineticTileEntity) reader.getTileEntity(pos)).getSpeed() != 0;
}
}
@ -441,12 +441,13 @@ public abstract class ArmInteractionPoint {
return stack;
if (simulate)
inserter.simulate();
if (!simulate) {
ItemStack insert = inserter.insert(stack);
if (!simulate && insert.getCount() != stack.getCount()) {
TileEntity tileEntity = world.getTileEntity(pos);
if (tileEntity instanceof FunnelTileEntity)
((FunnelTileEntity) tileEntity).onTransfer(stack);
}
return inserter.insert(stack);
return insert;
}
@Override

View file

@ -906,6 +906,9 @@ public class StandardRecipeGen extends CreateRecipeProvider {
.inFurnace(),
GRANITE = create(AllPaletteBlocks.GABBRO::get).viaCooking(() -> Blocks.GRANITE)
.inFurnace(),
NAT_SCORIA = create(AllPaletteBlocks.SCORIA::get).withSuffix("_from_natural")
.viaCooking(AllPaletteBlocks.NATURAL_SCORIA::get)
.inFurnace(),
FRAMED_GLASS = recycleGlass(AllPaletteBlocks.FRAMED_GLASS),
TILED_GLASS = recycleGlass(AllPaletteBlocks.TILED_GLASS),

View file

@ -1,12 +1,24 @@
package com.simibubi.create.foundation.tileEntity.behaviour.belt;
import java.util.function.Supplier;
import javax.annotation.Nullable;
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock;
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock.Shape;
import com.simibubi.create.content.logistics.block.funnel.FunnelBlock;
import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity;
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.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
@ -22,11 +34,23 @@ public class DirectBeltInputBehaviour extends TileEntityBehaviour {
private InsertionCallback tryInsert;
private AvailabilityPredicate canInsert;
private Supplier<Boolean> supportsBeltFunnels;
public DirectBeltInputBehaviour(SmartTileEntity te) {
super(te);
tryInsert = this::defaultInsertionCallback;
canInsert = d -> true;
supportsBeltFunnels = () -> false;
}
public DirectBeltInputBehaviour allowingBeltFunnelsWhen(Supplier<Boolean> pred) {
supportsBeltFunnels = pred;
return this;
}
public DirectBeltInputBehaviour allowingBeltFunnels() {
supportsBeltFunnels = () -> true;
return this;
}
public DirectBeltInputBehaviour onlyInsertWhen(AvailabilityPredicate pred) {
@ -73,4 +97,28 @@ public class DirectBeltInputBehaviour extends TileEntityBehaviour {
public boolean test(Direction side);
}
public ItemStack tryExportingToBeltFunnel(ItemStack stack, @Nullable Direction side) {
BlockPos funnelPos = tileEntity.getPos()
.up();
World world = getWorld();
BlockState funnelState = world.getBlockState(funnelPos);
if (!(funnelState.getBlock() instanceof BeltFunnelBlock))
return stack;
if (funnelState.get(BeltFunnelBlock.SHAPE) != Shape.PULLING)
return stack;
if (side != null && FunnelBlock.getFunnelFacing(funnelState) != side)
return stack;
TileEntity te = world.getTileEntity(funnelPos);
if (!(te instanceof FunnelTileEntity))
return stack;
ItemStack insert = FunnelBlock.tryInsert(world, funnelPos, stack, false);
if (insert.getCount() != stack.getCount())
((FunnelTileEntity) te).flap(true);
return insert;
}
public boolean canSupportBeltFunnels() {
return supportsBeltFunnels.get();
}
}

View file

@ -101,8 +101,8 @@
},
{
"name": "RearBackPlate",
"from": [0, -5, 13],
"to": [16, -2, 16],
"from": [0.05, -5, 13],
"to": [15.95, -2, 15.95],
"rotation": {"angle": 0, "axis": "y", "origin": [7, -8, 8]},
"faces": {
"north": {"uv": [0, 13, 8, 14.5], "texture": "#7"},

View file

@ -101,8 +101,8 @@
},
{
"name": "RearBackPlate",
"from": [0, -5, 13],
"to": [16, -2, 16],
"from": [0.05, -5, 13],
"to": [15.95, -2, 15.95],
"rotation": {"angle": 0, "axis": "y", "origin": [7, -8, 8]},
"faces": {
"north": {"uv": [0, 13, 8, 14.5], "texture": "#7"},