Skip to content

Commit

Permalink
Add more helper methods for ICraftingGridHelper
Browse files Browse the repository at this point in the history
  • Loading branch information
mezz committed Sep 3, 2024
1 parent 7fea3d9 commit 0c9ff93
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import java.util.List;

import com.mojang.datafixers.util.Pair;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.builder.IRecipeSlotBuilder;
import mezz.jei.api.ingredients.IIngredientType;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.category.extensions.vanilla.crafting.ICraftingCategoryExtension;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeHolder;
import org.jetbrains.annotations.Nullable;

Expand All @@ -21,6 +23,22 @@
* to help them override the default behavior.
*/
public interface ICraftingGridHelper {
/**
* Create and place input ingredients onto the crafting grid in a consistent way.
* For shapeless recipes, use a width and height of 0.
*
* @since 19.16.2
*/
List<IRecipeSlotBuilder> createAndSetNamedIngredients(IRecipeLayoutBuilder builder, List<Pair<String, Ingredient>> namedIngredients, int width, int height);

/**
* Create and place input ingredients onto the crafting grid in a consistent way.
* For shapeless recipes, use a width and height of 0.
*
* @since 19.16.2
*/
void createAndSetIngredients(IRecipeLayoutBuilder builder, List<Ingredient> ingredients, int width, int height);

/**
* Create and place input ingredients onto the crafting grid in a consistent way.
* For shapeless recipes, use a width and height of 0.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package mezz.jei.library.gui.helpers;

import com.mojang.datafixers.util.Pair;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.builder.IRecipeSlotBuilder;
import mezz.jei.api.gui.ingredient.ICraftingGridHelper;
Expand All @@ -21,23 +22,43 @@ public class CraftingGridHelper implements ICraftingGridHelper {

private CraftingGridHelper() {}

@Override
public List<IRecipeSlotBuilder> createAndSetNamedIngredients(IRecipeLayoutBuilder builder, List<Pair<String, Ingredient>> namedIngredients, int width, int height) {
List<IRecipeSlotBuilder> inputSlots = createInputSlots(builder, width, height);
setNamedIngredients(inputSlots, namedIngredients, width, height);
return inputSlots;
}

@Override
public void createAndSetIngredients(IRecipeLayoutBuilder builder, List<Ingredient> ingredients, int width, int height) {
List<IRecipeSlotBuilder> inputSlots = createInputSlots(builder, width, height);
setIngredients(inputSlots, ingredients, width, height);
}

@Override
public <T> List<IRecipeSlotBuilder> createAndSetInputs(IRecipeLayoutBuilder builder, IIngredientType<T> ingredientType, List<@Nullable List<@Nullable T>> inputs, int width, int height) {
List<IRecipeSlotBuilder> inputSlots = createInputSlots(builder, width, height);
setInputs(inputSlots, ingredientType, inputs, width, height);
return inputSlots;
}

public void setIngredients(List<IRecipeSlotBuilder> slotBuilders, List<Ingredient> ingredients, int width, int height) {
if (width <= 0 || height <= 0) {
builder.setShapeless();
width = height = getShapelessSize(ingredients.size());
}

List<IRecipeSlotBuilder> inputSlots = new ArrayList<>();
for (int y = 0; y < 3; ++y) {
for (int x = 0; x < 3; ++x) {
IRecipeSlotBuilder slot = builder.addSlot(RecipeIngredientRole.INPUT, x * 18 + 1, y * 18 + 1);
inputSlots.add(slot);
}
if (slotBuilders.size() < width * height) {
throw new IllegalArgumentException(String.format("There are not enough slots (%s) to hold a recipe of this size. (%sx%s)", slotBuilders.size(), width, height));
}

setInputs(inputSlots, ingredientType, inputs, width, height);
for (int i = 0; i < ingredients.size(); i++) {
int index = getCraftingIndex(i, width, height);
IRecipeSlotBuilder slot = slotBuilders.get(index);

return inputSlots;
Ingredient ingredient = ingredients.get(i);
if (ingredient != null) {
slot.addIngredients(ingredient);
}
}
}

@Override
Expand Down Expand Up @@ -69,6 +90,41 @@ public <T> IRecipeSlotBuilder createAndSetOutputs(IRecipeLayoutBuilder builder,
return outputSlot;
}

private static List<IRecipeSlotBuilder> createInputSlots(IRecipeLayoutBuilder builder, int width, int height) {
if (width <= 0 || height <= 0) {
builder.setShapeless();
}

List<IRecipeSlotBuilder> inputSlots = new ArrayList<>();
for (int y = 0; y < 3; ++y) {
for (int x = 0; x < 3; ++x) {
IRecipeSlotBuilder slot = builder.addSlot(RecipeIngredientRole.INPUT, x * 18 + 1, y * 18 + 1);
inputSlots.add(slot);
}
}
return inputSlots;
}

private static void setNamedIngredients(List<IRecipeSlotBuilder> slotBuilders, List<Pair<String, Ingredient>> namedIngredients, int width, int height) {
if (width <= 0 || height <= 0) {
width = height = getShapelessSize(namedIngredients.size());
}
if (slotBuilders.size() < width * height) {
throw new IllegalArgumentException(String.format("There are not enough slots (%s) to hold a recipe of this size. (%sx%s)", slotBuilders.size(), width, height));
}

for (int i = 0; i < namedIngredients.size(); i++) {
int index = getCraftingIndex(i, width, height);
IRecipeSlotBuilder slot = slotBuilders.get(index);

Pair<String, Ingredient> value = namedIngredients.get(i);
if (value != null) {
slot.setSlotName(value.getFirst())
.addIngredients(value.getSecond());
}
}
}

public static Map<Integer, Ingredient> getGuiSlotToIngredientMap(RecipeHolder<CraftingRecipe> recipeHolder, int width, int height) {
CraftingRecipe recipe = recipeHolder.value();
NonNullList<Ingredient> ingredients = recipe.getIngredients();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,22 @@
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.RecipeHolder;
import net.minecraft.world.item.crafting.ShapedRecipe;

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

public class CraftingCategoryExtension implements ICraftingCategoryExtension<CraftingRecipe> {
@Override
public void setRecipe(RecipeHolder<CraftingRecipe> recipeHolder, IRecipeLayoutBuilder builder, ICraftingGridHelper craftingGridHelper, IFocusGroup focuses) {
CraftingRecipe recipe = recipeHolder.value();
List<List<ItemStack>> inputs = new ArrayList<>();
for (Ingredient ingredient : recipe.getIngredients()) {
List<ItemStack> items = List.of(ingredient.getItems());
inputs.add(items);
}
ItemStack resultItem = RecipeUtil.getResultItem(recipe);

int width = getWidth(recipeHolder);
int height = getHeight(recipeHolder);
craftingGridHelper.createAndSetOutputs(builder, List.of(resultItem));
craftingGridHelper.createAndSetInputs(builder, inputs, width, height);
craftingGridHelper.createAndSetIngredients(builder, recipe.getIngredients(), width, height);
}

@SuppressWarnings("removal")
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,4 @@ curseHomepageUrl=https://www.curseforge.com/minecraft/mc-mods/jei
jUnitVersion=5.8.2

# Version
specificationVersion=19.16.1
specificationVersion=19.16.2

0 comments on commit 0c9ff93

Please sign in to comment.