Skip to content

Commit

Permalink
Add JEI support
Browse files Browse the repository at this point in the history
  • Loading branch information
MattiDragon committed Jun 22, 2024
1 parent a5f271b commit fa4ae97
Show file tree
Hide file tree
Showing 23 changed files with 926 additions and 30 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

TLA api is an abstraction layer over recipe viewer apis for minecraft.
It allows mod developers to write their recipe viewer integration once and have it work with multiple recipe viewers.
Currently supported recipe viewers are: [EMI](https://modrinth.com/mod/emi) and [REI](https://modrinth.com/mod/rei)
Currently supported recipe viewers are: [EMI](https://modrinth.com/mod/emi), [REI](https://modrinth.com/mod/rei) and [JEI](https://modrinth.com/mod/jei)

## Usage
### Gradle
Expand Down Expand Up @@ -49,10 +49,10 @@ public class MyTlaPlugin implements TlaApiPlugin {
### Registering Content
Once you've set up your entrypoint you can begin registering content.
The entire api is documented using javadocs, so you can use your IDE to explore the api.
The api design is mostly based on EMIs, but I've had to make some changes to accommodate REI.
The api design is mostly based on EMIs, but I've had to make some changes to accommodate REI and JEI.

### Things to Consider
While the TLA api abstracts everything, you will still need to verify yourself that your code works with both recipe viewers.
While the TLA api abstracts everything, you will still need to verify yourself that your code works with all> recipe viewers.
For example, you still need to translate all of your tags for EMI. Some widgets might also render slightly differently.

A useful thing to look for while using the api are the following annotations.
Expand All @@ -66,7 +66,7 @@ Unless you are creating your own recipe viewer integration, you should not use t

## Questions
#### Q: Does this allow mods that only support one viewer to work on both?
A: No. This api just makes it easier for mod developers to support both viewers.
A: No. This api just makes it easier for mod developers to support all recipe viewers.
#### Q: Why is this api client side only?
A: EMIs entire api is client side only. REI has a server side api, but it doesn't contain any features that TLA uses.
#### Q: Are there any examples?
Expand Down
12 changes: 9 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import org.gradle.kotlin.dsl.support.uppercaseFirstChar

plugins {
id("fabric-loom") version "1.6-SNAPSHOT"
id("fabric-loom") version "1.7-SNAPSHOT"
id("maven-publish")
}

Expand All @@ -17,6 +17,7 @@ base.archivesName = "TLA-Api"
repositories {
maven("https://maven.shedaniel.me/")
maven("https://maven.terraformersmc.com/")
maven("https://maven.blamejared.com/")
}

loom.splitEnvironmentSourceSets()
Expand Down Expand Up @@ -50,7 +51,7 @@ loom {
mods.create("tlaapi_testmod").sourceSet(sourceSets.testmod)
}

arrayOf("rei", "emi").forEach { name ->
arrayOf("rei", "emi", "jei").forEach { name ->
val compilePaths = sourceSets.main.compileClasspath +
sourceSets.main.output +
sourceSets.client.compileClasspath +
Expand Down Expand Up @@ -102,12 +103,17 @@ dependencies {
add("modReiCompileOnly", libs.rei.plugin.default)
// For some reason arch isn't a transitive dependency of rei-api, so we need to manually add it to use a few classes
add("modReiCompileOnly", libs.rei.architectury)
// add("modReiCompileOnly", libs.rei.math)
add("modReiCompileOnly", libs.rei.config)
add("modReiRuntimeOnly", libs.rei.all)

add("modEmiCompileOnly", libs.emi.withClassifier("api"))
add("modEmiRuntimeOnly", libs.emi)

// Because of issues with the remapping of the jei api, we have to depend on the fat jar instead (https://github.com/mezz/JustEnoughItems/issues/2891)
addProvider<MinimalExternalModuleDependency, MinimalExternalModuleDependency>("modJeiCompileOnly", libs.jei.fabric) {
exclude(group = "mezz.jei")
}
add("modJeiRuntimeOnly", libs.jei.fabric)
}

configurations.all {
Expand Down
1 change: 0 additions & 1 deletion changelog/1.0.0+1.20.4.md

This file was deleted.

8 changes: 0 additions & 8 deletions changelog/1.0.1+1.20.4.md

This file was deleted.

3 changes: 0 additions & 3 deletions changelog/1.1.0+1.20.6.md

This file was deleted.

1 change: 0 additions & 1 deletion changelog/1.1.1+1.20.6.md

This file was deleted.

2 changes: 2 additions & 0 deletions changelog/1.2.0+1.21.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* Updated to 1.21 (thanks [@Sollace](https://github.com/Sollace))
* Added JEI support
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ minecraft_version=1.21
yarn_mappings=1.21+build.2
loader_version=0.15.11

mod_version=1.2.0-beta.2
mod_version=1.2.0

fabric_version=0.100.1+1.21
rei_version=16.0.729
architectury_version=13.0.1
emi_version=1.1.7+1.21
cloth_basic_math_version=0.6.1
cloth_config_version=15.0.127
jei_version=19.0.0.9
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
2 changes: 1 addition & 1 deletion gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package io.github.mattidragon.tlaapi.impl.jei;

import io.github.mattidragon.tlaapi.api.recipe.CategoryIcon;
import io.github.mattidragon.tlaapi.api.recipe.TlaIngredient;
import io.github.mattidragon.tlaapi.api.recipe.TlaStack;
import mezz.jei.api.constants.ModIds;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.fabric.constants.FabricTypes;
import mezz.jei.api.fabric.ingredients.fluids.IJeiFluidIngredient;
import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.helpers.IGuiHelper;
import mezz.jei.api.helpers.IJeiHelpers;
import mezz.jei.api.helpers.IPlatformFluidHelper;
import mezz.jei.api.ingredients.ITypedIngredient;
import mezz.jei.api.runtime.IIngredientManager;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;

import java.util.List;
import java.util.Optional;

public class JeiUtils {
public static final Identifier VANILLA_GUI_TEXTURE = Identifier.of(ModIds.JEI_ID, "textures/jei/gui/gui_vanilla.png");

public static Optional<? extends ITypedIngredient<?>> convertStack(IJeiHelpers helpers, TlaStack stack) {
var manager = helpers.getIngredientManager();
return switch (stack) {
case TlaStack.TlaFluidStack fluidStack -> createFluidIngredient(manager, helpers.getPlatformFluidHelper(), fluidStack);
case TlaStack.TlaItemStack itemStack -> manager.createTypedIngredient(VanillaTypes.ITEM_STACK, itemStack.toStack());
};
}

public static List<ITypedIngredient<?>> convertIngredient(IJeiHelpers helpers, TlaIngredient ingredient) {
return ingredient.getStacks()
.stream()
.map(stack -> convertStack(helpers, stack))
.<ITypedIngredient<?>>flatMap(Optional::stream)
.toList();
}

public static TlaStack convertStack(ITypedIngredient<?> stack) {
if (stack.getType() == VanillaTypes.ITEM_STACK) {
return TlaStack.of(((ItemStack) stack.getIngredient()));
} else if (stack.getType() == FabricTypes.FLUID_STACK) {
var ingredient = (IJeiFluidIngredient) stack.getIngredient();
return TlaStack.of(ingredient.getFluidVariant(), ingredient.getAmount());
} else {
return TlaStack.empty();
}
}

public static TlaIngredient convertIngredient(List<ITypedIngredient<?>> stacks) {
return TlaIngredient.ofStacks(stacks.stream().map(JeiUtils::convertStack).toList());
}

public static IDrawable iconToDrawable(IJeiHelpers helpers, CategoryIcon icon) {
return switch (icon) {
case CategoryIcon.StackIcon stackIcon ->
convertStack(helpers, stackIcon.stack())
.map(it -> getDrawableIngredient(helpers.getGuiHelper(), it))
.orElseGet(() -> helpers.getGuiHelper().createBlankDrawable(16, 16));
case CategoryIcon.TextureIcon textureIcon -> new TextureDrawable(textureIcon.texture());
};
}

private static <T> IDrawable getDrawableIngredient(IGuiHelper guiHelper, ITypedIngredient<T> converted) {
return guiHelper.createDrawableIngredient(converted.getType(), converted.getIngredient());
}

private static <F> Optional<ITypedIngredient<F>> createFluidIngredient(IIngredientManager manager, IPlatformFluidHelper<F> helper, TlaStack.TlaFluidStack stack) {
var variant = stack.getFluidVariant();
return manager.createTypedIngredient(
helper.getFluidIngredientType(),
helper.create(variant.getRegistryEntry(), stack.getAmount(), variant.getComponents())
);
}
}
Loading

0 comments on commit fa4ae97

Please sign in to comment.