mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-12 21:44:06 +01:00
Perform over Function
- Chutes, (Extracting) Funnels, Smart Observers and Threshold Switches no longer search vault contents unless the vault contents have changed - Extracting Funnels no longer search their inventories' contents if their target depot or belt is occupied
This commit is contained in:
parent
8b5c3a90fb
commit
0510ea3e20
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
1
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -49,6 +49,7 @@ body:
|
|||||||
label: Mod Version
|
label: Mod Version
|
||||||
description: The version of the mod you were using when the bug occured
|
description: The version of the mod you were using when the bug occured
|
||||||
options:
|
options:
|
||||||
|
- "0.5.1e"
|
||||||
- "0.5.1d"
|
- "0.5.1d"
|
||||||
- "0.5.1c"
|
- "0.5.1c"
|
||||||
- "0.5.1b"
|
- "0.5.1b"
|
||||||
|
@ -202,6 +202,7 @@ dependencies {
|
|||||||
// runtimeOnly fg.deobf("slimeknights.tconstruct:TConstruct:1.16.5-3.1.1.252")
|
// runtimeOnly fg.deobf("slimeknights.tconstruct:TConstruct:1.16.5-3.1.1.252")
|
||||||
// runtimeOnly fg.deobf("maven.modrinth:rubidium:0.5.3")
|
// runtimeOnly fg.deobf("maven.modrinth:rubidium:0.5.3")
|
||||||
// implementation fg.deobf("com.railwayteam.railways:railways-1.18.2-1.1.1:all") { transitive = false }
|
// implementation fg.deobf("com.railwayteam.railways:railways-1.18.2-1.1.1:all") { transitive = false }
|
||||||
|
// runtimeOnly fg.deobf("maven.modrinth:spark:1.10.38-forge")
|
||||||
|
|
||||||
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
||||||
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
// Prevent Mixin annotation processor from getting into IntelliJ's annotation processor settings
|
||||||
|
@ -95,7 +95,7 @@ public class BeltBlockEntity extends KineticBlockEntity {
|
|||||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||||
super.addBehaviours(behaviours);
|
super.addBehaviours(behaviours);
|
||||||
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::canInsertFrom)
|
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::canInsertFrom)
|
||||||
.setInsertionHandler(this::tryInsertingFromSide));
|
.setInsertionHandler(this::tryInsertingFromSide).considerOccupiedWhen(this::isOccupied));
|
||||||
behaviours.add(new TransportedItemStackHandlerBehaviour(this, this::applyToAllItems)
|
behaviours.add(new TransportedItemStackHandlerBehaviour(this, this::applyToAllItems)
|
||||||
.withStackPlacement(this::getWorldPositionOf));
|
.withStackPlacement(this::getWorldPositionOf));
|
||||||
}
|
}
|
||||||
@ -464,6 +464,22 @@ public class BeltBlockEntity extends KineticBlockEntity {
|
|||||||
return false;
|
return false;
|
||||||
return getMovementFacing() != side.getOpposite();
|
return getMovementFacing() != side.getOpposite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isOccupied(Direction side) {
|
||||||
|
BeltBlockEntity nextBeltController = getControllerBE();
|
||||||
|
if (nextBeltController == null)
|
||||||
|
return true;
|
||||||
|
BeltInventory nextInventory = nextBeltController.getInventory();
|
||||||
|
if (nextInventory == null)
|
||||||
|
return true;
|
||||||
|
if (getSpeed() == 0)
|
||||||
|
return true;
|
||||||
|
if (getMovementFacing() == side.getOpposite())
|
||||||
|
return true;
|
||||||
|
if (!nextInventory.canInsertAtFromSide(index, side))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) {
|
private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) {
|
||||||
BeltBlockEntity nextBeltController = getControllerBE();
|
BeltBlockEntity nextBeltController = getControllerBE();
|
||||||
@ -493,11 +509,7 @@ public class BeltBlockEntity extends KineticBlockEntity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getSpeed() == 0)
|
if (isOccupied(side))
|
||||||
return inserted;
|
|
||||||
if (getMovementFacing() == side.getOpposite())
|
|
||||||
return inserted;
|
|
||||||
if (!nextInventory.canInsertAtFromSide(index, side))
|
|
||||||
return inserted;
|
return inserted;
|
||||||
if (simulate)
|
if (simulate)
|
||||||
return empty;
|
return empty;
|
||||||
|
@ -33,6 +33,7 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
|||||||
public static final BehaviourType<DirectBeltInputBehaviour> TYPE = new BehaviourType<>();
|
public static final BehaviourType<DirectBeltInputBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
|
||||||
private InsertionCallback tryInsert;
|
private InsertionCallback tryInsert;
|
||||||
|
private OccupiedPredicate isOccupied;
|
||||||
private AvailabilityPredicate canInsert;
|
private AvailabilityPredicate canInsert;
|
||||||
private Supplier<Boolean> supportsBeltFunnels;
|
private Supplier<Boolean> supportsBeltFunnels;
|
||||||
|
|
||||||
@ -40,6 +41,7 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
|||||||
super(be);
|
super(be);
|
||||||
tryInsert = this::defaultInsertionCallback;
|
tryInsert = this::defaultInsertionCallback;
|
||||||
canInsert = d -> true;
|
canInsert = d -> true;
|
||||||
|
isOccupied = d -> false;
|
||||||
supportsBeltFunnels = () -> false;
|
supportsBeltFunnels = () -> false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +59,11 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
|||||||
canInsert = pred;
|
canInsert = pred;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DirectBeltInputBehaviour considerOccupiedWhen(OccupiedPredicate pred) {
|
||||||
|
isOccupied = pred;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public DirectBeltInputBehaviour setInsertionHandler(InsertionCallback callback) {
|
public DirectBeltInputBehaviour setInsertionHandler(InsertionCallback callback) {
|
||||||
tryInsert = callback;
|
tryInsert = callback;
|
||||||
@ -75,6 +82,10 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
|||||||
return canInsert.test(side);
|
return canInsert.test(side);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isOccupied(Direction side) {
|
||||||
|
return isOccupied.test(side);
|
||||||
|
}
|
||||||
|
|
||||||
public ItemStack handleInsertion(ItemStack stack, Direction side, boolean simulate) {
|
public ItemStack handleInsertion(ItemStack stack, Direction side, boolean simulate) {
|
||||||
return handleInsertion(new TransportedItemStack(stack), side, simulate);
|
return handleInsertion(new TransportedItemStack(stack), side, simulate);
|
||||||
}
|
}
|
||||||
@ -93,6 +104,11 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
|||||||
public ItemStack apply(TransportedItemStack stack, Direction side, boolean simulate);
|
public ItemStack apply(TransportedItemStack stack, Direction side, boolean simulate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface OccupiedPredicate {
|
||||||
|
public boolean test(Direction side);
|
||||||
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
public interface AvailabilityPredicate {
|
public interface AvailabilityPredicate {
|
||||||
public boolean test(Direction side);
|
public boolean test(Direction side);
|
||||||
|
@ -20,6 +20,7 @@ import com.simibubi.create.content.logistics.funnel.FunnelBlock;
|
|||||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.VersionedInventoryTrackerBehaviour;
|
||||||
import com.simibubi.create.foundation.item.ItemHelper;
|
import com.simibubi.create.foundation.item.ItemHelper;
|
||||||
import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode;
|
import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode;
|
||||||
import com.simibubi.create.foundation.particle.AirParticleData;
|
import com.simibubi.create.foundation.particle.AirParticleData;
|
||||||
@ -81,6 +82,8 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||||||
int airCurrentUpdateCooldown;
|
int airCurrentUpdateCooldown;
|
||||||
int entitySearchCooldown;
|
int entitySearchCooldown;
|
||||||
|
|
||||||
|
VersionedInventoryTrackerBehaviour invVersionTracker;
|
||||||
|
|
||||||
LazyOptional<IItemHandler> capAbove;
|
LazyOptional<IItemHandler> capAbove;
|
||||||
LazyOptional<IItemHandler> capBelow;
|
LazyOptional<IItemHandler> capBelow;
|
||||||
|
|
||||||
@ -101,6 +104,7 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||||||
@Override
|
@Override
|
||||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||||
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen((d) -> canDirectlyInsertCached()));
|
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen((d) -> canDirectlyInsertCached()));
|
||||||
|
behaviours.add(invVersionTracker = new VersionedInventoryTrackerBehaviour(this));
|
||||||
registerAwardables(behaviours, AllAdvancements.CHUTE);
|
registerAwardables(behaviours, AllAdvancements.CHUTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,15 +340,20 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||||||
private void handleInput(IItemHandler inv, float startLocation) {
|
private void handleInput(IItemHandler inv, float startLocation) {
|
||||||
if (inv == null)
|
if (inv == null)
|
||||||
return;
|
return;
|
||||||
|
if (invVersionTracker.stillWaiting(inv))
|
||||||
|
return;
|
||||||
Predicate<ItemStack> canAccept = this::canAcceptItem;
|
Predicate<ItemStack> canAccept = this::canAcceptItem;
|
||||||
int count = getExtractionAmount();
|
int count = getExtractionAmount();
|
||||||
ExtractionCountMode mode = getExtractionMode();
|
ExtractionCountMode mode = getExtractionMode();
|
||||||
if (mode == ExtractionCountMode.UPTO || !ItemHelper.extract(inv, canAccept, mode, count, true)
|
if (mode == ExtractionCountMode.UPTO || !ItemHelper.extract(inv, canAccept, mode, count, true)
|
||||||
.isEmpty()) {
|
.isEmpty()) {
|
||||||
ItemStack extracted = ItemHelper.extract(inv, canAccept, mode, count, false);
|
ItemStack extracted = ItemHelper.extract(inv, canAccept, mode, count, false);
|
||||||
if (!extracted.isEmpty())
|
if (!extracted.isEmpty()) {
|
||||||
setItem(extracted, startLocation);
|
setItem(extracted, startLocation);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
invVersionTracker.awaitNewVersion(inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleDownwardOutput(boolean simulate) {
|
private boolean handleDownwardOutput(boolean simulate) {
|
||||||
@ -359,12 +368,16 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||||||
if (capBelow.isPresent()) {
|
if (capBelow.isPresent()) {
|
||||||
if (level.isClientSide && !isVirtual())
|
if (level.isClientSide && !isVirtual())
|
||||||
return false;
|
return false;
|
||||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(capBelow.orElse(null), item, simulate);
|
IItemHandler inv = capBelow.orElse(null);
|
||||||
|
if (invVersionTracker.stillWaiting(inv))
|
||||||
|
return false;
|
||||||
|
ItemStack remainder = ItemHandlerHelper.insertItemStacked(inv, item, simulate);
|
||||||
ItemStack held = getItem();
|
ItemStack held = getItem();
|
||||||
if (!simulate)
|
if (!simulate)
|
||||||
setItem(remainder, itemPosition.getValue(0));
|
setItem(remainder, itemPosition.getValue(0));
|
||||||
if (remainder.getCount() != held.getCount())
|
if (remainder.getCount() != held.getCount())
|
||||||
return true;
|
return true;
|
||||||
|
invVersionTracker.awaitNewVersion(inv);
|
||||||
if (direction == Direction.DOWN)
|
if (direction == Direction.DOWN)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -414,10 +427,16 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||||||
if (level.isClientSide && !isVirtual() && !ChuteBlock.isChute(stateAbove))
|
if (level.isClientSide && !isVirtual() && !ChuteBlock.isChute(stateAbove))
|
||||||
return false;
|
return false;
|
||||||
int countBefore = item.getCount();
|
int countBefore = item.getCount();
|
||||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(capAbove.orElse(null), item, simulate);
|
IItemHandler inv = capAbove.orElse(null);
|
||||||
|
if (invVersionTracker.stillWaiting(inv))
|
||||||
|
return false;
|
||||||
|
ItemStack remainder = ItemHandlerHelper.insertItemStacked(inv, item, simulate);
|
||||||
if (!simulate)
|
if (!simulate)
|
||||||
item = remainder;
|
item = remainder;
|
||||||
return countBefore != remainder.getCount();
|
if (countBefore != remainder.getCount())
|
||||||
|
return true;
|
||||||
|
invVersionTracker.awaitNewVersion(inv);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,6 +521,7 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
|||||||
public void setItem(ItemStack stack, float insertionPos) {
|
public void setItem(ItemStack stack, float insertionPos) {
|
||||||
item = stack;
|
item = stack;
|
||||||
itemPosition.startWithValue(insertionPos);
|
itemPosition.startWithValue(insertionPos);
|
||||||
|
invVersionTracker.reset();
|
||||||
if (!level.isClientSide) {
|
if (!level.isClientSide) {
|
||||||
notifyUpdate();
|
notifyUpdate();
|
||||||
award(AllAdvancements.CHUTE);
|
award(AllAdvancements.CHUTE);
|
||||||
|
@ -51,7 +51,8 @@ public class SmartChuteBlockEntity extends ChuteBlockEntity {
|
|||||||
@Override
|
@Override
|
||||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||||
behaviours.add(filtering =
|
behaviours.add(filtering =
|
||||||
new FilteringBehaviour(this, new SmartChuteFilterSlotPositioning()).showCountWhen(this::isExtracting));
|
new FilteringBehaviour(this, new SmartChuteFilterSlotPositioning()).showCountWhen(this::isExtracting)
|
||||||
|
.withCallback($ -> invVersionTracker.reset()));
|
||||||
super.addBehaviours(behaviours);
|
super.addBehaviours(behaviours);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ public class DepotBehaviour extends BlockEntityBehaviour {
|
|||||||
|
|
||||||
public void addSubBehaviours(List<BlockEntityBehaviour> behaviours) {
|
public void addSubBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||||
behaviours.add(new DirectBeltInputBehaviour(blockEntity).allowingBeltFunnels()
|
behaviours.add(new DirectBeltInputBehaviour(blockEntity).allowingBeltFunnels()
|
||||||
.setInsertionHandler(this::tryInsertingFromSide));
|
.setInsertionHandler(this::tryInsertingFromSide).considerOccupiedWhen(this::isOccupied));
|
||||||
transportedHandler = new TransportedItemStackHandlerBehaviour(blockEntity, this::applyToAllItems)
|
transportedHandler = new TransportedItemStackHandlerBehaviour(blockEntity, this::applyToAllItems)
|
||||||
.withStackPlacement(this::getWorldPositionOf);
|
.withStackPlacement(this::getWorldPositionOf);
|
||||||
behaviours.add(transportedHandler);
|
behaviours.add(transportedHandler);
|
||||||
@ -339,14 +339,20 @@ public class DepotBehaviour extends BlockEntityBehaviour {
|
|||||||
return lazyItemHandler.cast();
|
return lazyItemHandler.cast();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isOccupied(Direction side) {
|
||||||
|
if (!getHeldItemStack().isEmpty() && !canMergeItems())
|
||||||
|
return true;
|
||||||
|
if (!isOutputEmpty() && !canMergeItems())
|
||||||
|
return true;
|
||||||
|
if (!canAcceptItems.get())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) {
|
private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) {
|
||||||
ItemStack inserted = transportedStack.stack;
|
ItemStack inserted = transportedStack.stack;
|
||||||
|
|
||||||
if (!getHeldItemStack().isEmpty() && !canMergeItems())
|
if (isOccupied(side))
|
||||||
return inserted;
|
|
||||||
if (!isOutputEmpty() && !canMergeItems())
|
|
||||||
return inserted;
|
|
||||||
if (!canAcceptItems.get())
|
|
||||||
return inserted;
|
return inserted;
|
||||||
|
|
||||||
int size = transportedStack.stack.getCount();
|
int size = transportedStack.stack.getCount();
|
||||||
|
@ -3,6 +3,8 @@ package com.simibubi.create.content.logistics.funnel;
|
|||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllPackets;
|
import com.simibubi.create.AllPackets;
|
||||||
@ -18,6 +20,7 @@ import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
|||||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour;
|
import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour;
|
||||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour;
|
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour;
|
||||||
|
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.VersionedInventoryTrackerBehaviour;
|
||||||
import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode;
|
import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode;
|
||||||
import com.simibubi.create.foundation.utility.BlockFace;
|
import com.simibubi.create.foundation.utility.BlockFace;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
@ -42,6 +45,7 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
|||||||
|
|
||||||
private FilteringBehaviour filtering;
|
private FilteringBehaviour filtering;
|
||||||
private InvManipulationBehaviour invManipulation;
|
private InvManipulationBehaviour invManipulation;
|
||||||
|
private VersionedInventoryTrackerBehaviour invVersionTracker;
|
||||||
private int extractionCooldown;
|
private int extractionCooldown;
|
||||||
|
|
||||||
private WeakReference<ItemEntity> lastObserved; // In-world Extractors only
|
private WeakReference<ItemEntity> lastObserved; // In-world Extractors only
|
||||||
@ -111,6 +115,9 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void activateExtractor() {
|
private void activateExtractor() {
|
||||||
|
if (invVersionTracker.stillWaiting(invManipulation))
|
||||||
|
return;
|
||||||
|
|
||||||
BlockState blockState = getBlockState();
|
BlockState blockState = getBlockState();
|
||||||
Direction facing = AbstractFunnelBlock.getFunnelFacing(blockState);
|
Direction facing = AbstractFunnelBlock.getFunnelFacing(blockState);
|
||||||
|
|
||||||
@ -140,8 +147,10 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
|||||||
ExtractionCountMode mode = getModeToExtract();
|
ExtractionCountMode mode = getModeToExtract();
|
||||||
ItemStack stack = invManipulation.simulate()
|
ItemStack stack = invManipulation.simulate()
|
||||||
.extract(mode, amountToExtract);
|
.extract(mode, amountToExtract);
|
||||||
if (stack.isEmpty())
|
if (stack.isEmpty()) {
|
||||||
|
invVersionTracker.awaitNewVersion(invManipulation);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
for (ItemEntity itemEntity : level.getEntitiesOfClass(ItemEntity.class, area)) {
|
for (ItemEntity itemEntity : level.getEntitiesOfClass(ItemEntity.class, area)) {
|
||||||
lastObserved = new WeakReference<>(itemEntity);
|
lastObserved = new WeakReference<>(itemEntity);
|
||||||
return;
|
return;
|
||||||
@ -189,6 +198,9 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void activateExtractingBeltFunnel() {
|
private void activateExtractingBeltFunnel() {
|
||||||
|
if (invVersionTracker.stillWaiting(invManipulation))
|
||||||
|
return;
|
||||||
|
|
||||||
BlockState blockState = getBlockState();
|
BlockState blockState = getBlockState();
|
||||||
Direction facing = blockState.getValue(BeltFunnelBlock.HORIZONTAL_FACING);
|
Direction facing = blockState.getValue(BeltFunnelBlock.HORIZONTAL_FACING);
|
||||||
DirectBeltInputBehaviour inputBehaviour =
|
DirectBeltInputBehaviour inputBehaviour =
|
||||||
@ -198,14 +210,24 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
|||||||
return;
|
return;
|
||||||
if (!inputBehaviour.canInsertFromSide(facing))
|
if (!inputBehaviour.canInsertFromSide(facing))
|
||||||
return;
|
return;
|
||||||
|
if (inputBehaviour.isOccupied(facing))
|
||||||
|
return;
|
||||||
|
|
||||||
int amountToExtract = getAmountToExtract();
|
int amountToExtract = getAmountToExtract();
|
||||||
ExtractionCountMode mode = getModeToExtract();
|
ExtractionCountMode mode = getModeToExtract();
|
||||||
ItemStack stack =
|
MutableBoolean deniedByInsertion = new MutableBoolean(false);
|
||||||
invManipulation.extract(mode, amountToExtract, s -> inputBehaviour.handleInsertion(s, facing, true)
|
ItemStack stack = invManipulation.extract(mode, amountToExtract, s -> {
|
||||||
.isEmpty());
|
ItemStack handleInsertion = inputBehaviour.handleInsertion(s, facing, true);
|
||||||
if (stack.isEmpty())
|
if (handleInsertion.isEmpty())
|
||||||
|
return true;
|
||||||
|
deniedByInsertion.setTrue();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
if (deniedByInsertion.isFalse())
|
||||||
|
invVersionTracker.awaitNewVersion(invManipulation.getInventory());
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
flap(false);
|
flap(false);
|
||||||
onTransfer(stack);
|
onTransfer(stack);
|
||||||
inputBehaviour.handleInsertion(stack, facing, false);
|
inputBehaviour.handleInsertion(stack, facing, false);
|
||||||
@ -237,12 +259,15 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
|||||||
new InvManipulationBehaviour(this, (w, p, s) -> new BlockFace(p, AbstractFunnelBlock.getFunnelFacing(s)
|
new InvManipulationBehaviour(this, (w, p, s) -> new BlockFace(p, AbstractFunnelBlock.getFunnelFacing(s)
|
||||||
.getOpposite()));
|
.getOpposite()));
|
||||||
behaviours.add(invManipulation);
|
behaviours.add(invManipulation);
|
||||||
|
|
||||||
|
behaviours.add(invVersionTracker = new VersionedInventoryTrackerBehaviour(this));
|
||||||
|
|
||||||
filtering = new FilteringBehaviour(this, new FunnelFilterSlotPositioning());
|
filtering = new FilteringBehaviour(this, new FunnelFilterSlotPositioning());
|
||||||
filtering.showCountWhen(this::supportsAmountOnFilter);
|
filtering.showCountWhen(this::supportsAmountOnFilter);
|
||||||
filtering.onlyActiveWhen(this::supportsFiltering);
|
filtering.onlyActiveWhen(this::supportsFiltering);
|
||||||
|
filtering.withCallback($ -> invVersionTracker.reset());
|
||||||
behaviours.add(filtering);
|
behaviours.add(filtering);
|
||||||
|
|
||||||
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::supportsDirectBeltInput)
|
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::supportsDirectBeltInput)
|
||||||
.setInsertionHandler(this::handleDirectBeltInput));
|
.setInsertionHandler(this::handleDirectBeltInput));
|
||||||
registerAwardables(behaviours, AllAdvancements.FUNNEL);
|
registerAwardables(behaviours, AllAdvancements.FUNNEL);
|
||||||
|
@ -7,6 +7,7 @@ import com.simibubi.create.api.connectivity.ConnectivityHandler;
|
|||||||
import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer;
|
import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer;
|
||||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.VersionedInventoryWrapper;
|
||||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
@ -260,8 +261,8 @@ public class ItemVaultBlockEntity extends SmartBlockEntity implements IMultiBloc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CombinedInvWrapper combinedInvWrapper = new CombinedInvWrapper(invs);
|
IItemHandler itemHandler = new VersionedInventoryWrapper(new CombinedInvWrapper(invs));
|
||||||
itemCapability = LazyOptional.of(() -> combinedInvWrapper);
|
itemCapability = LazyOptional.of(() -> itemHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getMaxLength(int radius) {
|
public static int getMaxLength(int radius) {
|
||||||
|
@ -14,6 +14,7 @@ import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringB
|
|||||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.CapManipulationBehaviourBase.InterfaceProvider;
|
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.CapManipulationBehaviourBase.InterfaceProvider;
|
||||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour;
|
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour;
|
||||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.TankManipulationBehaviour;
|
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.TankManipulationBehaviour;
|
||||||
|
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.VersionedInventoryTrackerBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.BlockFace;
|
import com.simibubi.create.foundation.utility.BlockFace;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
|
||||||
@ -31,6 +32,10 @@ public class SmartObserverBlockEntity extends SmartBlockEntity {
|
|||||||
private FilteringBehaviour filtering;
|
private FilteringBehaviour filtering;
|
||||||
private InvManipulationBehaviour observedInventory;
|
private InvManipulationBehaviour observedInventory;
|
||||||
private TankManipulationBehaviour observedTank;
|
private TankManipulationBehaviour observedTank;
|
||||||
|
|
||||||
|
private VersionedInventoryTrackerBehaviour invVersionTracker;
|
||||||
|
private boolean sustainSignal;
|
||||||
|
|
||||||
public int turnOffTicks = 0;
|
public int turnOffTicks = 0;
|
||||||
|
|
||||||
public SmartObserverBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
public SmartObserverBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||||
@ -40,7 +45,9 @@ public class SmartObserverBlockEntity extends SmartBlockEntity {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||||
behaviours.add(filtering = new FilteringBehaviour(this, new FilteredDetectorFilterSlot(false)));
|
behaviours.add(filtering = new FilteringBehaviour(this, new FilteredDetectorFilterSlot(false))
|
||||||
|
.withCallback($ -> invVersionTracker.reset()));
|
||||||
|
behaviours.add(invVersionTracker = new VersionedInventoryTrackerBehaviour(this));
|
||||||
|
|
||||||
InterfaceProvider towardBlockFacing =
|
InterfaceProvider towardBlockFacing =
|
||||||
(w, p, s) -> new BlockFace(p, DirectedDirectionalBlock.getTargetDirection(s));
|
(w, p, s) -> new BlockFace(p, DirectedDirectionalBlock.getTargetDirection(s));
|
||||||
@ -105,11 +112,23 @@ public class SmartObserverBlockEntity extends SmartBlockEntity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!observedInventory.simulate()
|
if (observedInventory.hasInventory()) {
|
||||||
.extract()
|
boolean skipInv = invVersionTracker.stillWaiting(observedInventory);
|
||||||
.isEmpty()) {
|
invVersionTracker.awaitNewVersion(observedInventory);
|
||||||
activate();
|
|
||||||
return;
|
if (skipInv && sustainSignal)
|
||||||
|
turnOffTicks = DEFAULT_DELAY;
|
||||||
|
|
||||||
|
if (!skipInv) {
|
||||||
|
sustainSignal = false;
|
||||||
|
if (!observedInventory.simulate()
|
||||||
|
.extract()
|
||||||
|
.isEmpty()) {
|
||||||
|
sustainSignal = true;
|
||||||
|
activate();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!observedTank.simulate()
|
if (!observedTank.simulate()
|
||||||
|
@ -12,6 +12,7 @@ import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringB
|
|||||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.CapManipulationBehaviourBase.InterfaceProvider;
|
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.CapManipulationBehaviourBase.InterfaceProvider;
|
||||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour;
|
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour;
|
||||||
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.TankManipulationBehaviour;
|
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.TankManipulationBehaviour;
|
||||||
|
import com.simibubi.create.foundation.blockEntity.behaviour.inventory.VersionedInventoryTrackerBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.BlockFace;
|
import com.simibubi.create.foundation.utility.BlockFace;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
@ -39,6 +40,7 @@ public class ThresholdSwitchBlockEntity extends SmartBlockEntity {
|
|||||||
private FilteringBehaviour filtering;
|
private FilteringBehaviour filtering;
|
||||||
private InvManipulationBehaviour observedInventory;
|
private InvManipulationBehaviour observedInventory;
|
||||||
private TankManipulationBehaviour observedTank;
|
private TankManipulationBehaviour observedTank;
|
||||||
|
private VersionedInventoryTrackerBehaviour invVersionTracker;
|
||||||
|
|
||||||
public ThresholdSwitchBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
public ThresholdSwitchBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||||
super(type, pos, state);
|
super(type, pos, state);
|
||||||
@ -107,18 +109,26 @@ public class ThresholdSwitchBlockEntity extends SmartBlockEntity {
|
|||||||
|
|
||||||
} else if (observedInventory.hasInventory() || observedTank.hasInventory()) {
|
} else if (observedInventory.hasInventory() || observedTank.hasInventory()) {
|
||||||
if (observedInventory.hasInventory()) {
|
if (observedInventory.hasInventory()) {
|
||||||
|
|
||||||
// Item inventory
|
// Item inventory
|
||||||
IItemHandler inv = observedInventory.getInventory();
|
IItemHandler inv = observedInventory.getInventory();
|
||||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
if (invVersionTracker.stillWaiting(inv)) {
|
||||||
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
occupied = prevLevel;
|
||||||
int space = Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(slot));
|
totalSpace = 1f;
|
||||||
int count = stackInSlot.getCount();
|
|
||||||
if (space == 0)
|
} else {
|
||||||
continue;
|
invVersionTracker.awaitNewVersion(inv);
|
||||||
|
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||||
totalSpace += 1;
|
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
||||||
if (filtering.test(stackInSlot))
|
int space = Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(slot));
|
||||||
occupied += count * (1f / space);
|
int count = stackInSlot.getCount();
|
||||||
|
if (space == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
totalSpace += 1;
|
||||||
|
if (filtering.test(stackInSlot))
|
||||||
|
occupied += count * (1f / space);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +205,12 @@ public class ThresholdSwitchBlockEntity extends SmartBlockEntity {
|
|||||||
@Override
|
@Override
|
||||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||||
behaviours.add(filtering = new FilteringBehaviour(this, new FilteredDetectorFilterSlot(true))
|
behaviours.add(filtering = new FilteringBehaviour(this, new FilteredDetectorFilterSlot(true))
|
||||||
.withCallback($ -> this.updateCurrentLevel()));
|
.withCallback($ -> {
|
||||||
|
this.updateCurrentLevel();
|
||||||
|
invVersionTracker.reset();
|
||||||
|
}));
|
||||||
|
|
||||||
|
behaviours.add(invVersionTracker = new VersionedInventoryTrackerBehaviour(this));
|
||||||
|
|
||||||
InterfaceProvider towardBlockFacing =
|
InterfaceProvider towardBlockFacing =
|
||||||
(w, p, s) -> new BlockFace(p, DirectedDirectionalBlock.getTargetDirection(s));
|
(w, p, s) -> new BlockFace(p, DirectedDirectionalBlock.getTargetDirection(s));
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.simibubi.create.foundation.blockEntity.behaviour.inventory;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||||
|
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
|
||||||
|
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||||
|
|
||||||
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
|
public class VersionedInventoryTrackerBehaviour extends BlockEntityBehaviour {
|
||||||
|
|
||||||
|
public static final BehaviourType<VersionedInventoryTrackerBehaviour> TYPE = new BehaviourType<>();
|
||||||
|
|
||||||
|
private int ignoredId;
|
||||||
|
private int ignoredVersion;
|
||||||
|
|
||||||
|
public VersionedInventoryTrackerBehaviour(SmartBlockEntity be) {
|
||||||
|
super(be);
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean stillWaiting(InvManipulationBehaviour behaviour) {
|
||||||
|
return behaviour.hasInventory() && stillWaiting(behaviour.getInventory());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean stillWaiting(IItemHandler handler) {
|
||||||
|
if (handler instanceof VersionedInventoryWrapper viw)
|
||||||
|
return viw.getId() == ignoredId && viw.getVersion() == ignoredVersion;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void awaitNewVersion(InvManipulationBehaviour behaviour) {
|
||||||
|
if (behaviour.hasInventory())
|
||||||
|
awaitNewVersion(behaviour.getInventory());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void awaitNewVersion(IItemHandler handler) {
|
||||||
|
if (handler instanceof VersionedInventoryWrapper viw) {
|
||||||
|
ignoredId = viw.getId();
|
||||||
|
ignoredVersion = viw.getVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
ignoredVersion = -1;
|
||||||
|
ignoredId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BehaviourType<?> getType() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
package com.simibubi.create.foundation.blockEntity.behaviour.inventory;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraftforge.items.IItemHandlerModifiable;
|
||||||
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
|
|
||||||
|
public class VersionedInventoryWrapper implements IItemHandlerModifiable {
|
||||||
|
|
||||||
|
public static final AtomicInteger idGenerator = new AtomicInteger();
|
||||||
|
|
||||||
|
private IItemHandlerModifiable inventory;
|
||||||
|
private int version;
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
public VersionedInventoryWrapper(IItemHandlerModifiable inventory) {
|
||||||
|
this.id = idGenerator.getAndIncrement();
|
||||||
|
this.inventory = inventory;
|
||||||
|
this.version = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementVersion() {
|
||||||
|
version++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersion() {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSlots() {
|
||||||
|
return inventory.getSlots();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSlotLimit(int slot) {
|
||||||
|
return inventory.getSlotLimit(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isItemValid(int slot, ItemStack stack) {
|
||||||
|
return inventory.isItemValid(slot, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getStackInSlot(int slot) {
|
||||||
|
return inventory.getStackInSlot(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack insertItem(int slot, ItemStack stack, boolean simulate) {
|
||||||
|
int count = stack.getCount();
|
||||||
|
ItemStack result = inventory.insertItem(slot, stack, simulate);
|
||||||
|
if (!simulate && count != result.getCount())
|
||||||
|
incrementVersion();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||||
|
ItemStack result = inventory.extractItem(slot, amount, simulate);
|
||||||
|
if (!simulate && !result.isEmpty())
|
||||||
|
incrementVersion();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStackInSlot(int slot, ItemStack stack) {
|
||||||
|
ItemStack previousItem = inventory.getStackInSlot(slot);
|
||||||
|
inventory.setStackInSlot(slot, stack);
|
||||||
|
|
||||||
|
if (stack.isEmpty() == previousItem.isEmpty()) {
|
||||||
|
if (stack.isEmpty())
|
||||||
|
return;
|
||||||
|
if (ItemHandlerHelper.canItemStacksStack(stack, previousItem)
|
||||||
|
&& stack.getCount() == previousItem.getCount())
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
incrementVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user