diff options
| author | shedaniel <daniel@shedaniel.me> | 2022-04-13 19:32:33 +0800 |
|---|---|---|
| committer | shedaniel <daniel@shedaniel.me> | 2022-04-13 19:32:33 +0800 |
| commit | 8902036eb80f33310079ddd8ea85212e2aebc6cb (patch) | |
| tree | 062ed052df9f5f20a406fec8ce2a19f9e25d5768 | |
| parent | 6397967ecc1d2fba958c9feb59f55eff52d5a5db (diff) | |
| download | RoughlyEnoughItems-8902036eb80f33310079ddd8ea85212e2aebc6cb.tar.gz RoughlyEnoughItems-8902036eb80f33310079ddd8ea85212e2aebc6cb.tar.bz2 RoughlyEnoughItems-8902036eb80f33310079ddd8ea85212e2aebc6cb.zip | |
Make craftable filter account for container changes
5 files changed, 68 insertions, 23 deletions
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 8f29b8989..09d43c2a1 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 @@ -64,6 +64,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.util.LazyLoadedValue; import net.minecraft.util.Mth; import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -244,6 +245,30 @@ public class ClientHelperImpl implements ClientHelper { } @ApiStatus.Internal + public Long2LongMap _getContainerItemsTypes() { + EntryDefinition<ItemStack> definition; + try { + definition = VanillaEntryTypes.ITEM.getDefinition(); + } catch (NullPointerException e) { + return Long2LongMaps.EMPTY_MAP; + } + Long2LongOpenHashMap map = new Long2LongOpenHashMap(); + AbstractContainerMenu menu = Minecraft.getInstance().player.containerMenu; + if (menu != null) { + for (Slot slot : menu.slots) { + ItemStack stack = slot.getItem(); + + if (!stack.isEmpty()) { + long hash = definition.hash(null, stack, ComparisonContext.FUZZY); + long newCount = map.getOrDefault(hash, 0) + Math.max(0, stack.getCount()); + map.put(hash, newCount); + } + } + } + return map; + } + + @ApiStatus.Internal public void openRecipeViewingScreen(Map<DisplayCategory<?>, List<DisplaySpec>> map, @Nullable CategoryIdentifier<?> category, List<EntryStack<?>> ingredientNotice, List<EntryStack<?>> resultNotice) { LegacyWrapperViewSearchBuilder builder = new LegacyWrapperViewSearchBuilder(map); for (EntryStack<?> stack : ingredientNotice) { 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 73a5bc946..74c010f83 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() && Minecraft.getInstance().player.tickCount % 20 == 0) { + if (Minecraft.getInstance().player != null && !PluginManager.areAnyReloading() && Minecraft.getInstance().player.tickCount % 5 == 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 3912829d1..1996dc5ef 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 @@ -26,16 +26,13 @@ package me.shedaniel.rei.impl.client.gui.craftable; 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; public class CraftableFilter { public static final CraftableFilter INSTANCE = new CraftableFilter(); private boolean dirty = false; private Long2LongMap invStacks = new Long2LongOpenHashMap(); + private Long2LongMap containerStacks = new Long2LongOpenHashMap(); public void markDirty() { dirty = true; @@ -63,17 +60,21 @@ public class CraftableFilter { invStacks = currentStacks; markDirty(); } - } + if (dirty) return; - public int matches(EntryStack<?> stack, Iterable<SlotAccessor> 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 2; - } + try { + currentStacks = ClientHelperImpl.getInstance()._getContainerItemsTypes(); + } catch (Throwable throwable) { + throwable.printStackTrace(); + currentStacks = Long2LongMaps.EMPTY_MAP; + } + if (!currentStacks.equals(this.containerStacks)) { + containerStacks = currentStacks; + markDirty(); } - return 0; + } + + public Long2LongMap getInvStacks() { + return invStacks; } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java index d9df0215a..a7b762833 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java @@ -77,9 +77,11 @@ import net.minecraft.client.gui.screens.Screen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.player.LocalPlayer; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.resources.sounds.SimpleSoundInstance; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.sounds.SoundEvents; import net.minecraft.util.Mth; import net.minecraft.world.InteractionResult; import net.minecraft.world.item.CreativeModeTab; @@ -711,6 +713,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg TransferHandler.Result transferResult = handler.handle(context); if (transferResult.isBlocking()) { + minecraft.getSoundManager().play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F)); if (transferResult.isReturningToScreen() && Minecraft.getInstance().screen != containerScreen) { Minecraft.getInstance().setScreen(containerScreen); REIRuntime.getInstance().getOverlay().ifPresent(ScreenOverlay::queueReloadOverlay); 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 857f3aaea..ee348b71b 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 @@ -42,6 +42,8 @@ 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.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.plugins.PluginManager; import me.shedaniel.rei.api.common.transfer.info.MenuInfo; @@ -58,6 +60,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; @@ -377,7 +380,23 @@ public class ViewsImpl implements Views { Iterable<SlotAccessor> inputSlots = info != null ? info.getInputSlots(context.withDisplay(display)) : Collections.emptySet(); int slotsCraftable = 0; List<EntryIngredient> requiredInput = display.getRequiredEntries(); - Long2LongMap usedCount = new Long2LongOpenHashMap(); + Long2LongMap invCount = new Long2LongOpenHashMap(CraftableFilter.INSTANCE.getInvStacks()); + for (SlotAccessor inputSlot : inputSlots) { + ItemStack stack = inputSlot.getItemStack(); + + EntryDefinition<ItemStack> definition; + try { + definition = VanillaEntryTypes.ITEM.getDefinition(); + } catch (NullPointerException e) { + break; + } + + if (!stack.isEmpty()) { + long hash = definition.hash(null, stack, ComparisonContext.FUZZY); + long newCount = invCount.get(hash) + Math.max(0, stack.getCount()); + invCount.put(hash, newCount); + } + } for (EntryIngredient slot : requiredInput) { if (slot.isEmpty()) { slotsCraftable++; @@ -385,14 +404,11 @@ public class ViewsImpl implements Views { } for (EntryStack<?> slotPossible : slot) { if (slotPossible.getType() != VanillaEntryTypes.ITEM) continue; + ItemStack stack = slotPossible.castValue(); 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); - } - + long availableAmount = invCount.get(hashFuzzy); + if (availableAmount >= stack.getCount()) { + invCount.put(hashFuzzy, availableAmount - stack.getCount()); slotsCraftable++; break; } |
