From ddecc0c76ad1fec89eb3e2968c204d46d35efcf7 Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Tue, 13 Aug 2024 22:22:09 +0800 Subject: [PATCH 1/2] Basic JEI impl --- build.gradle | 18 ++++++ gradle.properties | 6 +- .../compatibility/emi/SkyblockEmiRecipe.java | 4 +- .../jei/SkyblockCraftingRecipeCategory.java | 33 ++++++++++ .../jei/SkyblockerJEIPlugin.java | 64 +++++++++++++++++++ .../itemlist/SkyblockCraftingRecipe.java | 6 ++ .../ItemStackComponentizationFixer.java | 20 +++--- src/main/resources/fabric.mod.json | 3 + 8 files changed, 140 insertions(+), 14 deletions(-) create mode 100644 src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockCraftingRecipeCategory.java create mode 100644 src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockerJEIPlugin.java diff --git a/build.gradle b/build.gradle index dd5babd172..97133efb5d 100644 --- a/build.gradle +++ b/build.gradle @@ -47,6 +47,20 @@ repositories { } } + // For JEI + exclusiveContent { + forRepository { + maven { + name = "Modrinth" + url = "https://api.modrinth.com/maven" + } + } + + filter { + includeGroup "maven.modrinth" + } + } + // YACL maven { url "https://maven.isxander.dev/releases" @@ -151,6 +165,10 @@ dependencies { modCompileOnly "dev.emi:emi-fabric:${project.emi_version}:api" //modLocalRuntime "dev.emi:emi-fabric:${project.emi_version}" + // JEI (Using modrinth repo since official release is in mojmap and doesn't work) + modCompileOnly "maven.modrinth:jei:${project.jei_version}-fabric" + //modRuntimeOnly "maven.modrinth:jei:${project.jei_version}-fabric" + compileOnly "com.demonwav.mcdev:annotations:${project.mcdev_annotations_version}" include modImplementation("meteordevelopment:discord-ipc:1.1") diff --git a/gradle.properties b/gradle.properties index dc2b917a93..5455212564 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,12 +4,12 @@ org.gradle.parallel=true # Fabric Properties (https://fabricmc.net/versions.html) ## 1.21.1 minecraft_version=1.21.1 -yarn_mappings=1.21.1+build.1 +yarn_mappings=1.21.1+build.3 loader_version=0.15.11 #Fabric api ## 1.21.1 -fabric_api_version=0.102.0+1.21.1 +fabric_api_version=0.102.1+1.21.1 # Minecraft Mods ## YACL (https://github.com/isXander/YetAnotherConfigLib) @@ -22,6 +22,8 @@ mod_menu_version = 11.0.0-beta.1 rei_version = 13.0.666 ## EMI (https://modrinth.com/mod/emi/versions) emi_version = 1.1.10+1.21 +## JEI (https://modrinth.com/mod/jei/versions) +jei_version = 19.8.4.113 # Minecraft and Related Libraries ## McDev Annotations (https://central.sonatype.com/artifact/com.demonwav.mcdev/annotations) diff --git a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java index 218eb8d126..7f102fc1e5 100644 --- a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java +++ b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java @@ -1,7 +1,6 @@ package de.hysky.skyblocker.compatibility.emi; import de.hysky.skyblocker.skyblock.itemlist.SkyblockCraftingRecipe; -import de.hysky.skyblocker.utils.ItemUtils; import dev.emi.emi.api.recipe.EmiCraftingRecipe; import dev.emi.emi.api.recipe.EmiRecipeCategory; import dev.emi.emi.api.stack.EmiIngredient; @@ -9,13 +8,12 @@ import dev.emi.emi.api.widget.WidgetHolder; import net.minecraft.client.MinecraftClient; import net.minecraft.text.Text; -import net.minecraft.util.Identifier; public class SkyblockEmiRecipe extends EmiCraftingRecipe { private final String craftText; public SkyblockEmiRecipe(SkyblockCraftingRecipe recipe) { - super(recipe.getGrid().stream().map(EmiStack::of).map(EmiIngredient.class::cast).toList(), EmiStack.of(recipe.getResult()), Identifier.of("skyblock", ItemUtils.getItemId(recipe.getResult()).toLowerCase().replace(';', '_') + "_" + recipe.getResult().getCount())); + super(recipe.getGrid().stream().map(EmiStack::of).map(EmiIngredient.class::cast).toList(), EmiStack.of(recipe.getResult()), recipe.getId()); this.craftText = recipe.getCraftText(); } diff --git a/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockCraftingRecipeCategory.java b/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockCraftingRecipeCategory.java new file mode 100644 index 0000000000..05bb7c5e26 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockCraftingRecipeCategory.java @@ -0,0 +1,33 @@ +package de.hysky.skyblocker.compatibility.jei; + +import de.hysky.skyblocker.SkyblockerMod; +import mezz.jei.api.helpers.IGuiHelper; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.library.plugins.vanilla.crafting.CraftingRecipeCategory; +import net.minecraft.recipe.CraftingRecipe; +import net.minecraft.recipe.RecipeEntry; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.NotNull; + +public class SkyblockCraftingRecipeCategory extends CraftingRecipeCategory { + @SuppressWarnings({"unchecked", "RedundantCast", "rawtypes"}) + private static final RecipeType> SKYBLOCK_RECIPE = new RecipeType<>(Identifier.of(SkyblockerMod.NAMESPACE, "skyblock"), (Class>) (Class) RecipeEntry.class); + private final Text title = Text.translatable("emi.category.skyblocker.skyblock"); + + public SkyblockCraftingRecipeCategory(IGuiHelper guiHelper) { + super(guiHelper); + } + + @Override + @NotNull + public RecipeType> getRecipeType() { + return SKYBLOCK_RECIPE; + } + + @NotNull + @Override + public Text getTitle() { + return title; + } +} \ No newline at end of file diff --git a/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockerJEIPlugin.java b/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockerJEIPlugin.java new file mode 100644 index 0000000000..0c709232a8 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockerJEIPlugin.java @@ -0,0 +1,64 @@ +package de.hysky.skyblocker.compatibility.jei; + +import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.skyblock.itemlist.ItemRepository; +import de.hysky.skyblocker.utils.datafixer.ItemStackComponentizationFixer; +import mezz.jei.api.IModPlugin; +import mezz.jei.api.JeiPlugin; +import mezz.jei.api.constants.RecipeTypes; +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.registration.IRecipeCategoryRegistration; +import mezz.jei.api.registration.IRecipeRegistration; +import mezz.jei.api.registration.ISubtypeRegistration; +import mezz.jei.library.ingredients.subtypes.SubtypeInterpreters; +import mezz.jei.library.load.registration.SubtypeRegistration; +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.*; +import net.minecraft.recipe.book.CraftingRecipeCategory; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.NotNull; + +import java.util.Map; + +@JeiPlugin +public class SkyblockerJEIPlugin implements IModPlugin { + private SkyblockCraftingRecipeCategory skyblockCraftingRecipeCategory; + + @Override + @NotNull + public Identifier getPluginUid() { + return Identifier.of(SkyblockerMod.NAMESPACE, "skyblock"); + } + + @Override + public void registerItemSubtypes(@NotNull ISubtypeRegistration registration) { + SubtypeInterpreters interpreters = ((SubtypeRegistration) registration).getInterpreters(); + ItemRepository.getItemsStream().filter(stack -> !interpreters.contains(VanillaTypes.ITEM_STACK, stack)).map(ItemStack::getItem).distinct().forEach(item -> + registration.registerSubtypeInterpreter(item, (stack, context) -> ItemStackComponentizationFixer.componentsAsString(stack)) + ); + } + + @Override + public void registerCategories(@NotNull IRecipeCategoryRegistration registration) { +// registration.addRecipeCategories(skyblockCraftingRecipeCategory = new SkyblockCraftingRecipeCategory(registration.getJeiHelpers().getGuiHelper())); + } + + @Override + public void registerRecipes(@NotNull IRecipeRegistration registration) { + registration.getIngredientManager().addIngredientsAtRuntime(VanillaTypes.ITEM_STACK, ItemRepository.getItems()); +// registration.addRecipes(skyblockCraftingRecipeCategory.getRecipeType(), ItemRepository.getRecipesStream().map(recipe -> + registration.addRecipes(RecipeTypes.CRAFTING, ItemRepository.getRecipesStream().map(recipe -> + new RecipeEntry(recipe.getId(), new ShapedRecipe("", CraftingRecipeCategory.MISC, RawShapedRecipe.create(Map.of( + 'a', Ingredient.ofStacks(recipe.getGrid().get(0)), + 'b', Ingredient.ofStacks(recipe.getGrid().get(1)), + 'c', Ingredient.ofStacks(recipe.getGrid().get(2)), + 'd', Ingredient.ofStacks(recipe.getGrid().get(3)), + 'e', Ingredient.ofStacks(recipe.getGrid().get(4)), + 'f', Ingredient.ofStacks(recipe.getGrid().get(5)), + 'g', Ingredient.ofStacks(recipe.getGrid().get(6)), + 'h', Ingredient.ofStacks(recipe.getGrid().get(7)), + 'i', Ingredient.ofStacks(recipe.getGrid().get(8)) + ), "abc", "def", "ghi"), recipe.getResult())) + ).toList()); + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SkyblockCraftingRecipe.java b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SkyblockCraftingRecipe.java index f5b379dc43..bc6d797751 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SkyblockCraftingRecipe.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/itemlist/SkyblockCraftingRecipe.java @@ -1,9 +1,11 @@ package de.hysky.skyblocker.skyblock.itemlist; +import de.hysky.skyblocker.utils.ItemUtils; import io.github.moulberry.repo.data.NEUCraftingRecipe; import io.github.moulberry.repo.data.NEUIngredient; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; +import net.minecraft.util.Identifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -52,4 +54,8 @@ public ItemStack getResult() { public String getCraftText() { return craftText; } + + public Identifier getId() { + return Identifier.of("skyblock", ItemUtils.getItemId(getResult()).toLowerCase().replace(';', '_') + "_" + getResult().getCount()); + } } diff --git a/src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java b/src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java index a9b227a18c..9c74cc99c0 100644 --- a/src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java +++ b/src/main/java/de/hysky/skyblocker/utils/datafixer/ItemStackComponentizationFixer.java @@ -10,6 +10,7 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.command.argument.ItemStringReader; import net.minecraft.command.argument.ItemStringReader.ItemResult; +import net.minecraft.component.Component; import net.minecraft.component.ComponentType; import net.minecraft.datafixer.Schemas; import net.minecraft.datafixer.TypeReferences; @@ -48,15 +49,16 @@ public static String componentsAsString(ItemStack stack) { RegistryOps nbtRegistryOps = getRegistryLookup().getOps(NbtOps.INSTANCE); return Arrays.toString(stack.getComponentChanges().entrySet().stream().map(entry -> { - @SuppressWarnings("unchecked") - ComponentType dataComponentType = (ComponentType) entry.getKey(); - Identifier componentId = Registries.DATA_COMPONENT_TYPE.getId(dataComponentType); - Optional encodedComponent = dataComponentType.getCodec().encodeStart(nbtRegistryOps, entry.getValue().orElseThrow()).result(); + ComponentType componentType = entry.getKey(); + Identifier componentId = Registries.DATA_COMPONENT_TYPE.getId(componentType); + if (componentId == null) return null; - if (componentId == null || encodedComponent.isEmpty()) { - return null; - } + Optional component = entry.getValue(); + if (component.isEmpty()) return "!" + componentId; + Optional encodedComponent = Component.of(componentType, component.get()).encode(nbtRegistryOps).result(); + + if (encodedComponent.isEmpty()) return null; return componentId + "=" + encodedComponent.orElseThrow(); }).filter(Objects::nonNull).toArray()); } @@ -87,6 +89,6 @@ public static ItemStack fromComponentsString(String itemId, int count, String co */ public static WrapperLookup getRegistryLookup() { MinecraftClient client = MinecraftClient.getInstance(); - return client != null && client.getNetworkHandler() != null && client.getNetworkHandler().getRegistryManager() != null ? client.getNetworkHandler().getRegistryManager() : LOOKUP; - } + return client != null && client.getNetworkHandler() != null && client.getNetworkHandler().getRegistryManager() != null ? client.getNetworkHandler().getRegistryManager() : LOOKUP; + } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index f7a2273c57..58ff95d050 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -26,6 +26,9 @@ ], "emi": [ "de.hysky.skyblocker.compatibility.emi.SkyblockerEMIPlugin" + ], + "jei_mod_plugin": [ + "de.hysky.skyblocker.compatibility.jei.SkyblockerJEIPlugin" ] }, "mixins": [ From 39d78b4bf85d745559bc9eaecce807aaf5fd450e Mon Sep 17 00:00:00 2001 From: Kevinthegreat <92656833+kevinthegreat1@users.noreply.github.com> Date: Sun, 18 Aug 2024 17:05:33 +0800 Subject: [PATCH 2/2] Add skyblock crafting category --- .../jei/SkyblockCraftingRecipeCategory.java | 9 +++++++++ .../compatibility/jei/SkyblockerJEIPlugin.java | 9 +++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockCraftingRecipeCategory.java b/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockCraftingRecipeCategory.java index 05bb7c5e26..c08155a5d5 100644 --- a/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockCraftingRecipeCategory.java +++ b/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockCraftingRecipeCategory.java @@ -1,6 +1,8 @@ package de.hysky.skyblocker.compatibility.jei; import de.hysky.skyblocker.SkyblockerMod; +import de.hysky.skyblocker.utils.ItemUtils; +import mezz.jei.api.gui.drawable.IDrawable; import mezz.jei.api.helpers.IGuiHelper; import mezz.jei.api.recipe.RecipeType; import mezz.jei.library.plugins.vanilla.crafting.CraftingRecipeCategory; @@ -14,9 +16,11 @@ public class SkyblockCraftingRecipeCategory extends CraftingRecipeCategory { @SuppressWarnings({"unchecked", "RedundantCast", "rawtypes"}) private static final RecipeType> SKYBLOCK_RECIPE = new RecipeType<>(Identifier.of(SkyblockerMod.NAMESPACE, "skyblock"), (Class>) (Class) RecipeEntry.class); private final Text title = Text.translatable("emi.category.skyblocker.skyblock"); + private final IDrawable icon; public SkyblockCraftingRecipeCategory(IGuiHelper guiHelper) { super(guiHelper); + icon = guiHelper.createDrawableItemStack(ItemUtils.getSkyblockerStack()); } @Override @@ -30,4 +34,9 @@ public RecipeType> getRecipeType() { public Text getTitle() { return title; } + + @Override + public IDrawable getIcon() { + return icon; + } } \ No newline at end of file diff --git a/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockerJEIPlugin.java b/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockerJEIPlugin.java index 0c709232a8..a1e57682af 100644 --- a/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockerJEIPlugin.java +++ b/src/main/java/de/hysky/skyblocker/compatibility/jei/SkyblockerJEIPlugin.java @@ -5,13 +5,13 @@ import de.hysky.skyblocker.utils.datafixer.ItemStackComponentizationFixer; import mezz.jei.api.IModPlugin; import mezz.jei.api.JeiPlugin; -import mezz.jei.api.constants.RecipeTypes; import mezz.jei.api.constants.VanillaTypes; import mezz.jei.api.registration.IRecipeCategoryRegistration; import mezz.jei.api.registration.IRecipeRegistration; import mezz.jei.api.registration.ISubtypeRegistration; import mezz.jei.library.ingredients.subtypes.SubtypeInterpreters; import mezz.jei.library.load.registration.SubtypeRegistration; +import mezz.jei.library.plugins.vanilla.crafting.CraftingCategoryExtension; import net.minecraft.item.ItemStack; import net.minecraft.recipe.*; import net.minecraft.recipe.book.CraftingRecipeCategory; @@ -40,14 +40,15 @@ public void registerItemSubtypes(@NotNull ISubtypeRegistration registration) { @Override public void registerCategories(@NotNull IRecipeCategoryRegistration registration) { -// registration.addRecipeCategories(skyblockCraftingRecipeCategory = new SkyblockCraftingRecipeCategory(registration.getJeiHelpers().getGuiHelper())); + skyblockCraftingRecipeCategory = new SkyblockCraftingRecipeCategory(registration.getJeiHelpers().getGuiHelper()); + skyblockCraftingRecipeCategory.addExtension(CraftingRecipe.class, new CraftingCategoryExtension()); + registration.addRecipeCategories(skyblockCraftingRecipeCategory); } @Override public void registerRecipes(@NotNull IRecipeRegistration registration) { registration.getIngredientManager().addIngredientsAtRuntime(VanillaTypes.ITEM_STACK, ItemRepository.getItems()); -// registration.addRecipes(skyblockCraftingRecipeCategory.getRecipeType(), ItemRepository.getRecipesStream().map(recipe -> - registration.addRecipes(RecipeTypes.CRAFTING, ItemRepository.getRecipesStream().map(recipe -> + registration.addRecipes(skyblockCraftingRecipeCategory.getRecipeType(), ItemRepository.getRecipesStream().map(recipe -> new RecipeEntry(recipe.getId(), new ShapedRecipe("", CraftingRecipeCategory.MISC, RawShapedRecipe.create(Map.of( 'a', Ingredient.ofStacks(recipe.getGrid().get(0)), 'b', Ingredient.ofStacks(recipe.getGrid().get(1)),