diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/InsertingBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/InsertingBehaviour.java index 3c38225de..17991e023 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/InsertingBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/InsertingBehaviour.java @@ -8,8 +8,11 @@ import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.foundation.behaviour.base.IBehaviourType; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; +import net.minecraft.item.ItemStack; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemHandlerHelper; public class InsertingBehaviour extends InventoryManagementBehaviour { @@ -20,6 +23,15 @@ public class InsertingBehaviour extends InventoryManagementBehaviour { super(te, attachments); } + public ItemStack insert(ItemStack stack, boolean simulate) { + for (IItemHandler inv : getInventories()) { + stack = ItemHandlerHelper.insertItemStacked(inv, stack, simulate); + if (stack.isEmpty()) + break; + } + return stack; + } + @Override public IBehaviourType getType() { return TYPE; diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/InventoryManagementBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/InventoryManagementBehaviour.java index 22fa74527..6da0fae2d 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/InventoryManagementBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/InventoryManagementBehaviour.java @@ -103,7 +103,8 @@ public class InventoryManagementBehaviour extends TileEntityBehaviour { public static class Attachments { public static final Supplier>> toward(Supplier facing) { - return () -> ImmutableList.of(Pair.of(new BlockPos(facing.get().getDirectionVec()), facing.get())); + return () -> ImmutableList + .of(Pair.of(new BlockPos(facing.get().getDirectionVec()), facing.get().getOpposite())); }; } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/SynchronizedExtraction.java b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/SynchronizedExtraction.java index aec9d4b00..92da9bc05 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/inventory/SynchronizedExtraction.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/inventory/SynchronizedExtraction.java @@ -57,6 +57,9 @@ public class SynchronizedExtraction { continue; if (!behaviour.shouldExtract.get()) continue; + if (!behaviour.inventories.keySet().stream() + .anyMatch(p -> p.getKey().add(behaviour.getPos()).equals(pos))) + continue; list.add(behaviour); } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java b/src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java deleted file mode 100644 index 845f1d12b..000000000 --- a/src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java +++ /dev/null @@ -1,224 +0,0 @@ -package com.simibubi.create.modules.logistics.block; - -import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING; - -import com.simibubi.create.AllBlocks; -import com.simibubi.create.CreateConfig; -import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; -import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; -import com.simibubi.create.foundation.utility.VecHelper; -import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; -import com.simibubi.create.modules.logistics.item.CardboardBoxItem; -import com.simibubi.create.modules.logistics.transport.CardboardBoxEntity; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.item.ItemEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.tileentity.ITickableTileEntity; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.Direction; -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.World; -import net.minecraftforge.items.IItemHandler; - -// Its like delegation but worse! -public interface IExtractor extends ITickableTileEntity, IInventoryManipulator { - - public enum State { - WAITING_FOR_INVENTORY, WAITING_FOR_ENTITY, RUNNING, ON_COOLDOWN, LOCKED; - } - - public State getState(); - - public void setState(State state); - - public int tickCooldown(); - - @Override - default void tick() { - if (isFrozen()) - return; - - State state = getState(); - - if (state == State.LOCKED) - return; - - if (state == State.ON_COOLDOWN || state == State.WAITING_FOR_INVENTORY) { - int cooldown = tickCooldown(); - if (cooldown <= 0) { - setState(State.RUNNING); - if (!getInventory().isPresent()) - findNewInventory(); - } - return; - } - - boolean hasSpace = hasSpaceForExtracting(); - boolean hasInventory = getInventory().isPresent(); - ItemStack toExtract = ItemStack.EMPTY; - - if (hasSpace && hasInventory) { - toExtract = extract(true); - - if (!matchesFilter(toExtract)) - toExtract = ItemStack.EMPTY; - } - - if (state == State.WAITING_FOR_ENTITY) { - if (hasSpace) - setState(State.RUNNING); - } - - if (state == State.RUNNING) { - if (!hasSpace) { - setState(State.WAITING_FOR_ENTITY); - return; - } - if (!hasInventory || toExtract.isEmpty()) { - setState(State.WAITING_FOR_INVENTORY); - return; - } - - extract(false); - setState(State.ON_COOLDOWN); - return; - } - - } - - default boolean matchesFilter(ItemStack stack) { - FilteringBehaviour filteringBehaviour = TileEntityBehaviour.get((TileEntity) this, FilteringBehaviour.TYPE); - return filteringBehaviour == null || filteringBehaviour.test(stack); - } - - public default void setLocked(boolean locked) { - setState(locked ? State.LOCKED : State.ON_COOLDOWN); - } - - public default void neighborChanged() { - if (isFrozen()) - return; - - boolean hasSpace = hasSpaceForExtracting(); - boolean hasInventory = getInventory().isPresent(); - ItemStack toExtract = ItemStack.EMPTY; - - if (hasSpace && hasInventory) { - toExtract = extract(true); - if (!matchesFilter(toExtract)) - toExtract = ItemStack.EMPTY; - } - - if (getState() == State.WAITING_FOR_INVENTORY) { - if (!hasInventory) { - if (findNewInventory()) { - setState(State.RUNNING); - } - } - if (!toExtract.isEmpty()) - setState(State.RUNNING); - return; - } - } - - default boolean hasSpaceForExtracting() { - BlockPos pos = getPos(); - World world = getWorld(); - - if (AllBlocks.BELT.typeOf(world.getBlockState(pos.down()))) { - TileEntity te = world.getTileEntity(pos.down()); - if (te != null && te instanceof BeltTileEntity) { - BeltTileEntity belt = (BeltTileEntity) te; - BeltTileEntity controller = belt.getControllerTE(); - if (controller != null) { - if (!controller.getInventory().canInsertFrom(belt.index, Direction.UP)) - return false; - } - } - } - - return world.getEntitiesWithinAABBExcludingEntity(null, new AxisAlignedBB(getPos())).isEmpty(); - } - - default ItemStack extract(boolean simulate) { - IItemHandler inv = getInventory().orElse(null); - ItemStack extracting = ItemStack.EMPTY; - FilteringBehaviour filteringBehaviour = TileEntityBehaviour.get((TileEntity) this, FilteringBehaviour.TYPE); - ItemStack filterItem = filteringBehaviour == null ? ItemStack.EMPTY : filteringBehaviour.getFilter(); - World world = getWorld(); - int extractionCount = filterItem.isEmpty() ? CreateConfig.parameters.extractorAmount.get() - : filterItem.getCount(); - boolean checkHasEnoughItems = !filterItem.isEmpty(); - boolean hasEnoughItems = !checkHasEnoughItems; - - Extraction: do { - extracting = ItemStack.EMPTY; - - for (int slot = 0; slot < inv.getSlots(); slot++) { - ItemStack stack = inv.extractItem(slot, extractionCount - extracting.getCount(), true); - ItemStack compare = stack.copy(); - - compare.setCount(filterItem.getCount()); - if (!filterItem.isEmpty() && !filterItem.equals(compare, false)) - continue; - - compare.setCount(extracting.getCount()); - if (!extracting.isEmpty() && !extracting.equals(compare, false)) - continue; - - if (extracting.isEmpty()) - extracting = stack.copy(); - else - extracting.grow(stack.getCount()); - - if (!simulate && hasEnoughItems) - inv.extractItem(slot, stack.getCount(), false); - - if (extracting.getCount() >= extractionCount) { - if (checkHasEnoughItems) { - hasEnoughItems = true; - checkHasEnoughItems = false; - continue Extraction; - } else { - break Extraction; - } - } - } - - if (checkHasEnoughItems) - checkHasEnoughItems = false; - else - break Extraction; - } while (true); - - if (!simulate && hasEnoughItems) { - Vec3d entityPos = VecHelper.getCenterOf(getPos()).add(0, -0.5f, 0); - Entity entityIn = null; - - if (extracting.getItem() instanceof CardboardBoxItem) { - Direction face = getWorld().getBlockState(getPos()).get(HORIZONTAL_FACING).getOpposite(); - entityIn = new CardboardBoxEntity(world, entityPos, extracting, face); - world.playSound(null, getPos(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .25f, .05f); - - } else { - entityIn = new ItemEntity(world, entityPos.x, entityPos.y, entityPos.z, extracting); - entityIn.setMotion(Vec3d.ZERO); - world.playSound(null, getPos(), SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .125f, .1f); - } - - world.addEntity(entityIn); - } - - return extracting; - } - - public static boolean isFrozen() { - return CreateConfig.parameters.freezeExtractors.get(); - } - -} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorTileEntity.java index 804f7b93a..8d1aed68c 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorTileEntity.java @@ -30,10 +30,10 @@ import net.minecraft.util.math.Vec3d; public class ExtractorTileEntity extends SmartTileEntity { - private static FilteringBehaviour.SlotPositioning slots; + protected static FilteringBehaviour.SlotPositioning slots; - private ExtractingBehaviour extracting; - private FilteringBehaviour filtering; + protected ExtractingBehaviour extracting; + protected FilteringBehaviour filtering; public ExtractorTileEntity() { this(AllTileEntities.EXTRACTOR.type); @@ -59,7 +59,7 @@ public class ExtractorTileEntity extends SmartTileEntity { behaviours.add(filtering); } - private void onExtract(ItemStack stack) { + protected void onExtract(ItemStack stack) { Vec3d entityPos = VecHelper.getCenterOf(getPos()).add(0, -0.5f, 0); Entity entityIn = null; Direction facing = AttachedLogisticalBlock.getBlockFacing(getBlockState()); @@ -88,7 +88,7 @@ public class ExtractorTileEntity extends SmartTileEntity { } - private boolean canExtract() { + protected boolean canExtract() { if (AllBlocks.BELT.typeOf(world.getBlockState(pos.down()))) { TileEntity te = world.getTileEntity(pos.down()); if (te != null && te instanceof BeltTileEntity) { diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerTileEntity.java index 9bd83b3b0..de129731b 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/transposer/TransposerTileEntity.java @@ -3,19 +3,19 @@ package com.simibubi.create.modules.logistics.block.transposer; import java.util.List; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; -import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; -import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning; -import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock; +import com.simibubi.create.foundation.behaviour.inventory.InsertingBehaviour; +import com.simibubi.create.foundation.behaviour.inventory.InventoryManagementBehaviour.Attachments; +import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock; +import com.simibubi.create.modules.logistics.block.extractor.ExtractorTileEntity; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntityType; +import net.minecraftforge.items.ItemHandlerHelper; -public class TransposerTileEntity extends SmartTileEntity { +public class TransposerTileEntity extends ExtractorTileEntity { - private static FilteringBehaviour.SlotPositioning slots; - private FilteringBehaviour filtering; + private InsertingBehaviour inserting; public TransposerTileEntity() { this(AllTileEntities.TRANSPOSER.type); @@ -27,15 +27,33 @@ public class TransposerTileEntity extends SmartTileEntity { @Override public void addBehaviours(List behaviours) { - if (slots == null) - slots = new SlotPositioning(ExtractorBlock::getFilterSlotPosition, ExtractorBlock::getFilterSlotOrientation) - .scale(.4f); - filtering = new FilteringBehaviour(this).withCallback(this::filterChanged).withSlotPositioning(slots) - .showCount(); - behaviours.add(filtering); + super.addBehaviours(behaviours); + inserting = new InsertingBehaviour(this, + Attachments.toward(() -> AttachedLogisticalBlock.getBlockFacing(getBlockState()).getOpposite())); + behaviours.add(inserting); + extracting.withSpecialFilter(this::shouldExtract); } public void filterChanged(ItemStack stack) { } + protected boolean shouldExtract(ItemStack stack) { + if (filtering.getFilter().isEmpty()) + return true; + return inserting.insert(stack, true).isEmpty(); + } + + @Override + protected boolean canExtract() { + return inserting.getInventory() != null; + } + + @Override + protected void onExtract(ItemStack stack) { + ItemStack remainder = inserting.insert(stack, false); + remainder = ItemHandlerHelper.insertItemStacked(extracting.getInventory(), remainder, false); + if (!remainder.isEmpty()) + super.onExtract(remainder); + } + }