[Feature] partial Integration with JEI
This commit is contained in:
parent
0c3a152caf
commit
d734b8b140
7 changed files with 439 additions and 2 deletions
|
@ -25,6 +25,8 @@ repositories {
|
|||
maven { url 'https://jitpack.io' }
|
||||
maven { url 'https://maven.terraformersmc.com/releases' }
|
||||
maven { url "https://ladysnake.jfrog.io/artifactory/mods" }
|
||||
maven { url = "https://dvs1.progwml6.com/files/maven/" }
|
||||
maven { url = "https://modmaven.dev" }
|
||||
flatDir {
|
||||
dirs 'libs'
|
||||
}
|
||||
|
@ -50,6 +52,12 @@ dependencies {
|
|||
modCompileOnly "me.shedaniel:RoughlyEnoughItems-fabric:${project.rei_version}"
|
||||
modCompileOnly "me.shedaniel:RoughlyEnoughItems-api-fabric:${project.rei_version}"
|
||||
|
||||
// compile against the JEI API but do not include it at runtime
|
||||
modCompileOnlyApi "mezz.jei:jei-${project.minecraft_version}-common-api:${project.jei_version}"
|
||||
modCompileOnlyApi "mezz.jei:jei-${project.minecraft_version}-fabric-api:${project.jei_version}"
|
||||
// at runtime, use the full JEI jar for Fabric
|
||||
modRuntimeOnly "mezz.jei:jei-${project.minecraft_version}-fabric:${project.jei_version}"
|
||||
|
||||
//needed for trinkets, otherwise BetterEnd would require users to install trinkets
|
||||
modApi "dev.onyxstudios.cardinal-components-api:cardinal-components-base:${project.cca_version}"
|
||||
modCompileOnly "dev.emi:trinkets:${project.trinkets_version}"
|
||||
|
|
|
@ -16,5 +16,6 @@ archives_base_name=better-end
|
|||
patchouli_version=1.19-73-FABRIC
|
||||
bclib_version=2.0.17
|
||||
rei_version=9.1.500
|
||||
jei_version=11.1.0.235
|
||||
trinkets_version=3.4.0
|
||||
cca_version=5.0.0-beta.1
|
||||
|
|
|
@ -275,7 +275,7 @@ public class EndStoneSmelterBlockEntity extends BaseContainerBlockEntity impleme
|
|||
}
|
||||
boolean accepted = blockEntity.canAcceptRecipeOutput(recipe);
|
||||
if (!burning && accepted) {
|
||||
blockEntity.burnTime = blockEntity.getFuelTime(fuel);
|
||||
blockEntity.burnTime = EndStoneSmelterBlockEntity.getFuelTime(fuel);
|
||||
blockEntity.fuelTime = blockEntity.burnTime;
|
||||
burning = blockEntity.isBurning();
|
||||
if (burning) {
|
||||
|
@ -419,7 +419,7 @@ public class EndStoneSmelterBlockEntity extends BaseContainerBlockEntity impleme
|
|||
return true;
|
||||
}
|
||||
|
||||
protected int getFuelTime(ItemStack fuel) {
|
||||
public static int getFuelTime(ItemStack fuel) {
|
||||
if (fuel.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,171 @@
|
|||
package org.betterx.betterend.integration.jei;
|
||||
|
||||
import org.betterx.betterend.BetterEnd;
|
||||
import org.betterx.betterend.recipe.builders.AlloyingRecipe;
|
||||
import org.betterx.betterend.registry.EndBlocks;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import mezz.jei.api.constants.ModIds;
|
||||
import mezz.jei.api.constants.VanillaTypes;
|
||||
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
|
||||
import mezz.jei.api.gui.drawable.IDrawable;
|
||||
import mezz.jei.api.gui.drawable.IDrawableAnimated;
|
||||
import mezz.jei.api.gui.drawable.IDrawableStatic;
|
||||
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
|
||||
import mezz.jei.api.helpers.IGuiHelper;
|
||||
import mezz.jei.api.recipe.IFocusGroup;
|
||||
import mezz.jei.api.recipe.RecipeIngredientRole;
|
||||
import mezz.jei.api.recipe.RecipeType;
|
||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
||||
|
||||
public class JEIAlloyingCategory implements IRecipeCategory<AlloyingRecipe> {
|
||||
public static final RecipeType TYPE = RecipeType.create(
|
||||
BetterEnd.MOD_ID,
|
||||
AlloyingRecipe.GROUP,
|
||||
AlloyingRecipe.class
|
||||
);
|
||||
public static final String TEXTURE_GUI_PATH = "textures/gui/";
|
||||
public static final String TEXTURE_GUI_VANILLA = TEXTURE_GUI_PATH + "gui_vanilla.png";
|
||||
public static final ResourceLocation RECIPE_GUI_VANILLA = new ResourceLocation(ModIds.JEI_ID, TEXTURE_GUI_VANILLA);
|
||||
public static final int width = 116;
|
||||
public static final int height = 54;
|
||||
|
||||
protected final IDrawableStatic staticFlame;
|
||||
protected final IDrawableStatic addonSlot;
|
||||
protected final IDrawableAnimated animatedFlame;
|
||||
|
||||
private final IDrawable background;
|
||||
private final IDrawable icon;
|
||||
private final Component title;
|
||||
private final LoadingCache<Integer, IDrawableAnimated> cachedArrows;
|
||||
|
||||
public JEIAlloyingCategory(IGuiHelper guiHelper) {
|
||||
staticFlame = guiHelper.createDrawable(RECIPE_GUI_VANILLA, 82, 114, 14, 14);
|
||||
animatedFlame = guiHelper.createAnimatedDrawable(staticFlame, 300, IDrawableAnimated.StartDirection.TOP, true);
|
||||
background = guiHelper.createDrawable(RECIPE_GUI_VANILLA, 0, 114, 82, 54);
|
||||
title = Component.translatable(EndBlocks.END_STONE_SMELTER.getDescriptionId());
|
||||
icon = guiHelper.createDrawableIngredient(VanillaTypes.ITEM_STACK, new ItemStack(EndBlocks.END_STONE_SMELTER));
|
||||
this.cachedArrows = CacheBuilder.newBuilder()
|
||||
.maximumSize(25)
|
||||
.build(new CacheLoader<>() {
|
||||
@Override
|
||||
public IDrawableAnimated load(Integer cookTime) {
|
||||
return guiHelper.drawableBuilder(
|
||||
RECIPE_GUI_VANILLA,
|
||||
82,
|
||||
128,
|
||||
24,
|
||||
17
|
||||
)
|
||||
.buildAnimated(
|
||||
cookTime,
|
||||
IDrawableAnimated.StartDirection.LEFT,
|
||||
false
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
addonSlot = guiHelper.getSlotDrawable();
|
||||
}
|
||||
|
||||
protected IDrawableAnimated getArrow(AlloyingRecipe recipe) {
|
||||
int cookTime = recipe.getSmeltTime();
|
||||
if (cookTime <= 0) {
|
||||
cookTime = 0;
|
||||
}
|
||||
return this.cachedArrows.getUnchecked(cookTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType<AlloyingRecipe> getRecipeType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDrawable getBackground() {
|
||||
return background;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDrawable getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRecipe(IRecipeLayoutBuilder builder, AlloyingRecipe recipe, IFocusGroup focuses) {
|
||||
builder.addSlot(RecipeIngredientRole.INPUT, 1, 1)
|
||||
.addIngredients(recipe.getIngredients().get(0));
|
||||
|
||||
if (recipe.getIngredients().size() > 1) {
|
||||
builder.addSlot(RecipeIngredientRole.INPUT, 21, 1)
|
||||
.addIngredients(recipe.getIngredients().get(1));
|
||||
}
|
||||
|
||||
builder.addSlot(RecipeIngredientRole.OUTPUT, 61, 19)
|
||||
.addItemStack(recipe.getResultItem());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHandled(AlloyingRecipe recipe) {
|
||||
return !recipe.isSpecial();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(
|
||||
AlloyingRecipe recipe,
|
||||
IRecipeSlotsView recipeSlotsView,
|
||||
PoseStack poseStack,
|
||||
double mouseX,
|
||||
double mouseY
|
||||
) {
|
||||
animatedFlame.draw(poseStack, 1, 20);
|
||||
|
||||
if (recipe.getIngredients().size() > 1) {
|
||||
addonSlot.draw(poseStack, 20, 0);
|
||||
}
|
||||
|
||||
IDrawableAnimated arrow = getArrow(recipe);
|
||||
arrow.draw(poseStack, 24, 18);
|
||||
|
||||
drawExperience(recipe, poseStack, 0);
|
||||
drawCookTime(recipe, poseStack, 45);
|
||||
|
||||
}
|
||||
|
||||
protected void drawExperience(AlloyingRecipe recipe, PoseStack poseStack, int y) {
|
||||
float experience = recipe.getExperience();
|
||||
if (experience > 0) {
|
||||
Component experienceString = Component.translatable("gui.jei.category.smelting.experience", experience);
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
Font fontRenderer = minecraft.font;
|
||||
int stringWidth = fontRenderer.width(experienceString);
|
||||
fontRenderer.draw(poseStack, experienceString, background.getWidth() - stringWidth, y, 0xFF808080);
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawCookTime(AlloyingRecipe recipe, PoseStack poseStack, int y) {
|
||||
int cookTime = recipe.getSmeltTime();
|
||||
if (cookTime > 0) {
|
||||
int cookTimeSeconds = cookTime / 20;
|
||||
Component timeString = Component.translatable("gui.jei.category.smelting.time.seconds", cookTimeSeconds);
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
net.minecraft.client.gui.Font fontRenderer = minecraft.font;
|
||||
int stringWidth = fontRenderer.width(timeString);
|
||||
fontRenderer.draw(poseStack, timeString, background.getWidth() - stringWidth, y, 0xFF808080);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
package org.betterx.betterend.integration.jei;
|
||||
|
||||
import org.betterx.betterend.BetterEnd;
|
||||
import org.betterx.betterend.blocks.entities.EndStoneSmelterBlockEntity;
|
||||
import org.betterx.betterend.recipe.builders.AlloyingRecipe;
|
||||
import org.betterx.betterend.registry.EndBlocks;
|
||||
import org.betterx.ui.layout.values.Rectangle;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Font;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import mezz.jei.api.constants.VanillaTypes;
|
||||
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
|
||||
import mezz.jei.api.gui.drawable.IDrawable;
|
||||
import mezz.jei.api.gui.drawable.IDrawableAnimated;
|
||||
import mezz.jei.api.gui.drawable.IDrawableStatic;
|
||||
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
|
||||
import mezz.jei.api.helpers.IGuiHelper;
|
||||
import mezz.jei.api.recipe.IFocusGroup;
|
||||
import mezz.jei.api.recipe.RecipeIngredientRole;
|
||||
import mezz.jei.api.recipe.RecipeType;
|
||||
import mezz.jei.api.recipe.category.IRecipeCategory;
|
||||
import mezz.jei.api.recipe.vanilla.IJeiFuelingRecipe;
|
||||
import mezz.jei.api.runtime.IIngredientManager;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
|
||||
|
||||
public class JEIAlloyingFuelCategory implements IRecipeCategory<IJeiFuelingRecipe> {
|
||||
public static final RecipeType FUEL_TYPE = RecipeType.create(
|
||||
BetterEnd.MOD_ID,
|
||||
AlloyingRecipe.GROUP + "_fuel",
|
||||
IJeiFuelingRecipe.class
|
||||
);
|
||||
|
||||
private final IDrawableStatic background;
|
||||
private final IDrawable icon;
|
||||
private final Component localizedName;
|
||||
private final LoadingCache<Integer, IDrawableAnimated> cachedFlames;
|
||||
private final Rectangle textArea;
|
||||
|
||||
public static List<IJeiFuelingRecipe> getFuelRecipes(IIngredientManager ingredientManager) {
|
||||
return ingredientManager.getAllIngredients(VanillaTypes.ITEM_STACK).stream()
|
||||
.<IJeiFuelingRecipe>mapMulti((stack, consumer) -> {
|
||||
if (EndStoneSmelterBlockEntity.canUseAsFuel(stack)) {
|
||||
final int time = EndStoneSmelterBlockEntity.getFuelTime(stack);
|
||||
if (time > 0) {
|
||||
final List<ItemStack> inputs = List.of(stack);
|
||||
consumer.accept(new IJeiFuelingRecipe() {
|
||||
@Override
|
||||
public @Unmodifiable List<ItemStack> getInputs() {
|
||||
return inputs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBurnTime() {
|
||||
return time;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
.sorted(Comparator.comparingInt(IJeiFuelingRecipe::getBurnTime))
|
||||
.toList();
|
||||
}
|
||||
|
||||
public JEIAlloyingFuelCategory(IGuiHelper guiHelper) {
|
||||
|
||||
// width of the recipe depends on the text, which is different in each language
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
Font fontRenderer = minecraft.font;
|
||||
Component maxSmeltCountText = createSmeltCountText(10000000 * 200);
|
||||
int maxStringWidth = fontRenderer.width(maxSmeltCountText.getString());
|
||||
int backgroundHeight = 34;
|
||||
int textPadding = 20;
|
||||
|
||||
background = guiHelper.drawableBuilder(JEIAlloyingCategory.RECIPE_GUI_VANILLA, 0, 134, 18, backgroundHeight)
|
||||
.addPadding(0, 0, 0, textPadding + maxStringWidth)
|
||||
.build();
|
||||
|
||||
textArea = new Rectangle(20, 0, textPadding + maxStringWidth, backgroundHeight);
|
||||
|
||||
icon = guiHelper.createDrawableIngredient(
|
||||
VanillaTypes.ITEM_STACK,
|
||||
new ItemStack(EndBlocks.END_STONE_SMELTER)
|
||||
);
|
||||
;
|
||||
localizedName = Component.translatable("gui.jei.category.fuel");
|
||||
|
||||
this.cachedFlames = CacheBuilder.newBuilder()
|
||||
.maximumSize(25)
|
||||
.build(new CacheLoader<>() {
|
||||
@Override
|
||||
public IDrawableAnimated load(Integer burnTime) {
|
||||
return guiHelper.drawableBuilder(
|
||||
JEIAlloyingCategory.RECIPE_GUI_VANILLA,
|
||||
82,
|
||||
114,
|
||||
14,
|
||||
14
|
||||
)
|
||||
.buildAnimated(
|
||||
burnTime,
|
||||
IDrawableAnimated.StartDirection.TOP,
|
||||
true
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDrawable getBackground() {
|
||||
return background;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType<IJeiFuelingRecipe> getRecipeType() {
|
||||
return FUEL_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getTitle() {
|
||||
return localizedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDrawable getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRecipe(IRecipeLayoutBuilder builder, IJeiFuelingRecipe recipe, IFocusGroup focuses) {
|
||||
builder.addSlot(RecipeIngredientRole.INPUT, 1, 17)
|
||||
.addItemStacks(recipe.getInputs());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(
|
||||
IJeiFuelingRecipe recipe,
|
||||
IRecipeSlotsView recipeSlotsView,
|
||||
PoseStack poseStack,
|
||||
double mouseX,
|
||||
double mouseY
|
||||
) {
|
||||
int burnTime = recipe.getBurnTime();
|
||||
IDrawableAnimated flame = cachedFlames.getUnchecked(burnTime);
|
||||
flame.draw(poseStack, 1, 0);
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
Font font = minecraft.font;
|
||||
Component smeltCountText = createSmeltCountText(burnTime);
|
||||
int width = font.width(smeltCountText);
|
||||
int height = font.lineHeight;
|
||||
|
||||
font.draw(
|
||||
poseStack,
|
||||
smeltCountText,
|
||||
this.textArea.left + (this.textArea.width - width) / 2,
|
||||
this.textArea.top + (this.textArea.height - height) / 2 + 1,
|
||||
0xFF808080
|
||||
);
|
||||
}
|
||||
|
||||
private static Component createSmeltCountText(int burnTime) {
|
||||
if (burnTime == 200) {
|
||||
return Component.translatable("gui.jei.category.fuel.smeltCount.single");
|
||||
} else {
|
||||
NumberFormat numberInstance = NumberFormat.getNumberInstance();
|
||||
numberInstance.setMaximumFractionDigits(2);
|
||||
String smeltCount = numberInstance.format(burnTime / 200f);
|
||||
return Component.translatable("gui.jei.category.fuel.smeltCount", smeltCount);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package org.betterx.betterend.integration.jei;
|
||||
|
||||
import org.betterx.betterend.BetterEnd;
|
||||
import org.betterx.betterend.recipe.builders.AlloyingRecipe;
|
||||
import org.betterx.betterend.registry.EndBlocks;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
import mezz.jei.api.IModPlugin;
|
||||
import mezz.jei.api.helpers.IGuiHelper;
|
||||
import mezz.jei.api.helpers.IJeiHelpers;
|
||||
import mezz.jei.api.registration.IRecipeCatalystRegistration;
|
||||
import mezz.jei.api.registration.IRecipeCategoryRegistration;
|
||||
import mezz.jei.api.registration.IRecipeRegistration;
|
||||
import mezz.jei.api.registration.IRecipeTransferRegistration;
|
||||
import mezz.jei.api.runtime.IIngredientManager;
|
||||
|
||||
public class JEIPlugin implements IModPlugin {
|
||||
public final static ResourceLocation PLUGIN_ID = BetterEnd.makeID("jei_plugin");
|
||||
|
||||
|
||||
@Override
|
||||
public ResourceLocation getPluginUid() {
|
||||
return PLUGIN_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerCategories(IRecipeCategoryRegistration registration) {
|
||||
IModPlugin.super.registerCategories(registration);
|
||||
|
||||
IJeiHelpers jeiHelpers = registration.getJeiHelpers();
|
||||
IGuiHelper guiHelper = jeiHelpers.getGuiHelper();
|
||||
|
||||
registration.addRecipeCategories(new JEIAlloyingCategory(guiHelper));
|
||||
registration.addRecipeCategories(new JEIAlloyingFuelCategory(guiHelper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipes(IRecipeRegistration registration) {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
ClientLevel world = minecraft.level;
|
||||
var recipeManager = world.getRecipeManager();
|
||||
IIngredientManager ingredientManager = registration.getIngredientManager();
|
||||
|
||||
IModPlugin.super.registerRecipes(registration);
|
||||
registration.addRecipes(JEIAlloyingCategory.TYPE, recipeManager.getAllRecipesFor(AlloyingRecipe.TYPE));
|
||||
registration.addRecipes(
|
||||
JEIAlloyingFuelCategory.FUEL_TYPE,
|
||||
JEIAlloyingFuelCategory.getFuelRecipes(ingredientManager)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
|
||||
IModPlugin.super.registerRecipeCatalysts(registration);
|
||||
registration.addRecipeCatalyst(
|
||||
new ItemStack(EndBlocks.END_STONE_SMELTER),
|
||||
JEIAlloyingCategory.TYPE,
|
||||
JEIAlloyingFuelCategory.FUEL_TYPE
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRecipeTransferHandlers(IRecipeTransferRegistration registration) {
|
||||
IModPlugin.super.registerRecipeTransferHandlers(registration);
|
||||
|
||||
}
|
||||
}
|
|
@ -30,6 +30,9 @@
|
|||
],
|
||||
"rei_client": [
|
||||
"org.betterx.betterend.integration.rei.REIPlugin"
|
||||
],
|
||||
"jei_mod_plugin": [
|
||||
"org.betterx.betterend.integration.jei.JEIPlugin"
|
||||
]
|
||||
},
|
||||
"accessWidener": "betterend.accesswidener",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue