From 1650b1c998ff1f214d5ae4b242b95aebe6aea305 Mon Sep 17 00:00:00 2001 From: shartte Date: Wed, 13 Mar 2024 02:50:19 +0100 Subject: [PATCH] Generalize ghost ingredient drag&drop over REI/EMI (#7759) --- .../modules/itemlists/DropTargets.java | 8 +- .../modules/rei/GhostIngredientHandler.java | 133 ++++-------------- src/main/java/appeng/menu/slot/FakeSlot.java | 9 ++ 3 files changed, 36 insertions(+), 114 deletions(-) diff --git a/src/main/java/appeng/integration/modules/itemlists/DropTargets.java b/src/main/java/appeng/integration/modules/itemlists/DropTargets.java index a85fa5f4245..8070c745eb6 100644 --- a/src/main/java/appeng/integration/modules/itemlists/DropTargets.java +++ b/src/main/java/appeng/integration/modules/itemlists/DropTargets.java @@ -11,9 +11,6 @@ import appeng.api.stacks.AEItemKey; import appeng.api.stacks.GenericStack; import appeng.client.gui.AEBaseScreen; -import appeng.core.network.NetworkHandler; -import appeng.core.network.serverbound.InventoryActionPacket; -import appeng.helpers.InventoryAction; import appeng.menu.slot.FakeSlot; public final class DropTargets { @@ -34,8 +31,6 @@ public static List getTargets(AEBaseScreen aeScreen) { private record FakeSlotDropTarget(Rect2i area, FakeSlot slot) implements DropTarget { @Override public boolean canDrop(GenericStack stack) { - var wrapped = wrapFilterAsItem(stack); - // Use the standard inventory function to test if the dragged stack would in theory be accepted return slot.canSetFilterTo(wrapFilterAsItem(stack)); } @@ -45,8 +40,7 @@ public boolean drop(GenericStack stack) { var itemStack = wrapFilterAsItem(stack); if (slot.canSetFilterTo(itemStack)) { - NetworkHandler.instance().sendToServer(new InventoryActionPacket(InventoryAction.SET_FILTER, - slot.index, itemStack)); + slot.setFilterTo(itemStack); return true; } return false; diff --git a/src/main/java/appeng/integration/modules/rei/GhostIngredientHandler.java b/src/main/java/appeng/integration/modules/rei/GhostIngredientHandler.java index d30c5afe990..a2f3503d542 100644 --- a/src/main/java/appeng/integration/modules/rei/GhostIngredientHandler.java +++ b/src/main/java/appeng/integration/modules/rei/GhostIngredientHandler.java @@ -18,34 +18,18 @@ package appeng.integration.modules.rei; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; import java.util.stream.Stream; -import org.jetbrains.annotations.Nullable; - import net.minecraft.client.gui.screens.Screen; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.ItemStack; -import dev.architectury.fluid.FluidStack; import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.client.gui.drag.DraggableStack; import me.shedaniel.rei.api.client.gui.drag.DraggableStackVisitor; import me.shedaniel.rei.api.client.gui.drag.DraggedAcceptorResult; import me.shedaniel.rei.api.client.gui.drag.DraggingContext; -import me.shedaniel.rei.api.common.entry.EntryStack; -import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; -import appeng.api.stacks.AEFluidKey; -import appeng.api.stacks.GenericStack; import appeng.client.gui.AEBaseScreen; -import appeng.core.network.NetworkHandler; -import appeng.core.network.serverbound.InventoryActionPacket; -import appeng.helpers.InventoryAction; -import appeng.menu.slot.AppEngSlot; -import appeng.menu.slot.FakeSlot; +import appeng.integration.modules.itemlists.DropTargets; /** * JEI allows ingredients to be dragged from a JEI panel onto compatible slots to set filters and the like without @@ -62,108 +46,43 @@ public boolean isHandingScreen(R screen) { @Override public Stream getDraggableAcceptingBounds(DraggingContext context, DraggableStack stack) { - List targets = getTargets(context, stack); - - return targets.stream().map(target -> BoundsProvider.ofRectangle(target.getArea())); - } - - @Override - public DraggedAcceptorResult acceptDraggedStack(DraggingContext context, DraggableStack stack) { - var targets = getTargets(context, stack); - var pos = context.getCurrentPosition(); - - for (var target : targets) { - if (target.getArea().contains(pos)) { - if (target.accept(stack)) { - return DraggedAcceptorResult.ACCEPTED; - } - } - } - - return DraggedAcceptorResult.PASS; - } - - @Nullable - private ItemStack wrapDraggedItem(EntryStack entryStack) { - if (entryStack.getType() == VanillaEntryTypes.ITEM) { - return entryStack.castValue(); - } else { - var genericStack = GenericEntryStackHelper.ingredientToStack(entryStack); - if (genericStack != null) { - return GenericStack.wrapInItemStack(genericStack); - } - } - return null; - } - private List getTargets(DraggingContext context, DraggableStack stack) { - var wrapped = wrapDraggedItem(stack.getStack()); - if (wrapped == null) { - return Collections.emptyList(); + var genericStack = GenericEntryStackHelper.ingredientToStack(stack.getStack()); + if (genericStack == null) { + return Stream.of(); } - List targets = new ArrayList<>(); - addItemStackTargets(context.getScreen(), targets, wrapped); - return targets; - } - - /** - * Returns possible drop-targets for ghost items. - */ - private static void addItemStackTargets(AEBaseScreen gui, List targets, ItemStack draggedStack) { - for (Slot slot : gui.getMenu().slots) { - if (slot.isActive() && slot instanceof FakeSlot fakeSlot) { - // Use the standard inventory function to test if the dragged stack would in theory be accepted - if (!fakeSlot.canSetFilterTo(draggedStack)) { - continue; - } - - targets.add(new ItemSlotTarget(gui, fakeSlot)); - } - } + return DropTargets.getTargets(context.getScreen()) + .stream() + .filter(dropTarget -> dropTarget.canDrop(genericStack)) + .map(target -> { + var area = target.area(); + return BoundsProvider.ofRectangle(new Rectangle( + area.getX(), area.getY(), + area.getWidth(), area.getHeight())); + }); } - private static class ItemSlotTarget implements DropTarget { - private final AppEngSlot slot; - private final Rectangle area; - - public ItemSlotTarget(AEBaseScreen screen, AppEngSlot slot) { - this.slot = slot; - this.area = new Rectangle(screen.getGuiLeft() + slot.x, screen.getGuiTop() + slot.y, 16, 16); + @Override + public DraggedAcceptorResult acceptDraggedStack(DraggingContext context, DraggableStack stack) { + var genericStack = GenericEntryStackHelper.ingredientToStack(stack.getStack()); + if (genericStack == null) { + return DraggedAcceptorResult.PASS; } - @Override - public Rectangle getArea() { - return area; + var pos = context.getCurrentPosition(); + if (pos == null) { + return DraggedAcceptorResult.PASS; } - @Override - public boolean accept(DraggableStack ingredient) { - var entryStack = ingredient.getStack(); - if (entryStack.getType() == VanillaEntryTypes.ITEM) { - ItemStack itemStack = entryStack.castValue(); - NetworkHandler.instance().sendToServer(new InventoryActionPacket(InventoryAction.SET_FILTER, - slot.index, itemStack)); - return true; - } else if (entryStack.getType() == VanillaEntryTypes.FLUID) { - FluidStack fluidStack = entryStack.castValue(); - - // Wrap in a generic stack to set it anyway - var wrappedFluid = GenericStack.wrapInItemStack( - new GenericStack(AEFluidKey.of(fluidStack.getFluid(), fluidStack.getTag()), - fluidStack.getAmount())); - NetworkHandler.instance().sendToServer(new InventoryActionPacket(InventoryAction.SET_FILTER, - slot.index, wrappedFluid)); - return true; + for (var target : DropTargets.getTargets(context.getScreen())) { + if (target.area().contains(pos.x, pos.y) && target.canDrop(genericStack)) { + target.drop(genericStack); + return DraggedAcceptorResult.ACCEPTED; } - return false; } - } - - interface DropTarget { - Rectangle getArea(); - boolean accept(DraggableStack stack); + return DraggedAcceptorResult.PASS; } } diff --git a/src/main/java/appeng/menu/slot/FakeSlot.java b/src/main/java/appeng/menu/slot/FakeSlot.java index f66a19fc2f8..3d0f0575fcd 100644 --- a/src/main/java/appeng/menu/slot/FakeSlot.java +++ b/src/main/java/appeng/menu/slot/FakeSlot.java @@ -23,6 +23,9 @@ import appeng.api.config.Actionable; import appeng.api.inventories.InternalInventory; +import appeng.core.network.NetworkHandler; +import appeng.core.network.serverbound.InventoryActionPacket; +import appeng.helpers.InventoryAction; import appeng.util.ConfigInventory; import appeng.util.ConfigMenuInventory; @@ -64,6 +67,12 @@ public boolean canSetFilterTo(ItemStack stack) { return slot < getInventory().size() && getInventory().isItemValid(slot, stack); } + // Used by the item list mod dropping ghost ingredients on this slot + public void setFilterTo(ItemStack itemStack) { + NetworkHandler.instance().sendToServer(new InventoryActionPacket(InventoryAction.SET_FILTER, + index, itemStack)); + } + public void increase(ItemStack is) { // Special support for increasing the configured stocking amount by simply clicking if (getInventory() instanceof ConfigMenuInventory configInv) {