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 // i'll leave this here commented for easier testing
//runtimeOnly fg.deobf("vazkii.arl:AutoRegLib:1.4-35.69") //runtimeOnly fg.deobf("vazkii.arl:AutoRegLib:1.4-35.69")
//runtimeOnly fg.deobf("vazkii.quark:Quark:r2.0-212.984") //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.mantle:Mantle:1.16.5-1.6.103")
// runtimeOnly fg.deobf("slimeknights.tconstruct:TConstruct:1.16.3-3.0.1.24") //runtimeOnly fg.deobf("slimeknights.tconstruct:TConstruct:1.16.5-3.0.3.168")
annotationProcessor 'org.spongepowered:mixin:0.8:processor' annotationProcessor 'org.spongepowered:mixin:0.8:processor'
} }

View file

@ -1,8 +1,8 @@
package com.simibubi.create.compat.jei; package com.simibubi.create.compat.jei;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -81,12 +81,12 @@ public class CreateJEI implements IModPlugin {
} }
public IIngredientManager ingredientManager; public IIngredientManager ingredientManager;
final List<CreateRecipeCategory<?>> ALL = new ArrayList<>(); private final List<CreateRecipeCategory<?>> allCategories = new ArrayList<>();
final CreateRecipeCategory<?> private final CreateRecipeCategory<?>
milling = register("milling", MillingCategory::new).recipes(AllRecipeTypes.MILLING) milling = register("milling", MillingCategory::new).recipes(AllRecipeTypes.MILLING)
.catalyst(AllBlocks.MILLSTONE::get) .catalyst(AllBlocks.MILLSTONE::get)
.build(), .build(),
crushing = register("crushing", CrushingCategory::new).recipes(AllRecipeTypes.CRUSHING) crushing = register("crushing", CrushingCategory::new).recipes(AllRecipeTypes.CRUSHING)
.recipesExcluding(AllRecipeTypes.MILLING::getType, AllRecipeTypes.CRUSHING::getType) .recipesExcluding(AllRecipeTypes.MILLING::getType, AllRecipeTypes.CRUSHING::getType)
@ -106,7 +106,9 @@ public class CreateJEI implements IModPlugin {
.build(), .build(),
blasting = register("fan_blasting", FanBlastingCategory::new) 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")) .catalystStack(ProcessingViaFanCategory.getFan("fan_blasting"))
.build(), .build(),
@ -213,20 +215,21 @@ public class CreateJEI implements IModPlugin {
@Override @Override
public void registerCategories(IRecipeCategoryRegistration registration) { public void registerCategories(IRecipeCategoryRegistration registration) {
ALL.forEach(registration::addRecipeCategories); allCategories.forEach(registration::addRecipeCategories);
} }
@Override @Override
public void registerRecipes(IRecipeRegistration registration) { public void registerRecipes(IRecipeRegistration registration) {
ingredientManager = registration.getIngredientManager(); 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 @Override
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) { 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 @Override
public void registerGuiHandlers(IGuiHandlerRegistration registration) { public void registerGuiHandlers(IGuiHandlerRegistration registration) {
SlotMover slotMover = new SlotMover(); SlotMover slotMover = new SlotMover();
@ -239,98 +242,106 @@ public class CreateJEI implements IModPlugin {
} }
private class CategoryBuilder<T extends IRecipe<?>> { 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; 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 = category.get();
this.category.setCategoryId(name); this.category.setCategoryId(name);
this.pred = Predicates.alwaysTrue(); pred = Predicates.alwaysTrue();
} }
CategoryBuilder<T> catalyst(Supplier<IItemProvider> supplier) { public CategoryBuilder<T> recipes(AllRecipeTypes recipeTypeEntry) {
return catalystStack(() -> new ItemStack(supplier.get()
.asItem()));
}
CategoryBuilder<T> catalystStack(Supplier<ItemStack> supplier) {
category.recipeCatalysts.add(supplier);
return this;
}
CategoryBuilder<T> recipes(AllRecipeTypes recipeTypeEntry) {
return recipes(recipeTypeEntry::getType); 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()); return recipes(r -> r.getType() == recipeType.get());
} }
CategoryBuilder<T> recipes(ResourceLocation serializer) { public CategoryBuilder<T> recipes(ResourceLocation serializer) {
return recipes(r -> r.getSerializer() return recipes(r -> r.getSerializer()
.getRegistryName() .getRegistryName()
.equals(serializer)); .equals(serializer));
} }
CategoryBuilder<T> recipes(Predicate<IRecipe<?>> pred) { public CategoryBuilder<T> recipes(Predicate<IRecipe<?>> pred) {
return recipeList(() -> findRecipes(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); 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); return recipeList(list, null);
} }
CategoryBuilder<T> recipeList(Supplier<List<? extends IRecipe<?>>> list, Function<IRecipe<?>, T> converter) { public CategoryBuilder<T> recipeList(Supplier<List<? extends IRecipe<?>>> list, Function<IRecipe<?>, T> converter) {
category.recipes.add(() -> { recipeListConsumers.add(recipes -> {
if (!this.pred.test(AllConfigs.SERVER.recipes)) List<? extends IRecipe<?>> toAdd = list.get();
return Collections.emptyList();
if (converter != null) if (converter != null)
return list.get() toAdd = toAdd
.stream() .stream()
.map(converter) .map(converter)
.collect(Collectors.toList()); .collect(Collectors.toList());
return list.get(); recipes.addAll(toAdd);
}); });
return this; return this;
} }
CategoryBuilder<T> recipesExcluding(Supplier<IRecipeType<? extends T>> recipeType, public CategoryBuilder<T> recipesExcluding(Supplier<IRecipeType<? extends T>> recipeType,
Supplier<IRecipeType<? extends T>> excluded) { Supplier<IRecipeType<? extends T>> excluded) {
category.recipes.add(() -> { recipeListConsumers.add(recipes -> {
if (!this.pred.test(AllConfigs.SERVER.recipes)) recipes.addAll(findRecipesByTypeExcluding(recipeType.get(), excluded.get()));
return Collections.emptyList();
return findRecipesByTypeExcluding(recipeType.get(), excluded.get());
}); });
return this; return this;
} }
CategoryBuilder<T> enableWhen(Function<CRecipes, ConfigBool> configValue) { public CategoryBuilder<T> removeRecipes(Supplier<IRecipeType<? extends T>> recipeType) {
this.pred = c -> configValue.apply(c) 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(); .get();
return this; return this;
} }
CategoryBuilder<T> enableWhenBool(Function<CRecipes, Boolean> configValue) { public CategoryBuilder<T> enableWhenBool(Function<CRecipes, Boolean> configValue) {
this.pred = configValue::apply; pred = configValue::apply;
return this; return this;
} }
CreateRecipeCategory<T> build() { public CreateRecipeCategory<T> build() {
ALL.add(category); 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; return category;
} }
} }
static List<IRecipe<?>> findRecipesByType(IRecipeType<?> type) { public static List<IRecipe<?>> findRecipes(Predicate<IRecipe<?>> predicate) {
return findRecipes(r -> r.getType() == type);
}
static List<IRecipe<?>> findRecipes(Predicate<IRecipe<?>> predicate) {
return Minecraft.getInstance().world.getRecipeManager() return Minecraft.getInstance().world.getRecipeManager()
.getRecipes() .getRecipes()
.stream() .stream()
@ -338,24 +349,44 @@ public class CreateJEI implements IModPlugin {
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
static List<IRecipe<?>> findRecipesByTypeExcluding(IRecipeType<?> type, IRecipeType<?> excludingType) { public static List<IRecipe<?>> findRecipesByType(IRecipeType<?> type) {
List<IRecipe<?>> byType = findRecipes(r -> r.getType() == type); return findRecipes(recipe -> recipe.getType() == type);
List<IRecipe<?>> byExcludingType = findRecipes(r -> r.getType() == excludingType); }
byType.removeIf(recipe -> {
for (IRecipe<?> r : byExcludingType) { public static List<IRecipe<?>> findRecipesByTypeExcluding(IRecipeType<?> type, IRecipeType<?> excludingType) {
ItemStack[] matchingStacks = recipe.getIngredients() List<IRecipe<?>> byType = findRecipesByType(type);
.get(0) removeRecipesByType(byType, excludingType);
.getMatchingStacks();
if (matchingStacks.length == 0)
return true;
if (r.getIngredients()
.get(0)
.test(matchingStacks[0]))
return true;
}
return false;
});
return byType; 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 abstract class CreateRecipeCategory<T extends IRecipe<?>> implements IRecipeCategory<T> {
public List<Supplier<? extends Object>> recipeCatalysts = new ArrayList<>(); public final List<Supplier<List<? extends IRecipe<?>>>> recipes = new ArrayList<>();
public List<Supplier<List<? extends IRecipe<?>>>> recipes = new ArrayList<>(); public final List<Supplier<? extends Object>> recipeCatalysts = new ArrayList<>();
public ResourceLocation uid;
protected ResourceLocation uid;
protected String name; protected String name;
private IDrawable icon;
private IDrawable background; private IDrawable background;
private IDrawable icon;
public CreateRecipeCategory(IDrawable icon, IDrawable background) { public CreateRecipeCategory(IDrawable icon, IDrawable background) {
this.background = background; this.background = background;
@ -49,11 +49,6 @@ public abstract class CreateRecipeCategory<T extends IRecipe<?>> implements IRec
this.name = name; this.name = name;
} }
@Override
public IDrawable getIcon() {
return icon;
}
@Override @Override
public ResourceLocation getUid() { public ResourceLocation getUid() {
return uid; return uid;
@ -70,6 +65,11 @@ public abstract class CreateRecipeCategory<T extends IRecipe<?>> implements IRec
return background; return background;
} }
@Override
public IDrawable getIcon() {
return icon;
}
protected static AllGuiTextures getRenderedSlot(IRecipe<?> recipe, int index) { protected static AllGuiTextures getRenderedSlot(IRecipe<?> recipe, int index) {
AllGuiTextures jeiSlot = AllGuiTextures.JEI_SLOT; AllGuiTextures jeiSlot = AllGuiTextures.JEI_SLOT;
if (!(recipe instanceof ProcessingRecipe)) 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.ItemStack;
import net.minecraft.item.crafting.IRecipe; import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.math.vector.Vector3f; import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.util.text.TextFormatting;
public abstract class ProcessingViaFanCategory<T extends IRecipe<?>> extends CreateRecipeCategory<T> { 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) { public static Supplier<ItemStack> getFan(String name) {
return () -> AllBlocks.ENCASED_FAN.asStack() 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 @Override