From 7ef31b9053d15112198758a5b5324e83f9f9d625 Mon Sep 17 00:00:00 2001 From: Zelophed Date: Sat, 17 Oct 2020 17:32:37 +0200 Subject: [PATCH] Spooky Filters - allow our filters to be populated from JEIs ghost-ingredients --- .../simibubi/create/compat/jei/CreateJEI.java | 6 ++ .../jei/FilterGhostIngredientHandler.java | 91 +++++++++++++++++++ .../item/filter/FilterScreenPacket.java | 19 ++-- 3 files changed, 108 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/simibubi/create/compat/jei/FilterGhostIngredientHandler.java diff --git a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java index 5514ed8d1..5f8bf6fb0 100644 --- a/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java +++ b/src/main/java/com/simibubi/create/compat/jei/CreateJEI.java @@ -9,6 +9,7 @@ import com.simibubi.create.compat.jei.category.BlockCuttingCategory.CondensedBlo import com.simibubi.create.content.contraptions.components.press.MechanicalPressTileEntity; import com.simibubi.create.content.contraptions.processing.BasinRecipe; import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateScreen; +import com.simibubi.create.content.logistics.item.filter.AbstractFilterScreen; import com.simibubi.create.content.schematics.block.SchematicannonScreen; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.CRecipes; @@ -26,6 +27,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; +import javax.annotation.Nonnull; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -38,6 +40,7 @@ public class CreateJEI implements IModPlugin { public static final IIngredientType FLUIDS = new IIngredientType() { @Override + @Nonnull public Class getIngredientClass() { return FluidIngredient.class; } @@ -61,6 +64,7 @@ public class CreateJEI implements IModPlugin { private final MechanicalCraftingCategory mechanicalCraftingExclusiveCategory; @Override + @Nonnull public ResourceLocation getPluginUid() { return ID; } @@ -189,6 +193,8 @@ public class CreateJEI implements IModPlugin { public void registerGuiHandlers(IGuiHandlerRegistration registration) { registration.addGuiContainerHandler(AdjustableCrateScreen.class, new SlotMover<>()); registration.addGuiContainerHandler(SchematicannonScreen.class, new SlotMover<>()); + + registration.addGhostIngredientHandler(AbstractFilterScreen.class, new FilterGhostIngredientHandler()); } private static List> findRecipes(AllRecipeTypes recipe) { diff --git a/src/main/java/com/simibubi/create/compat/jei/FilterGhostIngredientHandler.java b/src/main/java/com/simibubi/create/compat/jei/FilterGhostIngredientHandler.java new file mode 100644 index 000000000..7ec3d405e --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/jei/FilterGhostIngredientHandler.java @@ -0,0 +1,91 @@ +package com.simibubi.create.compat.jei; + +import com.simibubi.create.content.logistics.item.filter.AbstractFilterContainer; +import com.simibubi.create.content.logistics.item.filter.AbstractFilterScreen; +import com.simibubi.create.content.logistics.item.filter.AttributeFilterScreen; +import com.simibubi.create.content.logistics.item.filter.FilterScreenPacket; +import com.simibubi.create.foundation.networking.AllPackets; +import mcp.MethodsReturnNonnullByDefault; +import mezz.jei.api.gui.handlers.IGhostIngredientHandler; +import net.minecraft.client.renderer.Rectangle2d; +import net.minecraft.inventory.container.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import org.apache.logging.log4j.LogManager; + +import javax.annotation.ParametersAreNonnullByDefault; +import java.util.ArrayList; +import java.util.List; + +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +public class FilterGhostIngredientHandler implements IGhostIngredientHandler> { + + @Override + public List> getTargets(AbstractFilterScreen gui, I ingredient, boolean doStart) { + List> targets = new ArrayList<>(); + boolean isAttributeFilter = gui instanceof AttributeFilterScreen; + + if (ingredient instanceof ItemStack) { + for (int i = 36; i < gui.getContainer().inventorySlots.size(); i++) { + targets.add(new FilterGhostTarget<>(gui, i - 36, isAttributeFilter)); + + //Only accept items in 1st slot. 2nd is used for functionality, don't wanna override that one + if (isAttributeFilter) break; + } + } + + return targets; + } + + @Override + public void onComplete() {} + + @Override + public boolean shouldHighlightTargets() { + //TODO change to false and highlight the slots ourself in some better way + return true; + } + + private static class FilterGhostTarget implements Target { + + private final Rectangle2d area; + private final AbstractFilterScreen gui; + private final int slotIndex; + private final boolean isAttributeFilter; + + + public FilterGhostTarget(AbstractFilterScreen gui, int slotIndex, boolean isAttributeFilter) { + this.gui = gui; + this.slotIndex = slotIndex; + this.isAttributeFilter = isAttributeFilter; + Slot slot = gui.getContainer().inventorySlots.get(slotIndex + 36); + this.area = new Rectangle2d( + gui.getGuiLeft() + slot.xPos, + gui.getGuiTop() + slot.yPos, + 16, + 16); + } + + @Override + public Rectangle2d getArea() { + return area; + } + + @Override + public void accept(I ingredient) { + ItemStack stack = ((ItemStack) ingredient).copy(); + LogManager.getLogger().info(stack); + stack.setCount(1); + gui.getContainer().filterInventory.setStackInSlot(slotIndex, stack); + + if (isAttributeFilter) return; + + //sync new filter contents with server + CompoundNBT data = new CompoundNBT(); + data.putInt("Slot", slotIndex); + data.put("Item", stack.serializeNBT()); + AllPackets.channel.sendToServer(new FilterScreenPacket(FilterScreenPacket.Option.UPDATE_FILTER_ITEM, data)); + } + } +} diff --git a/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterScreenPacket.java b/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterScreenPacket.java index 984f455ec..a8b369975 100644 --- a/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterScreenPacket.java +++ b/src/main/java/com/simibubi/create/content/logistics/item/filter/FilterScreenPacket.java @@ -1,23 +1,22 @@ package com.simibubi.create.content.logistics.item.filter; -import java.util.function.Supplier; - import com.simibubi.create.content.logistics.item.filter.AttributeFilterContainer.WhitelistMode; import com.simibubi.create.foundation.networking.SimplePacketBase; - import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.nbt.CompoundNBT; import net.minecraft.network.PacketBuffer; import net.minecraftforge.fml.network.NetworkEvent.Context; +import java.util.function.Supplier; + public class FilterScreenPacket extends SimplePacketBase { - enum Option { - CLEAR, WHITELIST, WHITELIST2, BLACKLIST, RESPECT_DATA, IGNORE_DATA, ADD_TAG, ADD_INVERTED_TAG; + public enum Option { + CLEAR, WHITELIST, WHITELIST2, BLACKLIST, RESPECT_DATA, IGNORE_DATA, UPDATE_FILTER_ITEM, ADD_TAG, ADD_INVERTED_TAG; } - private Option option; - private CompoundNBT data; + private final Option option; + private final CompoundNBT data; public FilterScreenPacket(Option option) { this(option, new CompoundNBT()); @@ -45,7 +44,7 @@ public class FilterScreenPacket extends SimplePacketBase { ServerPlayerEntity player = context.get().getSender(); if (player == null) return; - + if (player.openContainer instanceof AbstractFilterContainer) { AbstractFilterContainer c = (AbstractFilterContainer) player.openContainer; if (option == Option.CLEAR) { @@ -64,6 +63,10 @@ public class FilterScreenPacket extends SimplePacketBase { c.respectNBT = true; if (option == Option.IGNORE_DATA) c.respectNBT = false; + if (option == Option.UPDATE_FILTER_ITEM) + c.filterInventory.setStackInSlot( + data.getInt("Slot"), + net.minecraft.item.ItemStack.read(data.getCompound("Item"))); } if (player.openContainer instanceof AttributeFilterContainer) {