aboutsummaryrefslogtreecommitdiff
path: root/runtime/src/main/java/me/shedaniel
diff options
context:
space:
mode:
authorshedaniel <daniel@shedaniel.me>2022-04-14 11:15:25 +0800
committershedaniel <daniel@shedaniel.me>2022-04-14 11:15:25 +0800
commit1fc0a945d287f2e782a511d1a92a494a4633776a (patch)
tree30b8504b0436af6ef030548b8b98c0effb481a69 /runtime/src/main/java/me/shedaniel
parent6236ed33c3ae70cf99219222c2e13e467fa1c8e0 (diff)
parentd16d89a165632d7babbb37168ace0c49f32286e7 (diff)
downloadRoughlyEnoughItems-1fc0a945d287f2e782a511d1a92a494a4633776a.tar.gz
RoughlyEnoughItems-1fc0a945d287f2e782a511d1a92a494a4633776a.tar.bz2
RoughlyEnoughItems-1fc0a945d287f2e782a511d1a92a494a4633776a.zip
Merge remote-tracking branch 'origin/8.x-1.18.2' into 9.x-1.19
Diffstat (limited to 'runtime/src/main/java/me/shedaniel')
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/ClientHelperImpl.java54
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java11
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/ScreenOverlayImpl.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/craftable/CraftableFilter.java44
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java10
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java12
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/EntryListWidget.java30
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ModArgumentType.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TextArgumentType.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TooltipArgumentType.java2
-rw-r--r--runtime/src/main/java/me/shedaniel/rei/impl/client/view/ViewsImpl.java34
12 files changed, 156 insertions, 49 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 f3b18ba39..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
@@ -27,8 +27,9 @@ import com.google.common.base.Suppliers;
import dev.architectury.networking.NetworkManager;
import dev.architectury.platform.Platform;
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.rei.RoughlyEnoughItemsNetwork;
import me.shedaniel.rei.api.client.ClientHelper;
import me.shedaniel.rei.api.client.config.ConfigManager;
@@ -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,12 +57,14 @@ 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.TranslatableComponent;
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;
@@ -221,17 +226,46 @@ public class ClientHelperImpl implements ClientHelper {
}
@ApiStatus.Internal
- public LongSet _getInventoryItemsTypes() {
+ public Long2LongMap _getInventoryItemsTypes() {
+ EntryDefinition<ItemStack> 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<ItemStack> 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 map;
+ }
+
+ @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 Minecraft.getInstance().player.getInventory().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/config/ConfigManagerImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java
index 078f46344..2d82a28c8 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigManagerImpl.java
@@ -293,7 +293,7 @@ public class ConfigManagerImpl implements ConfigManager {
@Override
public boolean isCraftableOnlyEnabled() {
- return craftableOnly;
+ return craftableOnly && getConfig().isCraftableFilterEnabled();
}
@Override
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java
index 76c7e269c..0f273b7e8 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/config/ConfigObjectImpl.java
@@ -357,6 +357,11 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
}
@Override
+ public boolean isUsingCompactTabButtons() {
+ return advanced.accessibility.useCompactTabButtons;
+ }
+
+ @Override
public boolean isLowerConfigButton() {
return appearance.layout.configButtonLocation == ConfigButtonPosition.LOWER;
}
@@ -521,7 +526,8 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
public static class Basics {
@ConfigEntry.Gui.Excluded public List<FavoriteEntry> favorites = new ArrayList<>();
- @Comment("Declares whether cheating mode is on.") @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON) private CheatingMode cheating = CheatingMode.OFF;
+ @Comment("Declares whether cheating mode is on.") @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ private CheatingMode cheating = CheatingMode.OFF;
private boolean favoritesEnabled = true;
@ConfigEntry.Gui.CollapsibleObject(startExpanded = true)
private KeyBindings keyBindings = new KeyBindings();
@@ -564,7 +570,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
private SearchFieldLocation searchFieldLocation = SearchFieldLocation.CENTER;
@Comment("Declares the position of the config button.") @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
private ConfigButtonPosition configButtonLocation = ConfigButtonPosition.LOWER;
- @Comment("Declares whether the craftable filter button is enabled.") private boolean enableCraftableOnlyButton = false;
+ @Comment("Declares whether the craftable filter button is enabled.") private boolean enableCraftableOnlyButton = true;
}
@UsePercentage(min = 0.1, max = 1.0, prefix = "Limit: ") private double horizontalEntriesBoundaries = 1.0;
@@ -631,6 +637,7 @@ public class ConfigObjectImpl implements ConfigObject, ConfigData {
@Comment("Declares how the scrollbar in composite screen should act.") private boolean compositeScrollBarPermanent = false;
private boolean toastDisplayedOnCopyIdentifier = true;
@Comment("Declares whether REI should use compact tabs for categories.") private boolean useCompactTabs = true;
+ @Comment("Declares whether REI should use compact tab buttons for categories.") private boolean useCompactTabButtons = true;
}
public static class Search {
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 a34423cb0..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()) {
+ 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 59c23cca0..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
@@ -23,20 +23,16 @@
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 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 it.unimi.dsi.fastutil.longs.Long2LongMap;
+import it.unimi.dsi.fastutil.longs.Long2LongMaps;
+import it.unimi.dsi.fastutil.longs.Long2LongOpenHashMap;
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();
+ private Long2LongMap containerStacks = new Long2LongOpenHashMap();
public void markDirty() {
dirty = true;
@@ -53,28 +49,32 @@ 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();
}
- }
+ if (dirty) return;
- public boolean matches(EntryStack<?> stack, Iterable<SlotAccessor> inputSlots) {
- if (invStacks.contains(EntryStacks.hashFuzzy(stack))) return true;
- if (stack.getType() != VanillaEntryTypes.ITEM) return false;
- for (SlotAccessor slot : inputSlots) {
- EntryStack<?> itemStack = EntryStacks.of(slot.getItemStack());
- if (!itemStack.isEmpty() && EntryStacks.equalsFuzzy(itemStack, stack)) {
- return true;
- }
+ try {
+ currentStacks = ClientHelperImpl.getInstance()._getContainerItemsTypes();
+ } catch (Throwable throwable) {
+ throwable.printStackTrace();
+ currentStacks = Long2LongMaps.EMPTY_MAP;
}
- return false;
+ if (!currentStacks.equals(this.containerStacks)) {
+ containerStacks = currentStacks;
+ markDirty();
+ }
+ }
+
+ public Long2LongMap getInvStacks() {
+ return invStacks;
}
}
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java
index b1f131197..1613d7f18 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/CompositeDisplayViewingScreen.java
@@ -108,6 +108,8 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen
public void init() {
super.init();
boolean isCompactTabs = ConfigObject.getInstance().isUsingCompactTabs();
+ boolean isCompactTabButtons = ConfigObject.getInstance().isUsingCompactTabButtons();
+ int tabButtonsSize = isCompactTabButtons ? 10 : 16;
int tabSize = isCompactTabs ? 24 : 28;
this.children().clear();
this.widgets.clear();
@@ -120,7 +122,7 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen
DisplaySpec display = categoryMap.get(category).get(selectedRecipeIndex);
int guiWidth = Mth.clamp(category.getDisplayWidth(display.provideInternalDisplay()) + 30, 0, largestWidth) + 100;
int guiHeight = Mth.clamp(category.getDisplayHeight() + 40, 166, largestHeight);
- this.tabsPerPage = Math.max(5, Mth.floor((guiWidth - 20d) / tabSize));
+ this.tabsPerPage = Math.max(5, Mth.floor((guiWidth - tabButtonsSize * 2d) / tabSize));
if (this.tabsPage == -1) {
this.tabsPage = selectedCategoryIndex / tabsPerPage;
}
@@ -207,21 +209,23 @@ public class CompositeDisplayViewingScreen extends AbstractDisplayViewingScreen
tab.setRenderer(tabCategory, tabCategory.getIcon(), tabCategory.getTitle(), j == selectedCategoryIndex);
}
}
- this.widgets.add(Widgets.createButton(new Rectangle(bounds.x + 2, bounds.y - 16, 10, 10), new TranslatableComponent("text.rei.left_arrow"))
+ this.widgets.add(Widgets.createButton(new Rectangle(bounds.x + 2, bounds.y - (isCompactTabButtons ? 16 : 20), tabButtonsSize, tabButtonsSize), new TranslatableComponent("text.rei.left_arrow"))
.onClick(button -> {
tabsPage--;
if (tabsPage < 0)
tabsPage = Mth.ceil(categories.size() / (float) tabsPerPage) - 1;
CompositeDisplayViewingScreen.this.init();
})
+ .tooltipLine(new TranslatableComponent("text.rei.previous_page"))
.enabled(categories.size() > tabsPerPage));
- this.widgets.add(Widgets.createButton(new Rectangle(bounds.x + bounds.width - 12, bounds.y - 16, 10, 10), new TranslatableComponent("text.rei.right_arrow"))
+ this.widgets.add(Widgets.createButton(new Rectangle(bounds.x + bounds.width - (isCompactTabButtons ? tabButtonsSize + 2 : tabButtonsSize + 3), bounds.y - (isCompactTabButtons ? 16 : 20), tabButtonsSize, tabButtonsSize), new TranslatableComponent("text.rei.right_arrow"))
.onClick(button -> {
tabsPage++;
if (tabsPage > Mth.ceil(categories.size() / (float) tabsPerPage) - 1)
tabsPage = 0;
CompositeDisplayViewingScreen.this.init();
})
+ .tooltipLine(new TranslatableComponent("text.rei.next_page"))
.enabled(categories.size() > tabsPerPage));
this.widgets.add(Widgets.createClickableLabel(new Point(bounds.x + 4 + scrollListBounds.width / 2, bounds.y + 6), categories.get(selectedCategoryIndex).getTitle(), label -> {
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java
index 47f914e5d..a5ea0a957 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/screen/DefaultDisplayViewingScreen.java
@@ -162,28 +162,32 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen {
}
boolean isCompactTabs = ConfigObject.getInstance().isUsingCompactTabs();
+ boolean isCompactTabButtons = ConfigObject.getInstance().isUsingCompactTabButtons();
+ int tabButtonsSize = isCompactTabButtons ? 10 : 16;
int tabSize = isCompactTabs ? 24 : 28;
- this.tabsPerPage = Math.max(5, Mth.floor((guiWidth - 20d) / tabSize));
+ this.tabsPerPage = Math.max(5, Mth.floor((guiWidth - tabButtonsSize * 2d) / tabSize));
if (this.categoryPages == -1) {
this.categoryPages = Math.max(0, selectedCategoryIndex / tabsPerPage);
}
this.page = Mth.clamp(page, 0, getCurrentTotalPages() - 1);
- this.widgets.add(Widgets.createButton(new Rectangle(bounds.x, bounds.y - 16, 10, 10), new TranslatableComponent("text.rei.left_arrow"))
+ this.widgets.add(Widgets.createButton(new Rectangle(bounds.x, bounds.y - (isCompactTabButtons ? 16 : 20), tabButtonsSize, tabButtonsSize), new TranslatableComponent("text.rei.left_arrow"))
.onClick(button -> {
categoryPages--;
if (categoryPages < 0)
categoryPages = Mth.ceil(categories.size() / (float) tabsPerPage) - 1;
DefaultDisplayViewingScreen.this.init();
})
+ .tooltipLine(new TranslatableComponent("text.rei.previous_page"))
.enabled(categories.size() > tabsPerPage));
- this.widgets.add(Widgets.createButton(new Rectangle(bounds.x + bounds.width - 10, bounds.y - 16, 10, 10), new TranslatableComponent("text.rei.right_arrow"))
+ this.widgets.add(Widgets.createButton(new Rectangle(bounds.x + bounds.width - tabButtonsSize - (isCompactTabButtons ? 0 : 1), bounds.y - (isCompactTabButtons ? 16 : 20), tabButtonsSize, tabButtonsSize), new TranslatableComponent("text.rei.right_arrow"))
.onClick(button -> {
categoryPages++;
if (categoryPages > Mth.ceil(categories.size() / (float) tabsPerPage) - 1)
categoryPages = 0;
DefaultDisplayViewingScreen.this.init();
})
+ .tooltipLine(new TranslatableComponent("text.rei.next_page"))
.enabled(categories.size() > tabsPerPage));
this.widgets.add(categoryBack = Widgets.createButton(new Rectangle(bounds.getX() + 5, bounds.getY() + 5, 12, 12), new TranslatableComponent("text.rei.left_arrow"))
.onClick(button -> previousCategory()).tooltipLine(new TranslatableComponent("text.rei.previous_category")));
@@ -354,7 +358,7 @@ public class DefaultDisplayViewingScreen extends AbstractDisplayViewingScreen {
}
PanelWidget.render(matrices, bounds, -1, delta);
fill(matrices, bounds.x + 17, bounds.y + 5, bounds.x + bounds.width - 17, bounds.y + 17, darkStripesColor.value().getColor());
- fill(matrices, bounds.x + 17, bounds.y + 19, bounds.x + bounds.width - 17, bounds.y + 30, darkStripesColor.value().getColor());
+ fill(matrices, bounds.x + 17, bounds.y + 19, bounds.x + bounds.width - 17, bounds.y + 31, darkStripesColor.value().getColor());
for (TabWidget tab : tabs) {
if (!tab.isSelected()) {
tab.render(matrices, mouseX, mouseY, delta);
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 28f6e2ca5..cde2ece23 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
@@ -71,14 +71,17 @@ import me.shedaniel.rei.impl.client.gui.ScreenOverlayImpl;
import me.shedaniel.rei.impl.client.search.AsyncSearchManager;
import me.shedaniel.rei.impl.client.view.ViewsImpl;
import net.minecraft.ChatFormatting;
+import net.minecraft.Util;
import net.minecraft.client.Minecraft;
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;
@@ -601,6 +604,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
}
private class EntryListEntry extends EntryListEntryWidget {
+ private long lastCheckTime = -1;
private Display display;
private EntryStack<?> our;
private NumberAnimator<Double> size = null;
@@ -654,6 +658,29 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
return null;
}
+ if (display != null) {
+ if (ViewsImpl.isRecipesFor(getEntries(), display)) {
+ AutoCraftingEvaluator.AutoCraftingResult result = AutoCraftingEvaluator.evaluateAutoCrafting(false, false, display, null);
+ if (result.successful) {
+ return result.successfulHandler;
+ }
+ }
+
+ display = null;
+ lastCheckTime = -1;
+ }
+
+ if (lastCheckTime != -1 && Util.getMillis() - lastCheckTime < 2000) {
+ return null;
+ }
+
+ return _getTransferHandler();
+ }
+
+ @Nullable
+ private TransferHandler _getTransferHandler() {
+ lastCheckTime = Util.getMillis();
+
for (List<Display> displays : DisplayRegistry.getInstance().getAll().values()) {
for (Display display : displays) {
if (ViewsImpl.isRecipesFor(getEntries(), display)) {
@@ -674,7 +701,7 @@ public class EntryListWidget extends WidgetWithBounds implements OverlayListWidg
public Tooltip getCurrentTooltip(Point point) {
Tooltip tooltip = super.getCurrentTooltip(point);
- if (tooltip != null && getTransferHandler() != null) {
+ if (tooltip != null && !ClientHelper.getInstance().isCheating() && getTransferHandler() != null) {
tooltip.add(new TranslatableComponent("text.auto_craft.move_items.tooltip").withStyle(ChatFormatting.YELLOW));
}
@@ -693,6 +720,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/search/argument/type/ModArgumentType.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ModArgumentType.java
index 06e8d35fc..510aab2ac 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ModArgumentType.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/ModArgumentType.java
@@ -75,7 +75,7 @@ public final class ModArgumentType extends ArgumentType<Unit, ModArgumentType.@N
if (pair.modName == null) {
pair.modName = ClientHelper.getInstance().getModFromModId(pair.modId).toLowerCase(Locale.ROOT);
}
- return pair.modName.isEmpty() || pair.modName.contains(searchText);
+ return pair.modName.contains(searchText);
}
@Override
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TextArgumentType.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TextArgumentType.java
index a3ee560f4..1342a2b0c 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TextArgumentType.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TextArgumentType.java
@@ -61,7 +61,7 @@ public final class TextArgumentType extends ArgumentType<Unit, String> {
@Override
public boolean matches(String value, EntryStack<?> stack, String searchText, Unit filterData) {
- return !value.isEmpty() && value.contains(searchText);
+ return value.contains(searchText);
}
@Override
diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TooltipArgumentType.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TooltipArgumentType.java
index 372214b8a..99e967456 100644
--- a/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TooltipArgumentType.java
+++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/search/argument/type/TooltipArgumentType.java
@@ -79,7 +79,7 @@ public final class TooltipArgumentType extends ArgumentType<Unit, String> {
public boolean matches(String tooltip, EntryStack<?> stack, String searchText, Unit filterData) {
//noinspection StringEquality
if (tooltip == INVALID) return false;
- return tooltip.isEmpty() || tooltip.contains(searchText);
+ return tooltip.contains(searchText);
}
@Nullable
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 4b2ce42e1..80b453d50 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,9 @@ 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;
import me.shedaniel.rei.api.common.transfer.info.MenuInfoRegistry;
@@ -55,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;
@@ -373,20 +379,44 @@ public class ViewsImpl implements Views {
Iterable<SlotAccessor> inputSlots = info != null ? info.getInputSlots(context.withDisplay(display)) : Collections.emptySet();
int slotsCraftable = 0;
+ boolean containsNonEmpty = false;
List<EntryIngredient> requiredInput = display.getRequiredEntries();
+ 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++;
continue;
}
for (EntryStack<?> slotPossible : slot) {
- if (CraftableFilter.INSTANCE.matches(slotPossible, inputSlots)) {
+ if (slotPossible.getType() != VanillaEntryTypes.ITEM) continue;
+ ItemStack stack = slotPossible.castValue();
+ long hashFuzzy = EntryStacks.hashFuzzy(slotPossible);
+ long availableAmount = invCount.get(hashFuzzy);
+ if (availableAmount >= stack.getCount()) {
+ invCount.put(hashFuzzy, availableAmount - stack.getCount());
+ containsNonEmpty = true;
slotsCraftable++;
break;
}
}
}
- if (slotsCraftable == display.getRequiredEntries().size()) {
+ if (slotsCraftable == display.getRequiredEntries().size() && containsNonEmpty) {
display.getOutputEntries().stream().flatMap(Collection::stream).collect(Collectors.toCollection(() -> craftables));
}
}