From cbf7626bec7b9252721bdad58a0cb8668a9ef2dc Mon Sep 17 00:00:00 2001 From: Gugle Date: Thu, 13 Jun 2024 03:52:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0Emi=E6=8B=96=E6=8B=BD?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../depository/FilteredItemDepository.java | 22 ++++++----- .../block/entity/IFilterBlockEntity.java | 4 +- .../screen/inventory/AutoCrafterScreen.java | 15 ++++++-- .../gui/screen/inventory/ChuteScreen.java | 15 ++++++-- .../gui/screen/inventory/IFilterScreen.java | 17 +++++++-- .../screen/inventory/ItemCollectorScreen.java | 16 ++++++-- .../integration/emi/AnvilCraftEmiPlugin.java | 7 ++++ .../emi/GhostIngredientHandler.java | 37 +++++++++++++++++++ .../anvilcraft/inventory/AutoCrafterMenu.java | 5 +++ .../dubhe/anvilcraft/inventory/ChuteMenu.java | 5 +++ .../anvilcraft/inventory/IFilterMenu.java | 7 +++- .../inventory/ItemCollectorMenu.java | 5 +++ .../network/MachineEnableFilterPack.java | 2 +- .../network/SlotDisableChangePack.java | 3 +- .../network/SlotFilterChangePack.java | 3 +- 15 files changed, 133 insertions(+), 30 deletions(-) create mode 100644 common/src/main/java/dev/dubhe/anvilcraft/integration/emi/GhostIngredientHandler.java diff --git a/common/src/main/java/dev/dubhe/anvilcraft/api/depository/FilteredItemDepository.java b/common/src/main/java/dev/dubhe/anvilcraft/api/depository/FilteredItemDepository.java index ebcbf575e..adaf299a9 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/api/depository/FilteredItemDepository.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/api/depository/FilteredItemDepository.java @@ -19,9 +19,9 @@ public class FilteredItemDepository extends ItemDepository { public static final Codec CODEC = RecordCodecBuilder.create(ins -> ins.group( - Codec.BOOL.fieldOf("filterEnabled").forGetter(o -> o.filterEnabled), - ItemStack.CODEC.listOf().fieldOf("filteredItems").forGetter(o -> o.filteredItems), - Codec.BOOL.listOf().fieldOf("disabled").forGetter(o -> o.disabled) + Codec.BOOL.fieldOf("filterEnabled").forGetter(o -> o.filterEnabled), + ItemStack.CODEC.listOf().fieldOf("filteredItems").forGetter(o -> o.filteredItems), + Codec.BOOL.listOf().fieldOf("disabled").forGetter(o -> o.disabled) ).apply(ins, FilteredItemDepository::new)); private boolean filterEnabled = false; @@ -140,10 +140,12 @@ public boolean isFiltered(int slot, ItemStack stack) { * @param slot 槽位 * @param stack 过滤物品堆栈(不检查NBT) */ - public void setFilter(int slot, @NotNull ItemStack stack) { - if (stack.isEmpty()) return; + public boolean setFilter(int slot, @NotNull ItemStack stack) { + if (slot < 0 || slot >= this.filteredItems.size()) return false; + if (stack.isEmpty()) return false; this.setSlotDisabled(slot, false); this.filteredItems.set(slot, new ItemStack(stack.getItem(), 1)); + return true; } /** @@ -203,8 +205,8 @@ public void deserializeNbt(@NotNull CompoundTag tag) { */ public CompoundTag serializeFiltering() { return (CompoundTag) CODEC.encodeStart(NbtOps.INSTANCE, this) - .getOrThrow(false, e -> { - }); + .getOrThrow(false, e -> { + }); } /** @@ -212,9 +214,9 @@ public CompoundTag serializeFiltering() { */ public void deserializeFiltering(@NotNull CompoundTag tag) { FilteredItemDepository depository = CODEC.decode(NbtOps.INSTANCE, tag) - .getOrThrow(false, s -> { - }) - .getFirst(); + .getOrThrow(false, s -> { + }) + .getFirst(); if (this.getSize() != depository.getSize()) throw new IllegalArgumentException("Depository size mismatch"); this.filterEnabled = tag.getBoolean("filterEnabled"); int size = depository.filteredItems.size(); diff --git a/common/src/main/java/dev/dubhe/anvilcraft/block/entity/IFilterBlockEntity.java b/common/src/main/java/dev/dubhe/anvilcraft/block/entity/IFilterBlockEntity.java index 44fd0e922..f9c9e4854 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/block/entity/IFilterBlockEntity.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/block/entity/IFilterBlockEntity.java @@ -76,7 +76,7 @@ default ItemStack getFilter(int slot) { * @param slot 槽位 * @param filter 过滤 */ - default void setFilter(int slot, ItemStack filter) { - this.getFilteredItemDepository().setFilter(slot, filter); + default boolean setFilter(int slot, ItemStack filter) { + return this.getFilteredItemDepository().setFilter(slot, filter); } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/AutoCrafterScreen.java b/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/AutoCrafterScreen.java index 70e6776e8..ee40f00eb 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/AutoCrafterScreen.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/AutoCrafterScreen.java @@ -4,7 +4,6 @@ import dev.dubhe.anvilcraft.api.depository.ItemDepositorySlot; import dev.dubhe.anvilcraft.client.gui.component.EnableFilterButton; import dev.dubhe.anvilcraft.inventory.AutoCrafterMenu; -import dev.dubhe.anvilcraft.inventory.IFilterMenu; import dev.dubhe.anvilcraft.network.SlotDisableChangePack; import lombok.Getter; import net.minecraft.client.gui.GuiGraphics; @@ -17,7 +16,7 @@ import java.util.function.BiFunction; -public class AutoCrafterScreen extends BaseMachineScreen implements IFilterScreen { +public class AutoCrafterScreen extends BaseMachineScreen implements IFilterScreen { private static final ResourceLocation CONTAINER_LOCATION = AnvilCraft.of("textures/gui/container/machine/background/auto_crafter.png"); BiFunction enableFilterButtonSupplier = this @@ -67,7 +66,7 @@ protected void renderSlotTooltip(@NotNull GuiGraphics guiGraphics, int x, int y) } @Override - public IFilterMenu getFilterMenu() { + public AutoCrafterMenu getFilterMenu() { return this.menu; } @@ -92,4 +91,14 @@ protected void slotClicked(@NotNull Slot slot, int slotId, int mouseButton, @Not } super.slotClicked(slot, slotId, mouseButton, type); } + + @Override + public int getOffsetX() { + return (this.width - this.imageWidth) / 2; + } + + @Override + public int getOffsetY() { + return (this.height - this.imageHeight) / 2; + } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/ChuteScreen.java b/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/ChuteScreen.java index 3df6b5937..bb5ecd160 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/ChuteScreen.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/ChuteScreen.java @@ -5,7 +5,6 @@ import dev.dubhe.anvilcraft.api.depository.ItemDepositorySlot; import dev.dubhe.anvilcraft.client.gui.component.EnableFilterButton; import dev.dubhe.anvilcraft.inventory.ChuteMenu; -import dev.dubhe.anvilcraft.inventory.IFilterMenu; import dev.dubhe.anvilcraft.network.SlotDisableChangePack; import lombok.Getter; import net.minecraft.client.gui.GuiGraphics; @@ -19,7 +18,7 @@ import java.util.function.BiFunction; -public class ChuteScreen extends BaseMachineScreen implements IFilterScreen { +public class ChuteScreen extends BaseMachineScreen implements IFilterScreen { private static final ResourceLocation CONTAINER_LOCATION = AnvilCraft.of("textures/gui/container/machine/background/chute.png"); @@ -72,7 +71,7 @@ protected void renderSlotTooltip(@NotNull GuiGraphics guiGraphics, int x, int y) } @Override - public IFilterMenu getFilterMenu() { + public ChuteMenu getFilterMenu() { return menu; } @@ -98,4 +97,14 @@ protected void slotClicked(@NotNull Slot slot, int slotId, int mouseButton, @Not } super.slotClicked(slot, slotId, mouseButton, type); } + + @Override + public int getOffsetX() { + return (this.width - this.imageWidth) / 2; + } + + @Override + public int getOffsetY() { + return (this.height - this.imageHeight) / 2; + } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/IFilterScreen.java b/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/IFilterScreen.java index 7b9874f23..5e4567973 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/IFilterScreen.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/IFilterScreen.java @@ -8,6 +8,7 @@ import dev.dubhe.anvilcraft.network.MachineEnableFilterPack; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.NotNull; @@ -17,10 +18,10 @@ /** * 有过滤的 GUI */ -public interface IFilterScreen { +public interface IFilterScreen { ResourceLocation DISABLED_SLOT = AnvilCraft.of("textures/gui/container/machine/disabled_slot.png"); - IFilterMenu getFilterMenu(); + T getFilterMenu(); /** * 获取是否开启过滤 @@ -65,8 +66,8 @@ default boolean isSlotDisabled(int slot) { * @param slot 槽位 * @param filter 过滤 */ - default void setFilter(int slot, ItemStack filter) { - this.getFilterMenu().setFilter(slot, filter); + default boolean setFilter(int slot, ItemStack filter) { + return this.getFilterMenu().setFilter(slot, filter); } /** @@ -143,4 +144,12 @@ default void renderFilterItem(@NotNull GuiGraphics guiGraphics, @NotNull Slot sl guiGraphics.renderFakeItem(stack, i, j); guiGraphics.fill(i, j, i + 16, j + 16, 0x80ffaaaa); } + + default int getOffsetY() { + return 0; + } + + default int getOffsetX() { + return 0; + } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/ItemCollectorScreen.java b/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/ItemCollectorScreen.java index 9ec98a3a7..7152a6691 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/ItemCollectorScreen.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/client/gui/screen/inventory/ItemCollectorScreen.java @@ -5,7 +5,6 @@ import dev.dubhe.anvilcraft.client.gui.component.EnableFilterButton; import dev.dubhe.anvilcraft.client.gui.component.ItemCollectorButton; import dev.dubhe.anvilcraft.client.gui.component.TextWidget; -import dev.dubhe.anvilcraft.inventory.IFilterMenu; import dev.dubhe.anvilcraft.inventory.ItemCollectorMenu; import dev.dubhe.anvilcraft.network.SlotDisableChangePack; import lombok.Getter; @@ -21,7 +20,8 @@ import java.util.function.BiFunction; -public class ItemCollectorScreen extends AbstractContainerScreen implements IFilterScreen { +public class ItemCollectorScreen extends AbstractContainerScreen + implements IFilterScreen { private static final ResourceLocation CONTAINER_LOCATION = AnvilCraft.of("textures/gui/container/machine/background/item_collector.png"); BiFunction enableFilterButtonSupplier = @@ -123,7 +123,7 @@ protected void renderSlotTooltip(@NotNull GuiGraphics guiGraphics, int x, int y) } @Override - public IFilterMenu getFilterMenu() { + public ItemCollectorMenu getFilterMenu() { return this.menu; } @@ -148,4 +148,14 @@ protected void slotClicked(@NotNull Slot slot, int slotId, int mouseButton, @Not } super.slotClicked(slot, slotId, mouseButton, type); } + + @Override + public int getOffsetX() { + return (this.width - this.imageWidth) / 2; + } + + @Override + public int getOffsetY() { + return (this.height - this.imageHeight) / 2; + } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/AnvilCraftEmiPlugin.java b/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/AnvilCraftEmiPlugin.java index 4f95703ed..21f42e7d6 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/AnvilCraftEmiPlugin.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/AnvilCraftEmiPlugin.java @@ -1,6 +1,9 @@ package dev.dubhe.anvilcraft.integration.emi; import dev.dubhe.anvilcraft.api.recipe.AnvilRecipeManager; +import dev.dubhe.anvilcraft.client.gui.screen.inventory.AutoCrafterScreen; +import dev.dubhe.anvilcraft.client.gui.screen.inventory.ChuteScreen; +import dev.dubhe.anvilcraft.client.gui.screen.inventory.ItemCollectorScreen; import dev.dubhe.anvilcraft.init.ModBlocks; import dev.dubhe.anvilcraft.integration.emi.recipe.AnvilProcessEmiRecipe; import dev.emi.emi.api.EmiEntrypoint; @@ -16,6 +19,10 @@ public class AnvilCraftEmiPlugin implements EmiPlugin { public void register(@NotNull EmiRegistry registry) { AnvilRecipeCategory.ALL.forEach(registry::addCategory); + registry.addDragDropHandler(AutoCrafterScreen.class, new GhostIngredientHandler<>()); + registry.addDragDropHandler(ChuteScreen.class, new GhostIngredientHandler<>()); + registry.addDragDropHandler(ItemCollectorScreen.class, new GhostIngredientHandler<>()); + registry.addWorkstation(AnvilRecipeCategory.STAMPING, EmiStack.of(ModBlocks.STAMPING_PLATFORM.get())); registry.addWorkstation(AnvilRecipeCategory.STAMPING, EmiStack.of(ModBlocks.ROYAL_ANVIL)); registry.addWorkstation(AnvilRecipeCategory.STAMPING, EmiStack.of(Blocks.ANVIL)); diff --git a/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/GhostIngredientHandler.java b/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/GhostIngredientHandler.java new file mode 100644 index 000000000..68359dbe5 --- /dev/null +++ b/common/src/main/java/dev/dubhe/anvilcraft/integration/emi/GhostIngredientHandler.java @@ -0,0 +1,37 @@ +package dev.dubhe.anvilcraft.integration.emi; + +import dev.dubhe.anvilcraft.client.gui.screen.inventory.IFilterScreen; +import dev.dubhe.anvilcraft.network.SlotFilterChangePack; +import dev.emi.emi.api.EmiDragDropHandler; +import dev.emi.emi.api.stack.EmiIngredient; +import dev.emi.emi.api.stack.EmiStack; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.client.renderer.Rect2i; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class GhostIngredientHandler> implements EmiDragDropHandler { + @Override + public boolean dropStack( + @NotNull T screen, @NotNull EmiIngredient ingredient, int x, int y + ) { + if (!screen.isFilterEnabled()) return false; + List stacks = ingredient.getEmiStacks(); + if (stacks.size() != 1) return false; + ItemStack stack = stacks.get(0).getItemStack(); + if (stack.isEmpty()) return false; + for (Slot slot : screen.getFilterMenu().slots) { + Rect2i rect2i = new Rect2i(screen.getOffsetX() + slot.x, screen.getOffsetY() + slot.y, 16, 16); + if (rect2i.contains(x, y)) { + if (screen.setFilter(screen.getFilterMenu().getFilterSlotIndex(slot), stack)) { + new SlotFilterChangePack(screen.getFilterMenu().getFilterSlotIndex(slot), stack).send(); + return true; + } + } + } + return false; + } +} diff --git a/common/src/main/java/dev/dubhe/anvilcraft/inventory/AutoCrafterMenu.java b/common/src/main/java/dev/dubhe/anvilcraft/inventory/AutoCrafterMenu.java index 88f7e6b49..d50d851ce 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/inventory/AutoCrafterMenu.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/inventory/AutoCrafterMenu.java @@ -177,6 +177,11 @@ public IFilterBlockEntity getFilterBlockEntity() { return this.blockEntity; } + @Override + public int getFilterSlotIndex(@NotNull Slot slot) { + return slot.index - 36; + } + @Override public void setItem(int slotId, int stateId, @NotNull ItemStack stack) { super.setItem(slotId, stateId, stack); diff --git a/common/src/main/java/dev/dubhe/anvilcraft/inventory/ChuteMenu.java b/common/src/main/java/dev/dubhe/anvilcraft/inventory/ChuteMenu.java index 6276e23e2..35d9bc5e9 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/inventory/ChuteMenu.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/inventory/ChuteMenu.java @@ -134,4 +134,9 @@ public boolean stillValid(@NotNull Player player) { public IFilterBlockEntity getFilterBlockEntity() { return blockEntity; } + + @Override + public int getFilterSlotIndex(@NotNull Slot slot) { + return slot.index - 36; + } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/inventory/IFilterMenu.java b/common/src/main/java/dev/dubhe/anvilcraft/inventory/IFilterMenu.java index 924e73c67..ad240d7d7 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/inventory/IFilterMenu.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/inventory/IFilterMenu.java @@ -2,6 +2,7 @@ import dev.dubhe.anvilcraft.block.entity.IFilterBlockEntity; import net.minecraft.core.NonNullList; +import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; /** @@ -76,10 +77,12 @@ default NonNullList getFilteredItems() { * @param slot 槽位 * @param filter 过滤 */ - default void setFilter(int slot, ItemStack filter) { - this.getFilterBlockEntity().setFilter(slot, filter); + default boolean setFilter(int slot, ItemStack filter) { + return this.getFilterBlockEntity().setFilter(slot, filter); } + int getFilterSlotIndex(Slot slot); + /** * 刷新 */ diff --git a/common/src/main/java/dev/dubhe/anvilcraft/inventory/ItemCollectorMenu.java b/common/src/main/java/dev/dubhe/anvilcraft/inventory/ItemCollectorMenu.java index 690db5d81..f35a3fd64 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/inventory/ItemCollectorMenu.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/inventory/ItemCollectorMenu.java @@ -175,4 +175,9 @@ public void notify(int index, String name) { } } } + + @Override + public int getFilterSlotIndex(@NotNull Slot slot) { + return slot.index - 36; + } } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/network/MachineEnableFilterPack.java b/common/src/main/java/dev/dubhe/anvilcraft/network/MachineEnableFilterPack.java index 48d9cde59..d087ee8d0 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/network/MachineEnableFilterPack.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/network/MachineEnableFilterPack.java @@ -60,7 +60,7 @@ public void handler(@NotNull MinecraftServer server, ServerPlayer player) { public void handler() { Minecraft client = Minecraft.getInstance(); client.execute(() -> { - if (client.screen instanceof IFilterScreen screen) { + if (client.screen instanceof IFilterScreen screen) { screen.setFilterEnabled(this.isFilterEnabled()); screen.flush(); } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/network/SlotDisableChangePack.java b/common/src/main/java/dev/dubhe/anvilcraft/network/SlotDisableChangePack.java index b97a49da6..55018ee4e 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/network/SlotDisableChangePack.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/network/SlotDisableChangePack.java @@ -45,6 +45,7 @@ public void handler(@NotNull MinecraftServer server, ServerPlayer player) { if (!player.hasContainerOpen()) return; if (!(player.containerMenu instanceof IFilterMenu menu)) return; menu.setSlotDisabled(this.index, this.state); + menu.flush(); this.send(player); }); } @@ -54,7 +55,7 @@ public void handler(@NotNull MinecraftServer server, ServerPlayer player) { public void handler() { Minecraft client = Minecraft.getInstance(); client.execute(() -> { - if (!(client.screen instanceof IFilterScreen screen)) return; + if (!(client.screen instanceof IFilterScreen screen)) return; screen.setSlotDisabled(this.index, this.state); }); } diff --git a/common/src/main/java/dev/dubhe/anvilcraft/network/SlotFilterChangePack.java b/common/src/main/java/dev/dubhe/anvilcraft/network/SlotFilterChangePack.java index 063369173..3e28900cf 100644 --- a/common/src/main/java/dev/dubhe/anvilcraft/network/SlotFilterChangePack.java +++ b/common/src/main/java/dev/dubhe/anvilcraft/network/SlotFilterChangePack.java @@ -51,6 +51,7 @@ public void handler(@NotNull MinecraftServer server, ServerPlayer player) { if (!player.hasContainerOpen()) return; if (!(player.containerMenu instanceof IFilterMenu menu)) return; menu.setFilter(this.index, this.filter); + menu.flush(); this.send(player); }); } @@ -60,7 +61,7 @@ public void handler(@NotNull MinecraftServer server, ServerPlayer player) { public void handler() { Minecraft client = Minecraft.getInstance(); client.execute(() -> { - if (!(client.screen instanceof IFilterScreen screen)) return; + if (!(client.screen instanceof IFilterScreen screen)) return; screen.setFilter(this.index, this.filter); }); }