From 21b8e18d4f17d292651f9f5ca313c24e4f5ac455 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Thu, 10 Oct 2024 07:18:46 -0700 Subject: [PATCH 1/4] add ability to sort categories --- examples/postInit/jei.groovy | 2 ++ .../compat/mods/jei/Category.java | 27 ++++++++++++--- .../compat/mods/jei/JeiPlugin.java | 14 ++++++++ .../core/mixin/jei/RecipeRegistryMixin.java | 33 +++++++++++++++++++ .../assets/groovyscript/lang/en_us.lang | 3 +- .../resources/mixin.groovyscript.jei.json | 3 +- 6 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/cleanroommc/groovyscript/core/mixin/jei/RecipeRegistryMixin.java diff --git a/examples/postInit/jei.groovy b/examples/postInit/jei.groovy index 61e8cfd30..b7fd4d9a3 100644 --- a/examples/postInit/jei.groovy +++ b/examples/postInit/jei.groovy @@ -29,6 +29,8 @@ mods.jei.category.hideCategory('minecraft.fuel') .register()*/ +mods.jei.category.setOrder('minecraft.crafting', 'jei.information', 'minecraft.smelting', 'groovyscript:burning', 'groovyscript:explosion', 'groovyscript:fluid_recipe', 'groovyscript:piston_push', 'minecraft.anvil') + // Description Category: // Modify the description of the input items, where the description is a unique JEI tab containing text. diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/Category.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/Category.java index da0af4020..cbe0ddff0 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/Category.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/Category.java @@ -15,10 +15,7 @@ import mezz.jei.api.recipe.IRecipeWrapper; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.function.Function; @RegistryDescription(category = RegistryDescription.Category.ENTRIES, @@ -28,6 +25,7 @@ public class Category extends VirtualizedRegistry { private boolean hideAllCategories; private final AbstractReloadableStorage categoryStorage = new AbstractReloadableStorage<>(); + private final List categoryUidOrder = new ArrayList<>(); /** * Called by {@link JeiPlugin#afterRuntimeAvailable()} @@ -38,6 +36,14 @@ public void applyChanges(IRecipeRegistry recipeRegistry) { getBackupRecipes().forEach(recipeRegistry::hideRecipeCategory); } + /** + * Called by {@link JeiPlugin#getCategoryComparator()} + */ + @GroovyBlacklist + public List getOrder() { + return categoryUidOrder; + } + @MethodDescription public void add(CustomCategory customCategory) { categoryStorage.addScripted(customCategory); @@ -91,6 +97,17 @@ public void onReload() { restoreFromBackup(); hideAllCategories = false; categoryStorage.removeScripted(); + categoryUidOrder.clear(); + } + + @MethodDescription(type = MethodDescription.Type.VALUE) + public void setOrder(List categoryUidOrder) { + this.categoryUidOrder.addAll(categoryUidOrder); + } + + @MethodDescription(type = MethodDescription.Type.VALUE, example = @Example("'minecraft.crafting', 'jei.information', 'minecraft.smelting', 'groovyscript:burning', 'groovyscript:explosion', 'groovyscript:fluid_recipe', 'groovyscript:piston_push', 'minecraft.anvil'")) + public void setOrder(String... categoryUidOrder) { + setOrder(Arrays.asList(categoryUidOrder)); } @MethodDescription(description = "groovyscript.wiki.jei.category.hideCategory") @@ -117,7 +134,7 @@ public void hideAll() { @SuppressWarnings("ClassCanBeRecord") public static final class CustomCategory { - + private final String id; private final Function> category; private final List catalysts; diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/JeiPlugin.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/JeiPlugin.java index 27900602f..e9503fad6 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/JeiPlugin.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/JeiPlugin.java @@ -23,6 +23,8 @@ import net.minecraft.util.text.TextComponentString; import net.minecraftforge.fluids.FluidStack; +import java.util.Comparator; + @SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod") @GroovyBlacklist @JEIPlugin @@ -47,6 +49,18 @@ public static void afterRuntimeAvailable() { ModSupport.JEI.get().description.applyRemovals(jeiRuntime.getRecipeRegistry()); } + /** + * We want to only return the index of the category if it exists, otherwise we want it placed at the end of the list. + * If this wasn't the case, any categories not in the list (such as new ones) would be disruptive to the user experience. + */ + public static Comparator> getCategoryComparator() { + var order = ModSupport.JEI.get().category.getOrder(); + return Comparator.comparingInt(category -> { + var uid = category.getUid(); + return order.contains(uid) ? order.indexOf(uid) : Integer.MAX_VALUE; + }); + } + public static boolean isLoaded() { return jeiRuntime != null; } diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/jei/RecipeRegistryMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/jei/RecipeRegistryMixin.java new file mode 100644 index 000000000..9d6ffb39d --- /dev/null +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/jei/RecipeRegistryMixin.java @@ -0,0 +1,33 @@ +package com.cleanroommc.groovyscript.core.mixin.jei; + +import com.cleanroommc.groovyscript.compat.mods.jei.JeiPlugin; +import mezz.jei.api.recipe.IRecipeCategory; +import mezz.jei.recipes.RecipeRegistry; +import mezz.jei.startup.ModRegistry; +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 java.util.List; + +@Mixin(value = ModRegistry.class, remap = false) +public abstract class RecipeRegistryMixin { + + @Shadow + @Final + private List> recipeCategories; + + /** + * @reason Sort recipe categories according to a list created and managed by GroovyScript + * to allow a custom order for JEI category tabs. + * @see JeiPlugin#getCategoryComparator() + */ + @Inject(method = "createRecipeRegistry", at = @At("HEAD")) + private void grs$sortRecipeCategories(CallbackInfoReturnable ci) { + recipeCategories.sort(JeiPlugin.getCategoryComparator()); + } + +} diff --git a/src/main/resources/assets/groovyscript/lang/en_us.lang b/src/main/resources/assets/groovyscript/lang/en_us.lang index 7b6d13ccb..19a937bf7 100644 --- a/src/main/resources/assets/groovyscript/lang/en_us.lang +++ b/src/main/resources/assets/groovyscript/lang/en_us.lang @@ -1391,7 +1391,7 @@ groovyscript.wiki.jei.catalyst.remove=Removes the given catalyst items from the groovyscript.wiki.jei.catalyst.removeByType=Removes all catalyst items from the given category groovyscript.wiki.jei.category.title=Categories -groovyscript.wiki.jei.category.description=Modify the Categories visible in JEI, each of which contain recipes and are associated with specific blocks, typically machines. +groovyscript.wiki.jei.category.description=Modify the Categories visible in JEI, each of which contain recipes and are associated with specific blocks, typically machines. Can also set the order of Categories. groovyscript.wiki.jei.category.note0=Hidden Categories will still take up load time, and recipes contained within can still be processed. This only prevents seeing Categories. groovyscript.wiki.jei.category.annotation=Note that `classes.GenericRecipeCategory` must be defined elsewhere, and this example presumes certain fields and methods exist. groovyscript.wiki.jei.category.id.value=Sets the ID of the Category, which must be unique among all other Categories @@ -1401,6 +1401,7 @@ groovyscript.wiki.jei.category.category.value=Sets the function used to generate groovyscript.wiki.jei.category.add=Adds a new Category to JEI in the format `id`, `category`, `catalsyts`, `wrappers` groovyscript.wiki.jei.category.hideCategory=Hides the given category from JEI groovyscript.wiki.jei.category.hideAll=Hides all categories from JEI +groovyscript.wiki.jei.category.setOrder=Sets the order of categories in JEI. Categories not included in the list will be placed at the end according to their normal order. groovyscript.wiki.jei.description.title=Description Category groovyscript.wiki.jei.description.description=Modify the description of the input items, where the description is a unique JEI tab containing text. diff --git a/src/main/resources/mixin.groovyscript.jei.json b/src/main/resources/mixin.groovyscript.jei.json index 2b32b5c24..fab2d42a6 100644 --- a/src/main/resources/mixin.groovyscript.jei.json +++ b/src/main/resources/mixin.groovyscript.jei.json @@ -8,6 +8,7 @@ "IngredientInfoRecipeAccessor", "JeiProxyAccessor", "JeiStarterMixin", - "ModRegistryAccessor" + "ModRegistryAccessor", + "RecipeRegistryMixin" ] } \ No newline at end of file From 0c39a9798e3c5c9ce85cec22e9384b326e47f72a Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Thu, 10 Oct 2024 07:19:27 -0700 Subject: [PATCH 2/4] add tip for using the command to get category uids --- examples/postInit/jei.groovy | 2 +- .../cleanroommc/groovyscript/compat/mods/jei/Category.java | 6 ++++-- src/main/resources/assets/groovyscript/lang/en_us.lang | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/postInit/jei.groovy b/examples/postInit/jei.groovy index b7fd4d9a3..bf4fa52a5 100644 --- a/examples/postInit/jei.groovy +++ b/examples/postInit/jei.groovy @@ -16,7 +16,7 @@ mods.jei.catalyst.add('minecraft.smelting', item('minecraft:clay') * 8, item('mi // Categories: // Modify the Categories visible in JEI, each of which contain recipes and are associated with specific blocks, typically -// machines. +// machines. Can also set the order of Categories. mods.jei.category.hideCategory('minecraft.fuel') // mods.jei.category.hideAll() diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/Category.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/Category.java index cbe0ddff0..531eca9a7 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/Category.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/Category.java @@ -18,8 +18,10 @@ import java.util.*; import java.util.function.Function; -@RegistryDescription(category = RegistryDescription.Category.ENTRIES, - admonition = @Admonition("groovyscript.wiki.jei.category.note0")) +@RegistryDescription(category = RegistryDescription.Category.ENTRIES, admonition = { + @Admonition("groovyscript.wiki.jei.category.note0"), + @Admonition(value = "groovyscript.wiki.jei.category.note1", type = Admonition.Type.TIP) +}) public class Category extends VirtualizedRegistry { private boolean hideAllCategories; diff --git a/src/main/resources/assets/groovyscript/lang/en_us.lang b/src/main/resources/assets/groovyscript/lang/en_us.lang index 19a937bf7..93e257b78 100644 --- a/src/main/resources/assets/groovyscript/lang/en_us.lang +++ b/src/main/resources/assets/groovyscript/lang/en_us.lang @@ -1393,6 +1393,7 @@ groovyscript.wiki.jei.catalyst.removeByType=Removes all catalyst items from the groovyscript.wiki.jei.category.title=Categories groovyscript.wiki.jei.category.description=Modify the Categories visible in JEI, each of which contain recipes and are associated with specific blocks, typically machines. Can also set the order of Categories. groovyscript.wiki.jei.category.note0=Hidden Categories will still take up load time, and recipes contained within can still be processed. This only prevents seeing Categories. +groovyscript.wiki.jei.category.note1=Use the command `/gs jeiCategories` to log the UIDs of all JEI Categories to the `groovy.log` file! groovyscript.wiki.jei.category.annotation=Note that `classes.GenericRecipeCategory` must be defined elsewhere, and this example presumes certain fields and methods exist. groovyscript.wiki.jei.category.id.value=Sets the ID of the Category, which must be unique among all other Categories groovyscript.wiki.jei.category.wrapper.value=Sets the `IRecipeWrapper`s used by the Category to generate entries From 9216fbeae4a83286c1e71eedecac865b196cbc61 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Thu, 10 Oct 2024 08:43:34 -0700 Subject: [PATCH 3/4] rename mixin class --- .../jei/{RecipeRegistryMixin.java => ModRegistryMixin.java} | 2 +- src/main/resources/mixin.groovyscript.jei.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename src/main/java/com/cleanroommc/groovyscript/core/mixin/jei/{RecipeRegistryMixin.java => ModRegistryMixin.java} (96%) diff --git a/src/main/java/com/cleanroommc/groovyscript/core/mixin/jei/RecipeRegistryMixin.java b/src/main/java/com/cleanroommc/groovyscript/core/mixin/jei/ModRegistryMixin.java similarity index 96% rename from src/main/java/com/cleanroommc/groovyscript/core/mixin/jei/RecipeRegistryMixin.java rename to src/main/java/com/cleanroommc/groovyscript/core/mixin/jei/ModRegistryMixin.java index 9d6ffb39d..f63b662ae 100644 --- a/src/main/java/com/cleanroommc/groovyscript/core/mixin/jei/RecipeRegistryMixin.java +++ b/src/main/java/com/cleanroommc/groovyscript/core/mixin/jei/ModRegistryMixin.java @@ -14,7 +14,7 @@ import java.util.List; @Mixin(value = ModRegistry.class, remap = false) -public abstract class RecipeRegistryMixin { +public abstract class ModRegistryMixin { @Shadow @Final diff --git a/src/main/resources/mixin.groovyscript.jei.json b/src/main/resources/mixin.groovyscript.jei.json index fab2d42a6..3fe83a680 100644 --- a/src/main/resources/mixin.groovyscript.jei.json +++ b/src/main/resources/mixin.groovyscript.jei.json @@ -9,6 +9,6 @@ "JeiProxyAccessor", "JeiStarterMixin", "ModRegistryAccessor", - "RecipeRegistryMixin" + "ModRegistryMixin" ] } \ No newline at end of file From 909bfbb780838bbf3b44146775af0aea0a233269 Mon Sep 17 00:00:00 2001 From: Waiting Idly <25394029+WaitingIdly@users.noreply.github.com> Date: Thu, 10 Oct 2024 09:07:48 -0700 Subject: [PATCH 4/4] use indexOf once instead of contains --- .../cleanroommc/groovyscript/compat/mods/jei/JeiPlugin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/JeiPlugin.java b/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/JeiPlugin.java index e9503fad6..0106116ed 100644 --- a/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/JeiPlugin.java +++ b/src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/JeiPlugin.java @@ -56,8 +56,8 @@ public static void afterRuntimeAvailable() { public static Comparator> getCategoryComparator() { var order = ModSupport.JEI.get().category.getOrder(); return Comparator.comparingInt(category -> { - var uid = category.getUid(); - return order.contains(uid) ? order.indexOf(uid) : Integer.MAX_VALUE; + var index = order.indexOf(category.getUid()); + return index >= 0 ? index : Integer.MAX_VALUE; }); }