JEI Fixes

- Fix #1661: blasting-only recipes would not be shown under the bulk blasting category
- Add ability to remove matching recipes by type while using the category builder
- Fix fan catalyst items being italicized
- Add and tweak some visibility modifiers
This commit is contained in:
PepperBell 2021-05-28 23:10:12 -07:00
parent 5975a3cbac
commit 9235aa93ba
4 changed files with 111 additions and 81 deletions

View File

@ -130,8 +130,8 @@ dependencies {
// i'll leave this here commented for easier testing
//runtimeOnly fg.deobf("vazkii.arl:AutoRegLib:1.4-35.69")
//runtimeOnly fg.deobf("vazkii.quark:Quark:r2.0-212.984")
// runtimeOnly fg.deobf("slimeknights.mantle:Mantle:1.16.3-1.6.40")
// runtimeOnly fg.deobf("slimeknights.tconstruct:TConstruct:1.16.3-3.0.1.24")
//runtimeOnly fg.deobf("slimeknights.mantle:Mantle:1.16.5-1.6.103")
//runtimeOnly fg.deobf("slimeknights.tconstruct:TConstruct:1.16.5-3.0.3.168")
annotationProcessor 'org.spongepowered:mixin:0.8:processor'
}

View File

@ -1,8 +1,8 @@
package com.simibubi.create.compat.jei;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
@ -81,12 +81,12 @@ public class CreateJEI implements IModPlugin {
}
public IIngredientManager ingredientManager;
final List<CreateRecipeCategory<?>> ALL = new ArrayList<>();
final CreateRecipeCategory<?>
private final List<CreateRecipeCategory<?>> allCategories = new ArrayList<>();
private final CreateRecipeCategory<?>
milling = register("milling", MillingCategory::new).recipes(AllRecipeTypes.MILLING)
.catalyst(AllBlocks.MILLSTONE::get)
.build(),
milling = register("milling", MillingCategory::new).recipes(AllRecipeTypes.MILLING)
.catalyst(AllBlocks.MILLSTONE::get)
.build(),
crushing = register("crushing", CrushingCategory::new).recipes(AllRecipeTypes.CRUSHING)
.recipesExcluding(AllRecipeTypes.MILLING::getType, AllRecipeTypes.CRUSHING::getType)
@ -106,7 +106,9 @@ public class CreateJEI implements IModPlugin {
.build(),
blasting = register("fan_blasting", FanBlastingCategory::new)
.recipesExcluding(() -> IRecipeType.SMELTING, () -> IRecipeType.SMOKING)
.recipesExcluding(() -> IRecipeType.SMELTING, () -> IRecipeType.BLASTING)
.recipes(() -> IRecipeType.BLASTING)
.removeRecipes(() -> IRecipeType.SMOKING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_blasting"))
.build(),
@ -213,20 +215,21 @@ public class CreateJEI implements IModPlugin {
@Override
public void registerCategories(IRecipeCategoryRegistration registration) {
ALL.forEach(registration::addRecipeCategories);
allCategories.forEach(registration::addRecipeCategories);
}
@Override
public void registerRecipes(IRecipeRegistration registration) {
ingredientManager = registration.getIngredientManager();
ALL.forEach(c -> c.recipes.forEach(s -> registration.addRecipes(s.get(), c.getUid())));
allCategories.forEach(c -> c.recipes.forEach(s -> registration.addRecipes(s.get(), c.getUid())));
}
@Override
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
ALL.forEach(c -> c.recipeCatalysts.forEach(s -> registration.addRecipeCatalyst(s.get(), c.getUid())));
allCategories.forEach(c -> c.recipeCatalysts.forEach(s -> registration.addRecipeCatalyst(s.get(), c.getUid())));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void registerGuiHandlers(IGuiHandlerRegistration registration) {
SlotMover slotMover = new SlotMover();
@ -239,98 +242,106 @@ public class CreateJEI implements IModPlugin {
}
private class CategoryBuilder<T extends IRecipe<?>> {
CreateRecipeCategory<T> category;
private CreateRecipeCategory<T> category;
private List<Consumer<List<IRecipe<?>>>> recipeListConsumers = new ArrayList<>();
private Predicate<CRecipes> pred;
CategoryBuilder(String name, Supplier<CreateRecipeCategory<T>> category) {
public CategoryBuilder(String name, Supplier<CreateRecipeCategory<T>> category) {
this.category = category.get();
this.category.setCategoryId(name);
this.pred = Predicates.alwaysTrue();
pred = Predicates.alwaysTrue();
}
CategoryBuilder<T> catalyst(Supplier<IItemProvider> supplier) {
return catalystStack(() -> new ItemStack(supplier.get()
.asItem()));
}
CategoryBuilder<T> catalystStack(Supplier<ItemStack> supplier) {
category.recipeCatalysts.add(supplier);
return this;
}
CategoryBuilder<T> recipes(AllRecipeTypes recipeTypeEntry) {
public CategoryBuilder<T> recipes(AllRecipeTypes recipeTypeEntry) {
return recipes(recipeTypeEntry::getType);
}
CategoryBuilder<T> recipes(Supplier<IRecipeType<T>> recipeType) {
public CategoryBuilder<T> recipes(Supplier<IRecipeType<? extends T>> recipeType) {
return recipes(r -> r.getType() == recipeType.get());
}
CategoryBuilder<T> recipes(ResourceLocation serializer) {
public CategoryBuilder<T> recipes(ResourceLocation serializer) {
return recipes(r -> r.getSerializer()
.getRegistryName()
.equals(serializer));
}
CategoryBuilder<T> recipes(Predicate<IRecipe<?>> pred) {
public CategoryBuilder<T> recipes(Predicate<IRecipe<?>> pred) {
return recipeList(() -> findRecipes(pred));
}
CategoryBuilder<T> recipes(Predicate<IRecipe<?>> pred, Function<IRecipe<?>, T> converter) {
public CategoryBuilder<T> recipes(Predicate<IRecipe<?>> pred, Function<IRecipe<?>, T> converter) {
return recipeList(() -> findRecipes(pred), converter);
}
CategoryBuilder<T> recipeList(Supplier<List<? extends IRecipe<?>>> list) {
public CategoryBuilder<T> recipeList(Supplier<List<? extends IRecipe<?>>> list) {
return recipeList(list, null);
}
CategoryBuilder<T> recipeList(Supplier<List<? extends IRecipe<?>>> list, Function<IRecipe<?>, T> converter) {
category.recipes.add(() -> {
if (!this.pred.test(AllConfigs.SERVER.recipes))
return Collections.emptyList();
public CategoryBuilder<T> recipeList(Supplier<List<? extends IRecipe<?>>> list, Function<IRecipe<?>, T> converter) {
recipeListConsumers.add(recipes -> {
List<? extends IRecipe<?>> toAdd = list.get();
if (converter != null)
return list.get()
toAdd = toAdd
.stream()
.map(converter)
.collect(Collectors.toList());
return list.get();
recipes.addAll(toAdd);
});
return this;
}
CategoryBuilder<T> recipesExcluding(Supplier<IRecipeType<? extends T>> recipeType,
public CategoryBuilder<T> recipesExcluding(Supplier<IRecipeType<? extends T>> recipeType,
Supplier<IRecipeType<? extends T>> excluded) {
category.recipes.add(() -> {
if (!this.pred.test(AllConfigs.SERVER.recipes))
return Collections.emptyList();
return findRecipesByTypeExcluding(recipeType.get(), excluded.get());
recipeListConsumers.add(recipes -> {
recipes.addAll(findRecipesByTypeExcluding(recipeType.get(), excluded.get()));
});
return this;
}
CategoryBuilder<T> enableWhen(Function<CRecipes, ConfigBool> configValue) {
this.pred = c -> configValue.apply(c)
public CategoryBuilder<T> removeRecipes(Supplier<IRecipeType<? extends T>> recipeType) {
recipeListConsumers.add(recipes -> {
removeRecipesByType(recipes, recipeType.get());
});
return this;
}
public CategoryBuilder<T> catalyst(Supplier<IItemProvider> supplier) {
return catalystStack(() -> new ItemStack(supplier.get()
.asItem()));
}
public CategoryBuilder<T> catalystStack(Supplier<ItemStack> supplier) {
category.recipeCatalysts.add(supplier);
return this;
}
public CategoryBuilder<T> enableWhen(Function<CRecipes, ConfigBool> configValue) {
pred = c -> configValue.apply(c)
.get();
return this;
}
CategoryBuilder<T> enableWhenBool(Function<CRecipes, Boolean> configValue) {
this.pred = configValue::apply;
public CategoryBuilder<T> enableWhenBool(Function<CRecipes, Boolean> configValue) {
pred = configValue::apply;
return this;
}
CreateRecipeCategory<T> build() {
ALL.add(category);
public CreateRecipeCategory<T> build() {
if (pred.test(AllConfigs.SERVER.recipes))
category.recipes.add(() -> {
List<IRecipe<?>> recipes = new ArrayList<>();
for (Consumer<List<IRecipe<?>>> consumer : recipeListConsumers)
consumer.accept(recipes);
return recipes;
});
allCategories.add(category);
return category;
}
}
static List<IRecipe<?>> findRecipesByType(IRecipeType<?> type) {
return findRecipes(r -> r.getType() == type);
}
static List<IRecipe<?>> findRecipes(Predicate<IRecipe<?>> predicate) {
public static List<IRecipe<?>> findRecipes(Predicate<IRecipe<?>> predicate) {
return Minecraft.getInstance().world.getRecipeManager()
.getRecipes()
.stream()
@ -338,24 +349,44 @@ public class CreateJEI implements IModPlugin {
.collect(Collectors.toList());
}
static List<IRecipe<?>> findRecipesByTypeExcluding(IRecipeType<?> type, IRecipeType<?> excludingType) {
List<IRecipe<?>> byType = findRecipes(r -> r.getType() == type);
List<IRecipe<?>> byExcludingType = findRecipes(r -> r.getType() == excludingType);
byType.removeIf(recipe -> {
for (IRecipe<?> r : byExcludingType) {
ItemStack[] matchingStacks = recipe.getIngredients()
.get(0)
.getMatchingStacks();
if (matchingStacks.length == 0)
return true;
if (r.getIngredients()
.get(0)
.test(matchingStacks[0]))
return true;
}
return false;
});
public static List<IRecipe<?>> findRecipesByType(IRecipeType<?> type) {
return findRecipes(recipe -> recipe.getType() == type);
}
public static List<IRecipe<?>> findRecipesByTypeExcluding(IRecipeType<?> type, IRecipeType<?> excludingType) {
List<IRecipe<?>> byType = findRecipesByType(type);
removeRecipesByType(byType, excludingType);
return byType;
}
public static List<IRecipe<?>> findRecipesByTypeExcluding(IRecipeType<?> type, IRecipeType<?>... excludingTypes) {
List<IRecipe<?>> byType = findRecipesByType(type);
for (IRecipeType<?> excludingType : excludingTypes)
removeRecipesByType(byType, excludingType);
return byType;
}
public static void removeRecipesByType(List<IRecipe<?>> recipes, IRecipeType<?> type) {
List<IRecipe<?>> byType = findRecipesByType(type);
recipes.removeIf(recipe -> {
for (IRecipe<?> r : byType)
if (doInputsMatch(recipe, r))
return true;
return false;
});
}
public static boolean doInputsMatch(IRecipe<?> recipe1, IRecipe<?> recipe2) {
ItemStack[] matchingStacks = recipe1.getIngredients()
.get(0)
.getMatchingStacks();
if (matchingStacks.length == 0)
return true;
if (recipe2.getIngredients()
.get(0)
.test(matchingStacks[0]))
return true;
return false;
}
}

View File

@ -31,13 +31,13 @@ import net.minecraftforge.fluids.FluidStack;
public abstract class CreateRecipeCategory<T extends IRecipe<?>> implements IRecipeCategory<T> {
public List<Supplier<? extends Object>> recipeCatalysts = new ArrayList<>();
public List<Supplier<List<? extends IRecipe<?>>>> recipes = new ArrayList<>();
public ResourceLocation uid;
public final List<Supplier<List<? extends IRecipe<?>>>> recipes = new ArrayList<>();
public final List<Supplier<? extends Object>> recipeCatalysts = new ArrayList<>();
protected ResourceLocation uid;
protected String name;
private IDrawable icon;
private IDrawable background;
private IDrawable icon;
public CreateRecipeCategory(IDrawable icon, IDrawable background) {
this.background = background;
@ -49,11 +49,6 @@ public abstract class CreateRecipeCategory<T extends IRecipe<?>> implements IRec
this.name = name;
}
@Override
public IDrawable getIcon() {
return icon;
}
@Override
public ResourceLocation getUid() {
return uid;
@ -70,6 +65,11 @@ public abstract class CreateRecipeCategory<T extends IRecipe<?>> implements IRec
return background;
}
@Override
public IDrawable getIcon() {
return icon;
}
protected static AllGuiTextures getRenderedSlot(IRecipe<?> recipe, int index) {
AllGuiTextures jeiSlot = AllGuiTextures.JEI_SLOT;
if (!(recipe instanceof ProcessingRecipe))

View File

@ -21,7 +21,6 @@ import mezz.jei.api.ingredients.IIngredients;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.util.text.TextFormatting;
public abstract class ProcessingViaFanCategory<T extends IRecipe<?>> extends CreateRecipeCategory<T> {
@ -41,7 +40,7 @@ public abstract class ProcessingViaFanCategory<T extends IRecipe<?>> extends Cre
public static Supplier<ItemStack> getFan(String name) {
return () -> AllBlocks.ENCASED_FAN.asStack()
.setDisplayName(Lang.translate("recipe." + name + ".fan").formatted(TextFormatting.RESET));
.setDisplayName(Lang.translate("recipe." + name + ".fan").styled(style -> style.withItalic(false)));
}
@Override