From 7c1d81fc316843b802578fe0383725333ebf7a40 Mon Sep 17 00:00:00 2001 From: Relentless Date: Thu, 6 Apr 2023 19:22:42 +0200 Subject: [PATCH] reintroduce JEI support --- .github/workflows/release.yml | 4 +- Common/build.gradle.kts | 4 +- .../unified/compat/AlmostJEI.java | 61 ++++++++++++++ .../unified/mixin/AlmostMixinPlugin.java | 55 ++++++++++++ .../unified/mixin/JeiRecipesGuiMixin.java | 84 +++++++++++++++++++ .../almostunified-common.mixins.json | 4 +- Fabric/build.gradle.kts | 2 +- Fabric/src/main/resources/fabric.mod.json | 3 + Forge/build.gradle.kts | 4 +- gradle.properties | 4 +- 10 files changed, 216 insertions(+), 9 deletions(-) create mode 100644 Common/src/main/java/com/almostreliable/unified/compat/AlmostJEI.java create mode 100644 Common/src/main/java/com/almostreliable/unified/mixin/AlmostMixinPlugin.java create mode 100644 Common/src/main/java/com/almostreliable/unified/mixin/JeiRecipesGuiMixin.java diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c0f1fda..2a8647f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -106,7 +106,7 @@ jobs: dependencies: | roughly-enough-items | suggests | * - # jei | suggests | * + jei | suggests | * retry-attempts: 2 retry-delay: 10000 @@ -132,7 +132,7 @@ jobs: dependencies: | roughly-enough-items | suggests | * - # jei | suggests | * + jei | suggests | * retry-attempts: 2 retry-delay: 10000 diff --git a/Common/build.gradle.kts b/Common/build.gradle.kts index eb7bd37..f6cf0b7 100644 --- a/Common/build.gradle.kts +++ b/Common/build.gradle.kts @@ -29,8 +29,8 @@ dependencies { modCompileOnly("me.shedaniel:RoughlyEnoughItems-api:$reiVersion") // required for common rei plugin compileOnly("me.shedaniel:REIPluginCompatibilities-forge-annotations:9.+") // required to disable rei compat layer on jei plugin testCompileOnly("me.shedaniel:REIPluginCompatibilities-forge-annotations:9.+") // don't question this, it's required for compiling -// modCompileOnlyApi("mezz.jei:jei-$minecraftVersion-common:$jeiVersion") // required for common jei plugin -// modCompileOnly("mezz.jei:jei-$minecraftVersion-gui:$jeiVersion") // required for jei mixin + modCompileOnlyApi("mezz.jei:jei-$minecraftVersion-common:$jeiVersion") // required for common jei plugin + modCompileOnly("mezz.jei:jei-$minecraftVersion-gui:$jeiVersion") // required for jei mixin // The Fabric loader is required here to use the @Environment annotations and to get the mixin dependencies. // Do NOT use other classes from the Fabric loader! diff --git a/Common/src/main/java/com/almostreliable/unified/compat/AlmostJEI.java b/Common/src/main/java/com/almostreliable/unified/compat/AlmostJEI.java new file mode 100644 index 0000000..f241ed1 --- /dev/null +++ b/Common/src/main/java/com/almostreliable/unified/compat/AlmostJEI.java @@ -0,0 +1,61 @@ +package com.almostreliable.unified.compat; + +import com.almostreliable.unified.AlmostUnified; +import com.almostreliable.unified.AlmostUnifiedFallbackRuntime; +import com.almostreliable.unified.api.ModConstants; +import com.almostreliable.unified.config.UnifyConfig; +import com.almostreliable.unified.recipe.CRTLookup; +import com.almostreliable.unified.utils.Utils; +import com.mojang.blaze3d.vertex.PoseStack; +import me.shedaniel.rei.plugincompatibilities.api.REIPluginCompatIgnore; +import mezz.jei.api.IModPlugin; +import mezz.jei.api.JeiPlugin; +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.recipe.category.IRecipeCategory; +import mezz.jei.api.runtime.IJeiRuntime; +import net.minecraft.client.renderer.Rect2i; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; + +import java.util.Collection; + +@REIPluginCompatIgnore +@JeiPlugin +public class AlmostJEI implements IModPlugin { + + @Override + public ResourceLocation getPluginUid() { + return Utils.getRL(ModConstants.JEI); + } + + @Override + public void onRuntimeAvailable(IJeiRuntime jei) { + AlmostUnifiedFallbackRuntime.getInstance().reload(); + + Boolean jeiDisabled = AlmostUnified.getRuntime() + .getUnifyConfig() + .map(UnifyConfig::reiOrJeiDisabled) + .orElse(false); + if (jeiDisabled) return; + + Collection items = HideHelper.createHidingList(AlmostUnified.getRuntime()); + if (!items.isEmpty()) { + jei.getIngredientManager().removeIngredientsAtRuntime(VanillaTypes.ITEM_STACK, items); + } + } + + public static void handleIndicator(PoseStack stack, int mX, int mY, int posX, int posY, IRecipeCategory recipeCategory, R recipe) { + var recipeId = recipeCategory.getRegistryName(recipe); + if (recipeId == null) return; + + var link = CRTLookup.getLink(recipeId); + if (link == null) return; + + var area = new Rect2i(posX, posY, RecipeIndicator.RENDER_SIZE, RecipeIndicator.RENDER_SIZE); + RecipeIndicator.renderIndicator(stack, area); + if (mX >= area.getX() && mX <= area.getX() + area.getWidth() && + mY >= area.getY() && mY <= area.getY() + area.getHeight()) { + Utils.renderTooltip(stack, mX, mY, RecipeIndicator.constructTooltip(link)); + } + } +} diff --git a/Common/src/main/java/com/almostreliable/unified/mixin/AlmostMixinPlugin.java b/Common/src/main/java/com/almostreliable/unified/mixin/AlmostMixinPlugin.java new file mode 100644 index 0000000..2f4676c --- /dev/null +++ b/Common/src/main/java/com/almostreliable/unified/mixin/AlmostMixinPlugin.java @@ -0,0 +1,55 @@ +package com.almostreliable.unified.mixin; + +import com.almostreliable.unified.AlmostUnifiedPlatform; +import com.almostreliable.unified.api.ModConstants; +import com.google.common.collect.ImmutableMap; +import org.objectweb.asm.tree.ClassNode; +import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; +import org.spongepowered.asm.mixin.extensibility.IMixinInfo; + +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.BooleanSupplier; + +@SuppressWarnings("unused") +public class AlmostMixinPlugin implements IMixinConfigPlugin { + + private static final BooleanSupplier TRUE = () -> true; + private static final Map CONDITIONS = ImmutableMap.of( + "com.almostreliable.unified.mixin.JeiRecipeLayoutMixin", modLoaded(ModConstants.JEI) + ); + + private static BooleanSupplier modLoaded(String id) { + return () -> AlmostUnifiedPlatform.INSTANCE.isModLoaded(id); + } + + @Override + public void onLoad(String mixinPackage) {} + + @SuppressWarnings({ "ReturnOfNull", "DataFlowIssue" }) + @Override + public String getRefMapperConfig() { + return null; + } + + @Override + public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { + return CONDITIONS.getOrDefault(mixinClassName, TRUE).getAsBoolean(); + } + + @Override + public void acceptTargets(Set myTargets, Set otherTargets) {} + + @SuppressWarnings({ "ReturnOfNull", "DataFlowIssue" }) + @Override + public List getMixins() { + return null; + } + + @Override + public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} + + @Override + public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {} +} diff --git a/Common/src/main/java/com/almostreliable/unified/mixin/JeiRecipesGuiMixin.java b/Common/src/main/java/com/almostreliable/unified/mixin/JeiRecipesGuiMixin.java new file mode 100644 index 0000000..502134b --- /dev/null +++ b/Common/src/main/java/com/almostreliable/unified/mixin/JeiRecipesGuiMixin.java @@ -0,0 +1,84 @@ +package com.almostreliable.unified.mixin; + +import com.almostreliable.unified.compat.AlmostJEI; +import com.almostreliable.unified.compat.RecipeIndicator; +import com.almostreliable.unified.utils.Utils; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import mezz.jei.api.gui.IRecipeLayoutDrawable; +import mezz.jei.common.util.ImmutableRect2i; +import mezz.jei.gui.recipes.RecipeTransferButton; +import mezz.jei.gui.recipes.RecipesGui; +import net.minecraft.client.renderer.Rect2i; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import java.util.Iterator; +import java.util.List; +import java.util.Optional; + +@Mixin(RecipesGui.class) +public abstract class JeiRecipesGuiMixin { + + private static final int BORDER_PADDING = 2; + + @Shadow(remap = false) @Final + private List recipeTransferButtons; + + @Inject( + method = "drawLayouts", + at = @At(value = "INVOKE", target = "Lmezz/jei/api/gui/IRecipeLayoutDrawable;drawRecipe(Lcom/mojang/blaze3d/vertex/PoseStack;II)V", shift = At.Shift.AFTER), + locals = LocalCapture.CAPTURE_FAILHARD, + remap = false + ) + private void unified$drawIndicator( + PoseStack poseStack, int mX, int mY, CallbackInfoReturnable>> cir, + IRecipeLayoutDrawable hoveredLayout, Iterator i, IRecipeLayoutDrawable recipeLayout + ) { + RenderSystem.disableBlend(); + RenderSystem.disableDepthTest(); + + var buttonArea = recipeLayout.getRecipeTransferButtonArea(); + + RecipeTransferButton transferButton = null; + for (var button : recipeTransferButtons) { + if (!button.visible || !buttonsMatch(buttonArea, button.getArea())) continue; + transferButton = button; + } + + int posX; + int posY; + if (transferButton == null) { + var layoutArea = recipeLayout.getRect(); + posX = layoutArea.getX() + layoutArea.getWidth() - RecipeIndicator.RENDER_SIZE / 2; + posY = layoutArea.getY() + layoutArea.getHeight() - RecipeIndicator.RENDER_SIZE / 2 + BORDER_PADDING; + } else { + posX = buttonArea.getX() + BORDER_PADDING; + posY = buttonArea.getY() - RecipeIndicator.RENDER_SIZE - 2 + BORDER_PADDING; + } + + AlmostJEI.handleIndicator( + poseStack, + mX, + mY, + posX, + posY, + Utils.cast(recipeLayout.getRecipeCategory()), + recipeLayout.getRecipe() + ); + RenderSystem.enableBlend(); + RenderSystem.enableDepthTest(); + } + + private static boolean buttonsMatch(Rect2i a, ImmutableRect2i b) { + return a.getX() == b.getX() && + a.getY() == b.getY() && + a.getWidth() == b.getWidth() && + a.getHeight() == b.getHeight(); + } +} diff --git a/Common/src/main/resources/almostunified-common.mixins.json b/Common/src/main/resources/almostunified-common.mixins.json index cd40e54..8c28cde 100644 --- a/Common/src/main/resources/almostunified-common.mixins.json +++ b/Common/src/main/resources/almostunified-common.mixins.json @@ -3,12 +3,14 @@ "minVersion": "0.8.5", "package": "com.almostreliable.unified.mixin", "compatibilityLevel": "JAVA_17", + "plugin": "com.almostreliable.unified.mixin.AlmostMixinPlugin", "mixins": [ "RecipeManagerMixin", "ReloadableServerResourcesMixin" ], "client": [ - "ClientPacketListenerMixin" + "ClientPacketListenerMixin", + "JeiRecipesGuiMixin" ], "injectors": { "defaultRequire": 1 diff --git a/Fabric/build.gradle.kts b/Fabric/build.gradle.kts index 55e291b..59bb571 100644 --- a/Fabric/build.gradle.kts +++ b/Fabric/build.gradle.kts @@ -33,7 +33,7 @@ dependencies { modCompileOnly("me.shedaniel:RoughlyEnoughItems-api-fabric:$reiVersion") // required for common rei plugin compileOnly("me.shedaniel:REIPluginCompatibilities-forge-annotations:9.+") // required to disable rei compat layer on jei plugin testCompileOnly("me.shedaniel:REIPluginCompatibilities-forge-annotations:9.+") // don't question this, it's required for compiling -// modCompileOnly("mezz.jei:jei-$minecraftVersion-fabric:$jeiVersion") // required for common jei plugin and mixin + modCompileOnly("mezz.jei:jei-$minecraftVersion-fabric:$jeiVersion") // required for common jei plugin and mixin when (fabricRecipeViewer) { // runtime only "rei" -> modLocalRuntime("me.shedaniel:RoughlyEnoughItems-fabric:$reiVersion") "jei" -> modLocalRuntime("mezz.jei:jei-$minecraftVersion-fabric:$jeiVersion") diff --git a/Fabric/src/main/resources/fabric.mod.json b/Fabric/src/main/resources/fabric.mod.json index 7811c13..377a068 100644 --- a/Fabric/src/main/resources/fabric.mod.json +++ b/Fabric/src/main/resources/fabric.mod.json @@ -18,6 +18,9 @@ "main": [ "com.almostreliable.unified.AlmostUnifiedFabric" ], + "jei_mod_plugin": [ + "com.almostreliable.unified.compat.AlmostJEI" + ], "rei_client": [ "com.almostreliable.unified.compat.AlmostREI" ] diff --git a/Forge/build.gradle.kts b/Forge/build.gradle.kts index ce5c395..a31d141 100644 --- a/Forge/build.gradle.kts +++ b/Forge/build.gradle.kts @@ -44,7 +44,9 @@ dependencies { modCompileOnly("me.shedaniel:RoughlyEnoughItems-forge:$reiVersion") // required for common rei plugin | api does not work here compileOnly("me.shedaniel:REIPluginCompatibilities-forge-annotations:9.+") // required to disable rei compat layer on jei plugin testCompileOnly("me.shedaniel:REIPluginCompatibilities-forge-annotations:9.+") // don't question this, it's required for compiling -// modCompileOnly("mezz.jei:jei-$minecraftVersion-forge:$jeiVersion") { isTransitive = false } // required for common jei plugin and mixin, transitivity is off because it breaks the forge runtime + modCompileOnly("mezz.jei:jei-$minecraftVersion-forge:$jeiVersion") { + isTransitive = false + } // required for common jei plugin and mixin, transitivity is off because it breaks the forge runtime when (forgeRecipeViewer) { // runtime only "rei" -> modLocalRuntime("me.shedaniel:RoughlyEnoughItems-forge:$reiVersion") "jei" -> modLocalRuntime("mezz.jei:jei-$minecraftVersion-forge:$jeiVersion") { isTransitive = false } diff --git a/gradle.properties b/gradle.properties index 6828501..d5c97c9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,7 +20,7 @@ modDescription = Unify all resources. # Mod Dependencies reiVersion = 11.0.597 -jeiVersion = 12.1.1.10 +jeiVersion = 13.1.0.2 # Fabric Settings fabricLoaderVersion = 0.14.18 @@ -29,7 +29,7 @@ fabricRecipeViewer = rei # Forge Settings forgeVersion = 45.0.24 -forgeRecipeViewer = rei +forgeRecipeViewer = jei # Github githubUser = AlmostReliable