Skip to content

Commit aef4323

Browse files
authored
add JEI Category Sorting functionality (#257)
* add ability to sort categories * add tip for using the command to get category uids * rename mixin class * use indexOf once instead of contains
1 parent c3d8582 commit aef4323

File tree

6 files changed

+79
-10
lines changed

6 files changed

+79
-10
lines changed

examples/postInit/jei.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ mods.jei.catalyst.add('minecraft.smelting', item('minecraft:clay') * 8, item('mi
1616

1717
// Categories:
1818
// Modify the Categories visible in JEI, each of which contain recipes and are associated with specific blocks, typically
19-
// machines.
19+
// machines. Can also set the order of Categories.
2020

2121
mods.jei.category.hideCategory('minecraft.fuel')
2222
// mods.jei.category.hideAll()
@@ -29,6 +29,8 @@ mods.jei.category.hideCategory('minecraft.fuel')
2929
.register()*/
3030

3131

32+
mods.jei.category.setOrder('minecraft.crafting', 'jei.information', 'minecraft.smelting', 'groovyscript:burning', 'groovyscript:explosion', 'groovyscript:fluid_recipe', 'groovyscript:piston_push', 'minecraft.anvil')
33+
3234
// Description Category:
3335
// Modify the description of the input items, where the description is a unique JEI tab containing text.
3436

src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/Category.java

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,19 @@
1515
import mezz.jei.api.recipe.IRecipeWrapper;
1616
import org.jetbrains.annotations.Nullable;
1717

18-
import java.util.ArrayList;
19-
import java.util.Collection;
20-
import java.util.List;
21-
import java.util.Objects;
18+
import java.util.*;
2219
import java.util.function.Function;
2320

24-
@RegistryDescription(
25-
category = RegistryDescription.Category.ENTRIES,
26-
admonition = @Admonition("groovyscript.wiki.jei.category.note0"))
21+
@RegistryDescription(category = RegistryDescription.Category.ENTRIES, admonition = {
22+
@Admonition("groovyscript.wiki.jei.category.note0"),
23+
@Admonition(value = "groovyscript.wiki.jei.category.note1", type = Admonition.Type.TIP)
24+
})
2725
public class Category extends VirtualizedRegistry<String> {
2826

2927
private boolean hideAllCategories;
3028

3129
private final AbstractReloadableStorage<CustomCategory> categoryStorage = new AbstractReloadableStorage<>();
30+
private final List<String> categoryUidOrder = new ArrayList<>();
3231

3332
/**
3433
* Called by {@link JeiPlugin#afterRuntimeAvailable()}
@@ -39,6 +38,14 @@ public void applyChanges(IRecipeRegistry recipeRegistry) {
3938
getBackupRecipes().forEach(recipeRegistry::hideRecipeCategory);
4039
}
4140

41+
/**
42+
* Called by {@link JeiPlugin#getCategoryComparator()}
43+
*/
44+
@GroovyBlacklist
45+
public List<String> getOrder() {
46+
return categoryUidOrder;
47+
}
48+
4249
@MethodDescription
4350
public void add(CustomCategory customCategory) {
4451
categoryStorage.addScripted(customCategory);
@@ -92,6 +99,17 @@ public void onReload() {
9299
restoreFromBackup();
93100
hideAllCategories = false;
94101
categoryStorage.removeScripted();
102+
categoryUidOrder.clear();
103+
}
104+
105+
@MethodDescription(type = MethodDescription.Type.VALUE)
106+
public void setOrder(List<String> categoryUidOrder) {
107+
this.categoryUidOrder.addAll(categoryUidOrder);
108+
}
109+
110+
@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'"))
111+
public void setOrder(String... categoryUidOrder) {
112+
setOrder(Arrays.asList(categoryUidOrder));
95113
}
96114

97115
@MethodDescription(description = "groovyscript.wiki.jei.category.hideCategory")

src/main/java/com/cleanroommc/groovyscript/compat/mods/jei/JeiPlugin.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
import net.minecraft.util.text.TextComponentString;
2424
import net.minecraftforge.fluids.FluidStack;
2525

26+
import java.util.Comparator;
27+
2628
@SuppressWarnings("AssignmentToStaticFieldFromInstanceMethod")
2729
@GroovyBlacklist
2830
@JEIPlugin
@@ -47,6 +49,18 @@ public static void afterRuntimeAvailable() {
4749
ModSupport.JEI.get().description.applyRemovals(jeiRuntime.getRecipeRegistry());
4850
}
4951

52+
/**
53+
* We want to only return the index of the category if it exists, otherwise we want it placed at the end of the list.
54+
* If this wasn't the case, any categories not in the list (such as new ones) would be disruptive to the user experience.
55+
*/
56+
public static Comparator<IRecipeCategory<?>> getCategoryComparator() {
57+
var order = ModSupport.JEI.get().category.getOrder();
58+
return Comparator.comparingInt(category -> {
59+
var index = order.indexOf(category.getUid());
60+
return index >= 0 ? index : Integer.MAX_VALUE;
61+
});
62+
}
63+
5064
public static boolean isLoaded() {
5165
return jeiRuntime != null;
5266
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.cleanroommc.groovyscript.core.mixin.jei;
2+
3+
import com.cleanroommc.groovyscript.compat.mods.jei.JeiPlugin;
4+
import mezz.jei.api.recipe.IRecipeCategory;
5+
import mezz.jei.recipes.RecipeRegistry;
6+
import mezz.jei.startup.ModRegistry;
7+
import org.spongepowered.asm.mixin.Final;
8+
import org.spongepowered.asm.mixin.Mixin;
9+
import org.spongepowered.asm.mixin.Shadow;
10+
import org.spongepowered.asm.mixin.injection.At;
11+
import org.spongepowered.asm.mixin.injection.Inject;
12+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
13+
14+
import java.util.List;
15+
16+
@Mixin(value = ModRegistry.class, remap = false)
17+
public abstract class ModRegistryMixin {
18+
19+
@Shadow
20+
@Final
21+
private List<IRecipeCategory<?>> recipeCategories;
22+
23+
/**
24+
* @reason Sort recipe categories according to a list created and managed by GroovyScript
25+
* to allow a custom order for JEI category tabs.
26+
* @see JeiPlugin#getCategoryComparator()
27+
*/
28+
@Inject(method = "createRecipeRegistry", at = @At("HEAD"))
29+
private void grs$sortRecipeCategories(CallbackInfoReturnable<RecipeRegistry> ci) {
30+
recipeCategories.sort(JeiPlugin.getCategoryComparator());
31+
}
32+
}

src/main/resources/assets/groovyscript/lang/en_us.lang

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1423,8 +1423,9 @@ groovyscript.wiki.jei.catalyst.remove=Removes the given catalyst items from the
14231423
groovyscript.wiki.jei.catalyst.removeByType=Removes all catalyst items from the given category
14241424

14251425
groovyscript.wiki.jei.category.title=Categories
1426-
groovyscript.wiki.jei.category.description=Modify the Categories visible in JEI, each of which contain recipes and are associated with specific blocks, typically machines.
1426+
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.
14271427
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.
1428+
groovyscript.wiki.jei.category.note1=Use the command `/gs jeiCategories` to log the UIDs of all JEI Categories to the `groovy.log` file!
14281429
groovyscript.wiki.jei.category.annotation=Note that `classes.GenericRecipeCategory` must be defined elsewhere, and this example presumes certain fields and methods exist.
14291430
groovyscript.wiki.jei.category.id.value=Sets the ID of the Category, which must be unique among all other Categories
14301431
groovyscript.wiki.jei.category.wrapper.value=Sets the `IRecipeWrapper`s used by the Category to generate entries
@@ -1433,6 +1434,7 @@ groovyscript.wiki.jei.category.category.value=Sets the function used to generate
14331434
groovyscript.wiki.jei.category.add=Adds a new Category to JEI in the format `id`, `category`, `catalsyts`, `wrappers`
14341435
groovyscript.wiki.jei.category.hideCategory=Hides the given category from JEI
14351436
groovyscript.wiki.jei.category.hideAll=Hides all categories from JEI
1437+
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.
14361438

14371439
groovyscript.wiki.jei.description.title=Description Category
14381440
groovyscript.wiki.jei.description.description=Modify the description of the input items, where the description is a unique JEI tab containing text.

src/main/resources/mixin.groovyscript.jei.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"IngredientInfoRecipeAccessor",
99
"JeiProxyAccessor",
1010
"JeiStarterMixin",
11-
"ModRegistryAccessor"
11+
"ModRegistryAccessor",
12+
"ModRegistryMixin"
1213
]
1314
}

0 commit comments

Comments
 (0)