Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JEI integration #448

Merged
merged 2 commits into from
Aug 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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")
Expand Down
6 changes: 4 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
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;
import dev.emi.emi.api.stack.EmiStack;
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();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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;
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<RecipeEntry<CraftingRecipe>> SKYBLOCK_RECIPE = new RecipeType<>(Identifier.of(SkyblockerMod.NAMESPACE, "skyblock"), (Class<? extends RecipeEntry<CraftingRecipe>>) (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
@NotNull
public RecipeType<RecipeEntry<CraftingRecipe>> getRecipeType() {
return SKYBLOCK_RECIPE;
}

@NotNull
@Override
public Text getTitle() {
return title;
}

@Override
public IDrawable getIcon() {
return icon;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
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.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;
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) {
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 ->
new RecipeEntry<CraftingRecipe>(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());
}
}
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -48,15 +49,16 @@ public static String componentsAsString(ItemStack stack) {
RegistryOps<NbtElement> nbtRegistryOps = getRegistryLookup().getOps(NbtOps.INSTANCE);

return Arrays.toString(stack.getComponentChanges().entrySet().stream().map(entry -> {
@SuppressWarnings("unchecked")
ComponentType<Object> dataComponentType = (ComponentType<Object>) entry.getKey();
Identifier componentId = Registries.DATA_COMPONENT_TYPE.getId(dataComponentType);
Optional<NbtElement> 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;
AzureAaron marked this conversation as resolved.
Show resolved Hide resolved

Optional<NbtElement> encodedComponent = Component.of(componentType, component.get()).encode(nbtRegistryOps).result();

if (encodedComponent.isEmpty()) return null;
return componentId + "=" + encodedComponent.orElseThrow();
}).filter(Objects::nonNull).toArray());
}
Expand Down Expand Up @@ -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;
}
}
3 changes: 3 additions & 0 deletions src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
],
"emi": [
"de.hysky.skyblocker.compatibility.emi.SkyblockerEMIPlugin"
],
"jei_mod_plugin": [
"de.hysky.skyblocker.compatibility.jei.SkyblockerJEIPlugin"
]
},
"mixins": [
Expand Down