From 7584809f2db150d7f9bf2fdbbebc0891cad812bb Mon Sep 17 00:00:00 2001 From: shedaniel Date: Wed, 13 Apr 2022 16:35:59 +0800 Subject: Make craftable filter check count --- .../rei/impl/client/ClientHelperImpl.java | 29 ++++++++++++++-------- .../rei/impl/client/gui/ScreenOverlayImpl.java | 2 +- .../impl/client/gui/craftable/CraftableFilter.java | 25 +++++++++---------- .../shedaniel/rei/impl/client/view/ViewsImpl.java | 14 ++++++++++- 4 files changed, 45 insertions(+), 25 deletions(-) (limited to 'runtime') diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java index 20396d980..70d53b917 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java @@ -25,8 +25,9 @@ package me.shedaniel.rei.impl.client; import com.google.common.base.Suppliers; import io.netty.buffer.Unpooled; -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import it.unimi.dsi.fastutil.longs.LongSet; +import it.unimi.dsi.fastutil.longs.Long2LongMap; +import it.unimi.dsi.fastutil.longs.Long2LongMaps; +import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; import me.shedaniel.architectury.networking.NetworkManager; import me.shedaniel.architectury.platform.Platform; import me.shedaniel.rei.RoughlyEnoughItemsNetwork; @@ -40,6 +41,8 @@ import me.shedaniel.rei.api.client.registry.display.DisplayCategory; import me.shedaniel.rei.api.client.view.ViewSearchBuilder; import me.shedaniel.rei.api.common.category.CategoryIdentifier; import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.entry.comparison.ComparisonContext; +import me.shedaniel.rei.api.common.entry.type.EntryDefinition; import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; import me.shedaniel.rei.api.common.util.EntryStacks; import me.shedaniel.rei.api.common.util.FormattingUtils; @@ -54,6 +57,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen; +import net.minecraft.core.NonNullList; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TranslatableComponent; @@ -222,17 +226,22 @@ public class ClientHelperImpl implements ClientHelper { } @ApiStatus.Internal - public LongSet _getInventoryItemsTypes() { + public Long2LongMap _getInventoryItemsTypes() { + EntryDefinition definition; try { - VanillaEntryTypes.ITEM.getDefinition(); + definition = VanillaEntryTypes.ITEM.getDefinition(); } catch (NullPointerException e) { - return new LongOpenHashSet(); + return Long2LongMaps.EMPTY_MAP; + } + Long2LongOpenHashMap map = new Long2LongOpenHashMap(); + for (NonNullList compartment : Minecraft.getInstance().player.getInventory().compartments) { + for (ItemStack stack : compartment) { + long hash = definition.hash(null, stack, ComparisonContext.FUZZY); + long newCount = map.getOrDefault(hash, 0) + Math.max(0, stack.getCount()); + map.put(hash, newCount); + } } - return Minecraft.getInstance().player.inventory.compartments.stream() - .flatMap(Collection::stream) - .map(EntryStacks::of) - .mapToLong(EntryStacks::hashFuzzy) - .collect(LongOpenHashSet::new, LongOpenHashSet::add, LongOpenHashSet::addAll); + return map; } @ApiStatus.Internal diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java index ca1e525e8..a8f1fc930 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java @@ -138,7 +138,7 @@ public class ScreenOverlayImpl extends ScreenOverlay { public void tick() { if (REIRuntimeImpl.getSearchField() != null) { REIRuntimeImpl.getSearchField().tick(); - if (Minecraft.getInstance().player != null && !PluginManager.areAnyReloading()) { + if (Minecraft.getInstance().player != null && !PluginManager.areAnyReloading() && Minecraft.getInstance().player.tickCount % 20 == 0) { CraftableFilter.INSTANCE.tick(); } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/craftable/CraftableFilter.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/craftable/CraftableFilter.java index 59c23cca0..3912829d1 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/craftable/CraftableFilter.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/craftable/CraftableFilter.java @@ -23,20 +23,19 @@ package me.shedaniel.rei.impl.client.gui.craftable; -import it.unimi.dsi.fastutil.longs.LongOpenHashSet; -import it.unimi.dsi.fastutil.longs.LongSet; -import it.unimi.dsi.fastutil.longs.LongSets; +import it.unimi.dsi.fastutil.longs.Long2LongMap; +import it.unimi.dsi.fastutil.longs.Long2LongMaps; +import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; import me.shedaniel.rei.api.common.entry.EntryStack; import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; import me.shedaniel.rei.api.common.transfer.info.stack.SlotAccessor; import me.shedaniel.rei.api.common.util.EntryStacks; import me.shedaniel.rei.impl.client.ClientHelperImpl; -import net.minecraft.client.Minecraft; public class CraftableFilter { public static final CraftableFilter INSTANCE = new CraftableFilter(); private boolean dirty = false; - private LongSet invStacks = new LongOpenHashSet(); + private Long2LongMap invStacks = new Long2LongOpenHashMap(); public void markDirty() { dirty = true; @@ -53,28 +52,28 @@ public class CraftableFilter { public void tick() { if (dirty) return; - LongSet currentStacks; + Long2LongMap currentStacks; try { currentStacks = ClientHelperImpl.getInstance()._getInventoryItemsTypes(); } catch (Throwable throwable) { throwable.printStackTrace(); - currentStacks = LongSets.EMPTY_SET; + currentStacks = Long2LongMaps.EMPTY_MAP; } if (!currentStacks.equals(this.invStacks)) { - invStacks = new LongOpenHashSet(currentStacks); + invStacks = currentStacks; markDirty(); } } - public boolean matches(EntryStack stack, Iterable inputSlots) { - if (invStacks.contains(EntryStacks.hashFuzzy(stack))) return true; - if (stack.getType() != VanillaEntryTypes.ITEM) return false; + public int matches(EntryStack stack, Iterable inputSlots, long currentUsed) { + long availableAmount = invStacks.get(EntryStacks.hashFuzzy(stack)); + if (availableAmount > currentUsed) return 1; for (SlotAccessor slot : inputSlots) { EntryStack itemStack = EntryStacks.of(slot.getItemStack()); if (!itemStack.isEmpty() && EntryStacks.equalsFuzzy(itemStack, stack)) { - return true; + return 2; } } - return false; + return 0; } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/view/ViewsImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/view/ViewsImpl.java index fe468ac97..938bceac0 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/view/ViewsImpl.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/view/ViewsImpl.java @@ -27,6 +27,8 @@ import com.google.common.base.Stopwatch; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import it.unimi.dsi.fastutil.longs.Long2LongMap; +import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap; import me.shedaniel.rei.RoughlyEnoughItemsCore; import me.shedaniel.rei.api.client.config.ConfigObject; import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; @@ -40,6 +42,7 @@ import me.shedaniel.rei.api.common.display.Display; import me.shedaniel.rei.api.common.display.DisplayMerger; import me.shedaniel.rei.api.common.entry.EntryIngredient; import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; import me.shedaniel.rei.api.common.plugins.PluginManager; import me.shedaniel.rei.api.common.transfer.info.MenuInfo; import me.shedaniel.rei.api.common.transfer.info.MenuInfoContext; @@ -370,13 +373,22 @@ public class ViewsImpl implements Views { Iterable inputSlots = info != null ? info.getInputSlots(context) : Collections.emptySet(); int slotsCraftable = 0; List requiredInput = display.getRequiredEntries(); + Long2LongMap usedCount = new Long2LongOpenHashMap(); for (EntryIngredient slot : requiredInput) { if (slot.isEmpty()) { slotsCraftable++; continue; } for (EntryStack slotPossible : slot) { - if (CraftableFilter.INSTANCE.matches(slotPossible, inputSlots)) { + if (slotPossible.getType() != VanillaEntryTypes.ITEM) continue; + long hashFuzzy = EntryStacks.hashFuzzy(slotPossible); + long currentUsed = usedCount.get(hashFuzzy); + int matches = CraftableFilter.INSTANCE.matches(slotPossible, inputSlots, currentUsed); + if (matches != 0) { + if (matches == 1) { + usedCount.put(hashFuzzy, currentUsed + 1); + } + slotsCraftable++; break; } -- cgit