mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-10 12:33:57 +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
|
||||
description: The version of the mod you were using when the bug occured
|
||||
options:
|
||||
- "0.5.1e"
|
||||
- "0.5.1d"
|
||||
- "0.5.1c"
|
||||
- "0.5.1b"
|
||||
|
@ -202,6 +202,7 @@ dependencies {
|
||||
// runtimeOnly fg.deobf("slimeknights.tconstruct:TConstruct:1.16.5-3.1.1.252")
|
||||
// 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 }
|
||||
// runtimeOnly fg.deobf("maven.modrinth:spark:1.10.38-forge")
|
||||
|
||||
// https://discord.com/channels/313125603924639766/725850371834118214/910619168821354497
|
||||
// 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) {
|
||||
super.addBehaviours(behaviours);
|
||||
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::canInsertFrom)
|
||||
.setInsertionHandler(this::tryInsertingFromSide));
|
||||
.setInsertionHandler(this::tryInsertingFromSide).considerOccupiedWhen(this::isOccupied));
|
||||
behaviours.add(new TransportedItemStackHandlerBehaviour(this, this::applyToAllItems)
|
||||
.withStackPlacement(this::getWorldPositionOf));
|
||||
}
|
||||
@ -464,6 +464,22 @@ public class BeltBlockEntity extends KineticBlockEntity {
|
||||
return false;
|
||||
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) {
|
||||
BeltBlockEntity nextBeltController = getControllerBE();
|
||||
@ -493,11 +509,7 @@ public class BeltBlockEntity extends KineticBlockEntity {
|
||||
}
|
||||
}
|
||||
|
||||
if (getSpeed() == 0)
|
||||
return inserted;
|
||||
if (getMovementFacing() == side.getOpposite())
|
||||
return inserted;
|
||||
if (!nextInventory.canInsertAtFromSide(index, side))
|
||||
if (isOccupied(side))
|
||||
return inserted;
|
||||
if (simulate)
|
||||
return empty;
|
||||
|
@ -33,6 +33,7 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
||||
public static final BehaviourType<DirectBeltInputBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
private InsertionCallback tryInsert;
|
||||
private OccupiedPredicate isOccupied;
|
||||
private AvailabilityPredicate canInsert;
|
||||
private Supplier<Boolean> supportsBeltFunnels;
|
||||
|
||||
@ -40,6 +41,7 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
||||
super(be);
|
||||
tryInsert = this::defaultInsertionCallback;
|
||||
canInsert = d -> true;
|
||||
isOccupied = d -> false;
|
||||
supportsBeltFunnels = () -> false;
|
||||
}
|
||||
|
||||
@ -57,6 +59,11 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
||||
canInsert = pred;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DirectBeltInputBehaviour considerOccupiedWhen(OccupiedPredicate pred) {
|
||||
isOccupied = pred;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DirectBeltInputBehaviour setInsertionHandler(InsertionCallback callback) {
|
||||
tryInsert = callback;
|
||||
@ -75,6 +82,10 @@ public class DirectBeltInputBehaviour extends BlockEntityBehaviour {
|
||||
return canInsert.test(side);
|
||||
}
|
||||
|
||||
public boolean isOccupied(Direction side) {
|
||||
return isOccupied.test(side);
|
||||
}
|
||||
|
||||
public ItemStack handleInsertion(ItemStack stack, Direction side, boolean 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);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface OccupiedPredicate {
|
||||
public boolean test(Direction side);
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface AvailabilityPredicate {
|
||||
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.blockEntity.SmartBlockEntity;
|
||||
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.ExtractionCountMode;
|
||||
import com.simibubi.create.foundation.particle.AirParticleData;
|
||||
@ -81,6 +82,8 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
||||
int airCurrentUpdateCooldown;
|
||||
int entitySearchCooldown;
|
||||
|
||||
VersionedInventoryTrackerBehaviour invVersionTracker;
|
||||
|
||||
LazyOptional<IItemHandler> capAbove;
|
||||
LazyOptional<IItemHandler> capBelow;
|
||||
|
||||
@ -101,6 +104,7 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
||||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen((d) -> canDirectlyInsertCached()));
|
||||
behaviours.add(invVersionTracker = new VersionedInventoryTrackerBehaviour(this));
|
||||
registerAwardables(behaviours, AllAdvancements.CHUTE);
|
||||
}
|
||||
|
||||
@ -336,15 +340,20 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
||||
private void handleInput(IItemHandler inv, float startLocation) {
|
||||
if (inv == null)
|
||||
return;
|
||||
if (invVersionTracker.stillWaiting(inv))
|
||||
return;
|
||||
Predicate<ItemStack> canAccept = this::canAcceptItem;
|
||||
int count = getExtractionAmount();
|
||||
ExtractionCountMode mode = getExtractionMode();
|
||||
if (mode == ExtractionCountMode.UPTO || !ItemHelper.extract(inv, canAccept, mode, count, true)
|
||||
.isEmpty()) {
|
||||
ItemStack extracted = ItemHelper.extract(inv, canAccept, mode, count, false);
|
||||
if (!extracted.isEmpty())
|
||||
if (!extracted.isEmpty()) {
|
||||
setItem(extracted, startLocation);
|
||||
return;
|
||||
}
|
||||
}
|
||||
invVersionTracker.awaitNewVersion(inv);
|
||||
}
|
||||
|
||||
private boolean handleDownwardOutput(boolean simulate) {
|
||||
@ -359,12 +368,16 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
||||
if (capBelow.isPresent()) {
|
||||
if (level.isClientSide && !isVirtual())
|
||||
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();
|
||||
if (!simulate)
|
||||
setItem(remainder, itemPosition.getValue(0));
|
||||
if (remainder.getCount() != held.getCount())
|
||||
return true;
|
||||
invVersionTracker.awaitNewVersion(inv);
|
||||
if (direction == Direction.DOWN)
|
||||
return false;
|
||||
}
|
||||
@ -414,10 +427,16 @@ public class ChuteBlockEntity extends SmartBlockEntity implements IHaveGoggleInf
|
||||
if (level.isClientSide && !isVirtual() && !ChuteBlock.isChute(stateAbove))
|
||||
return false;
|
||||
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)
|
||||
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) {
|
||||
item = stack;
|
||||
itemPosition.startWithValue(insertionPos);
|
||||
invVersionTracker.reset();
|
||||
if (!level.isClientSide) {
|
||||
notifyUpdate();
|
||||
award(AllAdvancements.CHUTE);
|
||||
|
@ -51,7 +51,8 @@ public class SmartChuteBlockEntity extends ChuteBlockEntity {
|
||||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -240,7 +240,7 @@ public class DepotBehaviour extends BlockEntityBehaviour {
|
||||
|
||||
public void addSubBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
behaviours.add(new DirectBeltInputBehaviour(blockEntity).allowingBeltFunnels()
|
||||
.setInsertionHandler(this::tryInsertingFromSide));
|
||||
.setInsertionHandler(this::tryInsertingFromSide).considerOccupiedWhen(this::isOccupied));
|
||||
transportedHandler = new TransportedItemStackHandlerBehaviour(blockEntity, this::applyToAllItems)
|
||||
.withStackPlacement(this::getWorldPositionOf);
|
||||
behaviours.add(transportedHandler);
|
||||
@ -339,14 +339,20 @@ public class DepotBehaviour extends BlockEntityBehaviour {
|
||||
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) {
|
||||
ItemStack inserted = transportedStack.stack;
|
||||
|
||||
if (!getHeldItemStack().isEmpty() && !canMergeItems())
|
||||
return inserted;
|
||||
if (!isOutputEmpty() && !canMergeItems())
|
||||
return inserted;
|
||||
if (!canAcceptItems.get())
|
||||
if (isOccupied(side))
|
||||
return inserted;
|
||||
|
||||
int size = transportedStack.stack.getCount();
|
||||
|
@ -3,6 +3,8 @@ package com.simibubi.create.content.logistics.funnel;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
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.filtering.FilteringBehaviour;
|
||||
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.utility.BlockFace;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
@ -42,6 +45,7 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
||||
|
||||
private FilteringBehaviour filtering;
|
||||
private InvManipulationBehaviour invManipulation;
|
||||
private VersionedInventoryTrackerBehaviour invVersionTracker;
|
||||
private int extractionCooldown;
|
||||
|
||||
private WeakReference<ItemEntity> lastObserved; // In-world Extractors only
|
||||
@ -111,6 +115,9 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
||||
}
|
||||
|
||||
private void activateExtractor() {
|
||||
if (invVersionTracker.stillWaiting(invManipulation))
|
||||
return;
|
||||
|
||||
BlockState blockState = getBlockState();
|
||||
Direction facing = AbstractFunnelBlock.getFunnelFacing(blockState);
|
||||
|
||||
@ -140,8 +147,10 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
||||
ExtractionCountMode mode = getModeToExtract();
|
||||
ItemStack stack = invManipulation.simulate()
|
||||
.extract(mode, amountToExtract);
|
||||
if (stack.isEmpty())
|
||||
if (stack.isEmpty()) {
|
||||
invVersionTracker.awaitNewVersion(invManipulation);
|
||||
return;
|
||||
}
|
||||
for (ItemEntity itemEntity : level.getEntitiesOfClass(ItemEntity.class, area)) {
|
||||
lastObserved = new WeakReference<>(itemEntity);
|
||||
return;
|
||||
@ -189,6 +198,9 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
||||
}
|
||||
|
||||
private void activateExtractingBeltFunnel() {
|
||||
if (invVersionTracker.stillWaiting(invManipulation))
|
||||
return;
|
||||
|
||||
BlockState blockState = getBlockState();
|
||||
Direction facing = blockState.getValue(BeltFunnelBlock.HORIZONTAL_FACING);
|
||||
DirectBeltInputBehaviour inputBehaviour =
|
||||
@ -198,14 +210,24 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering
|
||||
return;
|
||||
if (!inputBehaviour.canInsertFromSide(facing))
|
||||
return;
|
||||
if (inputBehaviour.isOccupied(facing))
|
||||
return;
|
||||
|
||||
int amountToExtract = getAmountToExtract();
|
||||
ExtractionCountMode mode = getModeToExtract();
|
||||
ItemStack stack =
|
||||
invManipulation.extract(mode, amountToExtract, s -> inputBehaviour.handleInsertion(s, facing, true)
|
||||
.isEmpty());
|
||||
if (stack.isEmpty())
|
||||
MutableBoolean deniedByInsertion = new MutableBoolean(false);
|
||||
ItemStack stack = invManipulation.extract(mode, amountToExtract, s -> {
|
||||
ItemStack handleInsertion = inputBehaviour.handleInsertion(s, facing, true);
|
||||
if (handleInsertion.isEmpty())
|
||||
return true;
|
||||
deniedByInsertion.setTrue();
|
||||
return false;
|
||||
});
|
||||
if (stack.isEmpty()) {
|
||||
if (deniedByInsertion.isFalse())
|
||||
invVersionTracker.awaitNewVersion(invManipulation.getInventory());
|
||||
return;
|
||||
}
|
||||
flap(false);
|
||||
onTransfer(stack);
|
||||
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)
|
||||
.getOpposite()));
|
||||
behaviours.add(invManipulation);
|
||||
|
||||
behaviours.add(invVersionTracker = new VersionedInventoryTrackerBehaviour(this));
|
||||
|
||||
filtering = new FilteringBehaviour(this, new FunnelFilterSlotPositioning());
|
||||
filtering.showCountWhen(this::supportsAmountOnFilter);
|
||||
filtering.onlyActiveWhen(this::supportsFiltering);
|
||||
filtering.withCallback($ -> invVersionTracker.reset());
|
||||
behaviours.add(filtering);
|
||||
|
||||
|
||||
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::supportsDirectBeltInput)
|
||||
.setInsertionHandler(this::handleDirectBeltInput));
|
||||
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.SmartBlockEntity;
|
||||
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 net.minecraft.core.BlockPos;
|
||||
@ -260,8 +261,8 @@ public class ItemVaultBlockEntity extends SmartBlockEntity implements IMultiBloc
|
||||
}
|
||||
}
|
||||
|
||||
CombinedInvWrapper combinedInvWrapper = new CombinedInvWrapper(invs);
|
||||
itemCapability = LazyOptional.of(() -> combinedInvWrapper);
|
||||
IItemHandler itemHandler = new VersionedInventoryWrapper(new CombinedInvWrapper(invs));
|
||||
itemCapability = LazyOptional.of(() -> itemHandler);
|
||||
}
|
||||
|
||||
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.InvManipulationBehaviour;
|
||||
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.Iterate;
|
||||
|
||||
@ -31,6 +32,10 @@ public class SmartObserverBlockEntity extends SmartBlockEntity {
|
||||
private FilteringBehaviour filtering;
|
||||
private InvManipulationBehaviour observedInventory;
|
||||
private TankManipulationBehaviour observedTank;
|
||||
|
||||
private VersionedInventoryTrackerBehaviour invVersionTracker;
|
||||
private boolean sustainSignal;
|
||||
|
||||
public int turnOffTicks = 0;
|
||||
|
||||
public SmartObserverBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
@ -40,7 +45,9 @@ public class SmartObserverBlockEntity extends SmartBlockEntity {
|
||||
|
||||
@Override
|
||||
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 =
|
||||
(w, p, s) -> new BlockFace(p, DirectedDirectionalBlock.getTargetDirection(s));
|
||||
@ -105,11 +112,23 @@ public class SmartObserverBlockEntity extends SmartBlockEntity {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!observedInventory.simulate()
|
||||
.extract()
|
||||
.isEmpty()) {
|
||||
activate();
|
||||
return;
|
||||
if (observedInventory.hasInventory()) {
|
||||
boolean skipInv = invVersionTracker.stillWaiting(observedInventory);
|
||||
invVersionTracker.awaitNewVersion(observedInventory);
|
||||
|
||||
if (skipInv && sustainSignal)
|
||||
turnOffTicks = DEFAULT_DELAY;
|
||||
|
||||
if (!skipInv) {
|
||||
sustainSignal = false;
|
||||
if (!observedInventory.simulate()
|
||||
.extract()
|
||||
.isEmpty()) {
|
||||
sustainSignal = true;
|
||||
activate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.InvManipulationBehaviour;
|
||||
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 net.minecraft.core.BlockPos;
|
||||
@ -39,6 +40,7 @@ public class ThresholdSwitchBlockEntity extends SmartBlockEntity {
|
||||
private FilteringBehaviour filtering;
|
||||
private InvManipulationBehaviour observedInventory;
|
||||
private TankManipulationBehaviour observedTank;
|
||||
private VersionedInventoryTrackerBehaviour invVersionTracker;
|
||||
|
||||
public ThresholdSwitchBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
||||
super(type, pos, state);
|
||||
@ -107,18 +109,26 @@ public class ThresholdSwitchBlockEntity extends SmartBlockEntity {
|
||||
|
||||
} else if (observedInventory.hasInventory() || observedTank.hasInventory()) {
|
||||
if (observedInventory.hasInventory()) {
|
||||
|
||||
// Item inventory
|
||||
IItemHandler inv = observedInventory.getInventory();
|
||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
||||
int space = Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(slot));
|
||||
int count = stackInSlot.getCount();
|
||||
if (space == 0)
|
||||
continue;
|
||||
|
||||
totalSpace += 1;
|
||||
if (filtering.test(stackInSlot))
|
||||
occupied += count * (1f / space);
|
||||
if (invVersionTracker.stillWaiting(inv)) {
|
||||
occupied = prevLevel;
|
||||
totalSpace = 1f;
|
||||
|
||||
} else {
|
||||
invVersionTracker.awaitNewVersion(inv);
|
||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||
ItemStack stackInSlot = inv.getStackInSlot(slot);
|
||||
int space = Math.min(stackInSlot.getMaxStackSize(), inv.getSlotLimit(slot));
|
||||
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
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
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 =
|
||||
(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