Skip to content

Commit

Permalink
Merge pull request #493 from P3pp3rF1y/1.20.x-dev
Browse files Browse the repository at this point in the history
feat: ✨ Changed hopper upgrade to filter by contents of the target in…
  • Loading branch information
P3pp3rF1y authored Sep 29, 2024
2 parents df6cac7 + 0a86229 commit 4451e73
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 10 deletions.
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ org.gradle.daemon=false

mod_id=sophisticatedstorage
mod_group_id=sophisticatedstorage
mod_version=0.10.41
mod_version=0.10.42
sonar_project_key=sophisticatedstorage:SophisticatedStorage
github_package_url=https://maven.pkg.github.com/P3pp3rF1y/SophisticatedStorage

Expand All @@ -30,6 +30,6 @@ jade_cf_file_id=4614153
chipped_cf_file_id=5077656
resourcefullib_cf_file_id=5070629
athena_cf_file_id=4764357
sc_version=[1.20.1-0.6.31,1.20.4)
sc_version=[1.20.1-0.6.33,1.20.4)
sb_version=[1.20.1-3.20.5,1.20.4)
parchment_version=1.19.3-2023.03.12-1.20
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.wrapper.EmptyHandler;
import net.p3pp3rf1y.sophisticatedcore.api.IStorageWrapper;
import net.p3pp3rf1y.sophisticatedcore.inventory.ITrackedContentsItemHandler;
import net.p3pp3rf1y.sophisticatedcore.settings.memory.MemorySettingsCategory;
Expand All @@ -25,13 +26,15 @@
import net.p3pp3rf1y.sophisticatedcore.util.NBTHelper;
import net.p3pp3rf1y.sophisticatedcore.util.WorldHelper;
import net.p3pp3rf1y.sophisticatedstorage.block.StorageBlockBase;
import net.p3pp3rf1y.sophisticatedstorage.block.StorageInputBlockEntity;
import net.p3pp3rf1y.sophisticatedstorage.block.VerticalFacing;
import net.p3pp3rf1y.sophisticatedstorage.common.gui.BlockSide;
import net.p3pp3rf1y.sophisticatedstorage.init.ModItems;
import net.p3pp3rf1y.sophisticatedstorage.upgrades.INeighborChangeListenerUpgrade;

import javax.annotation.Nullable;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;

public class HopperUpgradeWrapper extends UpgradeWrapperBase<HopperUpgradeWrapper, HopperUpgradeItem>
Expand All @@ -40,17 +43,17 @@ public class HopperUpgradeWrapper extends UpgradeWrapperBase<HopperUpgradeWrappe
private Set<Direction> pullDirections = new LinkedHashSet<>();
private Set<Direction> pushDirections = new LinkedHashSet<>();
private boolean directionsInitialized = false;
private final Map<Direction, List<LazyOptional<IItemHandler>>> handlerCache = new EnumMap<>(Direction.class);
private final Map<Direction, ItemHandlerHolder> handlerCache = new EnumMap<>(Direction.class);

private final ContentsFilterLogic inputFilterLogic;
private final ContentsFilterLogic outputFilterLogic;
private final TargetContentsFilterLogic outputFilterLogic;
private long coolDownTime = 0;

protected HopperUpgradeWrapper(IStorageWrapper storageWrapper, ItemStack upgrade, Consumer<ItemStack> upgradeSaveHandler) {
super(storageWrapper, upgrade, upgradeSaveHandler);
inputFilterLogic = new ContentsFilterLogic(upgrade, upgradeSaveHandler, upgradeItem.getInputFilterSlotCount(), storageWrapper::getInventoryHandler,
storageWrapper.getSettingsHandler().getTypeCategory(MemorySettingsCategory.class), "inputFilter");
outputFilterLogic = new ContentsFilterLogic(upgrade, upgradeSaveHandler, upgradeItem.getOutputFilterSlotCount(), storageWrapper::getInventoryHandler,
outputFilterLogic = new TargetContentsFilterLogic(upgrade, upgradeSaveHandler, upgradeItem.getOutputFilterSlotCount(), storageWrapper::getInventoryHandler,
storageWrapper.getSettingsHandler().getTypeCategory(MemorySettingsCategory.class), "outputFilter");

deserialize();
Expand Down Expand Up @@ -105,6 +108,7 @@ public void tick(@Nullable LivingEntity entity, Level level, BlockPos pos) {
private boolean pushItemsToContainer(WorldlyContainer worldlyContainer, Direction face) {
ITrackedContentsItemHandler fromHandler = storageWrapper.getInventoryForUpgradeProcessing();

outputFilterLogic.setInventory(EmptyHandler.INSTANCE);
for (int slot = 0; slot < fromHandler.getSlots(); slot++) {
ItemStack slotStack = fromHandler.getStackInSlot(slot);
if (!slotStack.isEmpty() && outputFilterLogic.matchesFilter(slotStack)) {
Expand Down Expand Up @@ -192,6 +196,7 @@ private boolean pullItems(IItemHandler fromHandler) {
}

private boolean pushItems(IItemHandler toHandler) {
outputFilterLogic.setInventory(toHandler);
return moveItems(storageWrapper.getInventoryForUpgradeProcessing(), toHandler, outputFilterLogic);
}

Expand Down Expand Up @@ -221,12 +226,14 @@ && needsCacheUpdate(level, pos, direction)) {
}

private boolean needsCacheUpdate(Level level, BlockPos pos, Direction direction) {
List<LazyOptional<IItemHandler>> handlers = handlerCache.get(direction);
if (handlers == null || handlers.isEmpty()) {
ItemHandlerHolder holder = handlerCache.get(direction);
if (holder == null || holder.handlers().isEmpty()) {
return !level.getBlockState(pos).isAir();
} else if (holder.refreshOnEveryNeighborChange()) {
return true;
}

for (LazyOptional<IItemHandler> handler : handlers) {
for (LazyOptional<IItemHandler> handler : holder.handlers()) {
if (!handler.isPresent()) {
return true;
}
Expand All @@ -244,22 +251,28 @@ public void updateCacheOnSide(Level level, BlockPos pos, Direction direction) {
BlockState storageState = level.getBlockState(pos);
List<BlockPos> offsetPositions = storageState.getBlock() instanceof StorageBlockBase storageBlock ? storageBlock.getNeighborPos(storageState, pos, direction) : List.of(pos.relative(direction));
List<LazyOptional<IItemHandler>> caches = new ArrayList<>();
AtomicBoolean refreshOnEveryNeighborChange = new AtomicBoolean(false);
offsetPositions.forEach(offsetPos ->
WorldHelper.getLoadedBlockEntity(level, offsetPos).ifPresent(blockEntity -> {
if (blockEntity instanceof StorageInputBlockEntity input) {
refreshOnEveryNeighborChange.set(true);
blockEntity = input.getControllerPos().map(level::getBlockEntity).orElse(blockEntity);
}

LazyOptional<IItemHandler> lazyOptional = blockEntity.getCapability(ForgeCapabilities.ITEM_HANDLER, direction.getOpposite());
if (lazyOptional.isPresent()) {
lazyOptional.addListener(l -> updateCacheOnSide(level, pos, direction));
caches.add(lazyOptional);
}
}));
handlerCache.put(direction, caches);
handlerCache.put(direction, new ItemHandlerHolder(caches, refreshOnEveryNeighborChange.get()));
}

private List<LazyOptional<IItemHandler>> getItemHandlers(Level level, BlockPos pos, Direction direction) {
if (!handlerCache.containsKey(direction)) {
updateCacheOnSide(level, pos, direction);
}
return handlerCache.getOrDefault(direction, Collections.emptyList());
return handlerCache.containsKey(direction) ? handlerCache.get(direction).handlers() : Collections.emptyList();
}

public ContentsFilterLogic getInputFilterLogic() {
Expand Down Expand Up @@ -319,4 +332,7 @@ public void initDirections(Direction pushDirection, Direction pullDirection) {
setPushingTo(pushDirection, true);
setPullingFrom(pullDirection, true);
}

private record ItemHandlerHolder(List<LazyOptional<IItemHandler>> handlers, boolean refreshOnEveryNeighborChange) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package net.p3pp3rf1y.sophisticatedstorage.upgrades.hopper;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.items.IItemHandler;
import net.p3pp3rf1y.sophisticatedcore.inventory.InventoryHandler;
import net.p3pp3rf1y.sophisticatedcore.inventory.ItemStackKey;
import net.p3pp3rf1y.sophisticatedcore.settings.memory.MemorySettingsCategory;
import net.p3pp3rf1y.sophisticatedcore.upgrades.ContentsFilterLogic;
import net.p3pp3rf1y.sophisticatedcore.util.InventoryHelper;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Supplier;

public class TargetContentsFilterLogic extends ContentsFilterLogic {
private Set<ItemStackKey> inventoryFilterStacks = new HashSet<>();
private final LoadingCache<IItemHandler, Set<ItemStackKey>> inventoryCache = CacheBuilder.newBuilder().expireAfterWrite(5, TimeUnit.SECONDS).build(new CacheLoader<>() {
@Override
public Set<ItemStackKey> load(IItemHandler inventory) {
return InventoryHelper.getUniqueStacks(inventory);
}
});

public TargetContentsFilterLogic(ItemStack upgrade, Consumer<ItemStack> saveHandler, int filterSlotCount, Supplier<InventoryHandler> getInventoryHandler, MemorySettingsCategory memorySettings, String parentTagKey) {
super(upgrade, saveHandler, filterSlotCount, getInventoryHandler, memorySettings, parentTagKey);
}

public void setInventory(IItemHandler inventory) {
inventoryFilterStacks = inventoryCache.getUnchecked(inventory);
}

@Override
public boolean matchesFilter(ItemStack stack) {
if (!shouldFilterByStorage()) {
return super.matchesFilter(stack);
}

for (ItemStackKey filterStack : inventoryFilterStacks) {
if (stackMatchesFilter(stack, filterStack.getStack())) {
return true;
}
}
return false;
}
}

0 comments on commit 4451e73

Please sign in to comment.