diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/clean/InputCleanHandler.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/clean/InputCleanHandler.java index 82071f4c6..afc71033e 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/clean/InputCleanHandler.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/clean/InputCleanHandler.java @@ -44,6 +44,10 @@ static void error(String translationKey) { static void returnSlotsToPlayerInventory(MenuInfoContext context, DumpHandler dumpHandler, SlotAccessor slotAccessor) { ItemStack stackToReturn = slotAccessor.getItemStack(); if (!stackToReturn.isEmpty()) { + if (!slotAccessor.allowModification(context.getPlayerEntity())) { + error("rei.rei.no.slot.in.inv"); + } + for (; !(stackToReturn = slotAccessor.getItemStack()).isEmpty(); slotAccessor.takeStack(1)) { ItemStack stackToInsert = stackToReturn.copy(); stackToInsert.setCount(1); diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/simple/DumpHandler.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/simple/DumpHandler.java index 9f1fe8593..776f34498 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/simple/DumpHandler.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/simple/DumpHandler.java @@ -36,7 +36,7 @@ public interface DumpHandler static SlotAccessor getOccupiedSlotWithRoomForStack(ItemStack stack, Iterable inventoryStacks) { for (SlotAccessor inventoryStack : inventoryStacks) { - if (canStackAddMore(inventoryStack.getItemStack(), stack)) { + if (canStackAddMore(inventoryStack.getItemStack(), stack) && inventoryStack.canPlace(stack)) { return inventoryStack; } } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/stack/ContainerSlotAccessor.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/stack/ContainerSlotAccessor.java index b2ff12a3e..467c4b06e 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/stack/ContainerSlotAccessor.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/stack/ContainerSlotAccessor.java @@ -24,6 +24,7 @@ package me.shedaniel.rei.api.common.transfer.info.stack; import net.minecraft.world.Container; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; /** @@ -53,4 +54,14 @@ public void setItemStack(ItemStack stack) { public ItemStack takeStack(int amount) { return this.container.removeItem(index, amount); } + + @Override + public boolean allowModification(Player player) { + return canPlace(getItemStack()); + } + + @Override + public boolean canPlace(ItemStack stack) { + return this.container.canPlaceItem(index, stack); + } } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/stack/SlotAccessor.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/stack/SlotAccessor.java index 79513fe40..f2dd1c4e5 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/stack/SlotAccessor.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/stack/SlotAccessor.java @@ -41,6 +41,14 @@ public interface SlotAccessor { ItemStack takeStack(int amount); + default boolean allowModification(Player player) { + return true; + } + + default boolean canPlace(ItemStack stack) { + return true; + } + static SlotAccessor fromSlot(Slot slot) { return new VanillaSlotAccessor(slot); } diff --git a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/stack/VanillaSlotAccessor.java b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/stack/VanillaSlotAccessor.java index 6e3c97134..579716dea 100644 --- a/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/stack/VanillaSlotAccessor.java +++ b/api/src/main/java/me/shedaniel/rei/api/common/transfer/info/stack/VanillaSlotAccessor.java @@ -23,6 +23,7 @@ package me.shedaniel.rei.api.common.transfer.info.stack; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; @@ -54,4 +55,14 @@ public ItemStack takeStack(int amount) { public Slot getSlot() { return slot; } + + @Override + public boolean allowModification(Player player) { + return slot.allowModification(player); + } + + @Override + public boolean canPlace(ItemStack stack) { + return slot.mayPlace(stack); + } } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigGroupWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigGroupWidget.java index 161a38f69..2c9548c85 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigGroupWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/config/components/ConfigGroupWidget.java @@ -25,6 +25,7 @@ import me.shedaniel.math.Point; import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.REIRuntime; import me.shedaniel.rei.api.client.gui.widgets.Widget; import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds; import me.shedaniel.rei.api.client.gui.widgets.Widgets; @@ -37,6 +38,7 @@ import me.shedaniel.rei.impl.client.gui.config.options.preview.InterfacePreviewer; import me.shedaniel.rei.impl.client.gui.config.options.preview.TooltipPreviewer; import me.shedaniel.rei.impl.client.gui.text.TextTransformations; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiComponent; import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.Nullable; @@ -66,6 +68,10 @@ public static WidgetWithBounds create(ConfigAccess access, OptionGroup entry, in .withPadding(0, 0, 0, 6); WidgetWithBounds contents; + if (applyPreview) { + applyPreview = REIRuntime.getInstance().getPreviousContainerScreen() != null && Minecraft.getInstance().getConnection() != null && Minecraft.getInstance().getConnection().getRecipeManager() != null; + } + if (applyPreview && SPECIAL_GROUPS.containsKey(entry.getId())) { Pair pair = SPECIAL_GROUPS.get(entry.getId()); PreviewLocation location = pair.getLeft(); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java index 4f5ffe12d..e4b1faec3 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/client/gui/widget/entrylist/PaginatedEntryListWidget.java @@ -116,6 +116,10 @@ protected void renderEntries(boolean fastEntryRendering, PoseStack matrices, int } public int getTotalPages() { + return getTotalPages(entries); + } + + public int getTotalPages(List entries) { return Mth.ceil(stacks.size() / (float) entries.size()); } @@ -134,7 +138,7 @@ protected void updateEntries(int entrySize, boolean zoomed) { } } } - page = Math.max(Math.min(page, getTotalPages() - 1), 0); + page = Mth.clamp(page, 0, getTotalPages(entries) - 1); int skip = Math.max(0, page * entries.size()); List | List>*/ Object> subList = stacks.subList(skip, Math.min(stacks.size(), skip + entries.size())); Int2ObjectMap indexedCollapsedStack = getCollapsedStackIndexed(); diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/transfer/InputSlotCrafter.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/transfer/InputSlotCrafter.java index 7cbf4ebcd..52c8d8503 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/common/transfer/InputSlotCrafter.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/transfer/InputSlotCrafter.java @@ -117,6 +117,10 @@ protected void fillInputSlot(SlotAccessor slot, ItemStack toBeTakenStack) { } takenStack.setCount(1); + if (!slot.canPlace(takenStack)) { + return; + } + if (slot.getItemStack().isEmpty()) { slot.setItemStack(takenStack); } else { @@ -148,13 +152,22 @@ protected void fillInputSlots(RecipeFinder recipeFinder, NonNullList @Nullable public SlotAccessor takeInventoryStack(ItemStack itemStack) { + boolean rejectedModification = false; for (SlotAccessor inventoryStack : inventoryStacks) { ItemStack itemStack1 = inventoryStack.getItemStack(); if (!itemStack1.isEmpty() && areItemsEqual(itemStack, itemStack1) && !itemStack1.isDamaged() && !itemStack1.isEnchanted() && !itemStack1.hasCustomHoverName()) { - return inventoryStack; + if (!inventoryStack.allowModification(player)) { + rejectedModification = true; + } else { + return inventoryStack; + } } } + if (rejectedModification) { + throw new IllegalStateException("Unable to take item from inventory due to slot not allowing modification! Item requested: " + itemStack); + } + return null; } diff --git a/runtime/src/main/java/me/shedaniel/rei/impl/common/transfer/NewInputSlotCrafter.java b/runtime/src/main/java/me/shedaniel/rei/impl/common/transfer/NewInputSlotCrafter.java index a2d35f24d..36bd20fd2 100644 --- a/runtime/src/main/java/me/shedaniel/rei/impl/common/transfer/NewInputSlotCrafter.java +++ b/runtime/src/main/java/me/shedaniel/rei/impl/common/transfer/NewInputSlotCrafter.java @@ -77,6 +77,9 @@ protected void markDirty() { protected void cleanInputs() { for (SlotAccessor slot : getInputSlots()) { ItemStack stackToReturn = slot.getItemStack(); + if (!slot.allowModification(player)) { + throw new IllegalStateException("Slot " + slot + " is not modifiable!"); + } if (!stackToReturn.isEmpty()) { for (; !(stackToReturn = slot.getItemStack()).isEmpty(); slot.takeStack(1)) { ItemStack stackToInsert = stackToReturn.copy(); diff --git a/settings.gradle b/settings.gradle index 937a949bf..1cbf494f4 100755 --- a/settings.gradle +++ b/settings.gradle @@ -2,8 +2,8 @@ pluginManagement { repositories { maven { url "https://maven.shedaniel.me/" } maven { url "https://maven.fabricmc.net/" } - maven { url "https://files.minecraftforge.net/maven/" } gradlePluginPortal() + maven { url "https://files.minecraftforge.net/maven/" } } }