Just Enough API

- replace (most?) calls to deprecated JEI-API features
- improve rotation for the /c u angle command
This commit is contained in:
zelophed 2022-07-04 13:25:21 +02:00
parent 9b9e252bac
commit 2fb3081da7
26 changed files with 771 additions and 966 deletions

View file

@ -1,38 +1,40 @@
package com.simibubi.create.compat.jei;
import javax.annotation.ParametersAreNonnullByDefault;
import org.jetbrains.annotations.Nullable;
import com.simibubi.create.content.curiosities.tools.BlueprintAssignCompleteRecipePacket;
import com.simibubi.create.content.curiosities.tools.BlueprintContainer;
import com.simibubi.create.foundation.networking.AllPackets;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.transfer.IRecipeTransferError;
import mezz.jei.api.recipe.transfer.IRecipeTransferHandler;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.CraftingRecipe;
@SuppressWarnings("rawtypes")
public class BlueprintTransferHandler implements IRecipeTransferHandler<BlueprintContainer, Recipe> {
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class BlueprintTransferHandler implements IRecipeTransferHandler<BlueprintContainer, CraftingRecipe> {
@Override
public Class<BlueprintContainer> getContainerClass() {
return BlueprintContainer.class;
}
@Override
public Class<Recipe> getRecipeClass() {
return Recipe.class;
public Class<CraftingRecipe> getRecipeClass() {
return CraftingRecipe.class;
}
@Override
public IRecipeTransferError transferRecipe(BlueprintContainer container, Recipe recipe,
IRecipeLayout recipeLayout, Player player, boolean maxTransfer, boolean doTransfer) {
if (!(recipe instanceof Recipe))
return null;
public @Nullable IRecipeTransferError transferRecipe(BlueprintContainer container, CraftingRecipe craftingRecipe, IRecipeSlotsView recipeSlots, Player player, boolean maxTransfer, boolean doTransfer) {
if (!doTransfer)
return null;
Recipe<?> iRecipe = (Recipe<?>) recipe;
// Continued server-side in BlueprintItem.assignCompleteRecipe()
AllPackets.channel.sendToServer(new BlueprintAssignCompleteRecipePacket(iRecipe.getId()));
AllPackets.channel.sendToServer(new BlueprintAssignCompleteRecipePacket(craftingRecipe.getId()));
return null;
}

View file

@ -8,11 +8,10 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import com.google.common.base.Predicates;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllFluids;
import com.simibubi.create.AllItems;
@ -61,7 +60,7 @@ import com.simibubi.create.foundation.utility.recipe.IRecipeTypeInfo;
import mezz.jei.api.IModPlugin;
import mezz.jei.api.JeiPlugin;
import mezz.jei.api.constants.VanillaRecipeCategoryUid;
import mezz.jei.api.constants.RecipeTypes;
import mezz.jei.api.recipe.category.IRecipeCategory;
import mezz.jei.api.registration.IGuiHandlerRegistration;
import mezz.jei.api.registration.IRecipeCatalystRegistration;
@ -83,6 +82,7 @@ import net.minecraftforge.fml.ModList;
@JeiPlugin
@SuppressWarnings("unused")
@ParametersAreNonnullByDefault
public class CreateJEI implements IModPlugin {
private static final ResourceLocation ID = Create.asResource("jei_plugin");
@ -94,154 +94,154 @@ public class CreateJEI implements IModPlugin {
allCategories.clear();
CreateRecipeCategory<?>
milling = register("milling", MillingCategory::new).addTypedRecipes(AllRecipeTypes.MILLING)
.catalyst(AllBlocks.MILLSTONE::get)
.build(),
milling = register("milling", MillingCategory::new)
.addTypedRecipes(AllRecipeTypes.MILLING)
.catalyst(AllBlocks.MILLSTONE::get)
.build(),
crushing = register("crushing", CrushingCategory::new).addTypedRecipes(AllRecipeTypes.CRUSHING)
.addTypedRecipesExcluding(AllRecipeTypes.MILLING::getType, AllRecipeTypes.CRUSHING::getType)
.catalyst(AllBlocks.CRUSHING_WHEEL::get)
.build(),
crushing = register("crushing", CrushingCategory::new)
.addTypedRecipes(AllRecipeTypes.CRUSHING)
.addTypedRecipesExcluding(AllRecipeTypes.MILLING::getType, AllRecipeTypes.CRUSHING::getType)
.catalyst(AllBlocks.CRUSHING_WHEEL::get)
.build(),
pressing = register("pressing", PressingCategory::new).addTypedRecipes(AllRecipeTypes.PRESSING)
.catalyst(AllBlocks.MECHANICAL_PRESS::get)
.build(),
pressing = register("pressing", PressingCategory::new)
.addTypedRecipes(AllRecipeTypes.PRESSING)
.catalyst(AllBlocks.MECHANICAL_PRESS::get)
.build(),
washing = register("fan_washing", FanWashingCategory::new).addTypedRecipes(AllRecipeTypes.SPLASHING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_washing"))
.build(),
washing = register("fan_washing", FanWashingCategory::new)
.addTypedRecipes(AllRecipeTypes.SPLASHING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_washing"))
.build(),
smoking = register("fan_smoking", FanSmokingCategory::new).addTypedRecipes(() -> RecipeType.SMOKING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_smoking"))
.build(),
smoking = register("fan_smoking", FanSmokingCategory::new)
.addTypedRecipes(() -> RecipeType.SMOKING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_smoking"))
.build(),
blasting = register("fan_blasting", FanBlastingCategory::new)
.addTypedRecipesExcluding(() -> RecipeType.SMELTING, () -> RecipeType.BLASTING)
.addTypedRecipes(() -> RecipeType.BLASTING)
.removeRecipes(() -> RecipeType.SMOKING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_blasting"))
.build(),
blasting = register("fan_blasting", FanBlastingCategory::new)
.addTypedRecipesExcluding(() -> RecipeType.SMELTING, () -> RecipeType.BLASTING)
.addTypedRecipes(() -> RecipeType.BLASTING)
.removeRecipes(() -> RecipeType.SMOKING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_blasting"))
.build(),
haunting = register("fan_haunting", FanHauntingCategory::new).addTypedRecipes(AllRecipeTypes.HAUNTING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_haunting"))
.build(),
haunting = register("fan_haunting", FanHauntingCategory::new).addTypedRecipes(AllRecipeTypes.HAUNTING)
.catalystStack(ProcessingViaFanCategory.getFan("fan_haunting"))
.build(),
mixing = register("mixing", MixingCategory::standard).addTypedRecipes(AllRecipeTypes.MIXING)
.catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get)
.build(),
mixing = register("mixing", MixingCategory::standard).addTypedRecipes(AllRecipeTypes.MIXING)
.catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get)
.build(),
seqAssembly = register("sequenced_assembly", SequencedAssemblyCategory::new)
.addTypedRecipes(AllRecipeTypes.SEQUENCED_ASSEMBLY)
.build(),
seqAssembly = register("sequenced_assembly", SequencedAssemblyCategory::new)
.addTypedRecipes(AllRecipeTypes.SEQUENCED_ASSEMBLY)
.build(),
autoShapeless = register("automatic_shapeless", MixingCategory::autoShapeless)
.addAllRecipesIf(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>)
&& r.getIngredients()
.size() > 1
&& !MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.shouldIgnoreInAutomation(r),
BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get)
.enableWhen(c -> c.allowShapelessInMixer)
.build(),
autoShapeless = register("automatic_shapeless", MixingCategory::autoShapeless)
.addAllRecipesIf(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>)
&& r.getIngredients()
.size() > 1
&& !MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.shouldIgnoreInAutomation(r),
BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get)
.enableWhen(c -> c.allowShapelessInMixer)
.build(),
brewing =
register("automatic_brewing", MixingCategory::autoBrewing).addRecipes(() -> PotionMixingRecipes.ALL)
.catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get)
.build(),
brewing = register("automatic_brewing", MixingCategory::autoBrewing).addRecipes(() -> PotionMixingRecipes.ALL)
.catalyst(AllBlocks.MECHANICAL_MIXER::get)
.catalyst(AllBlocks.BASIN::get)
.build(),
sawing = register("sawing", SawingCategory::new).addTypedRecipes(AllRecipeTypes.CUTTING)
.catalyst(AllBlocks.MECHANICAL_SAW::get)
.build(),
sawing = register("sawing", SawingCategory::new).addTypedRecipes(AllRecipeTypes.CUTTING)
.catalyst(AllBlocks.MECHANICAL_SAW::get)
.build(),
blockCutting =
register("block_cutting", () -> new BlockCuttingCategory(Items.STONE_BRICK_STAIRS))
.addRecipes(() -> CondensedBlockCuttingRecipe.condenseRecipes(getTypedRecipesExcluding(
RecipeType.STONECUTTING, recipe -> AllRecipeTypes.shouldIgnoreInAutomation(recipe))))
.catalyst(AllBlocks.MECHANICAL_SAW::get)
.enableWhen(c -> c.allowStonecuttingOnSaw)
.build(),
blockCutting = register("block_cutting", () -> new BlockCuttingCategory(Items.STONE_BRICK_STAIRS))
.addRecipes(() -> CondensedBlockCuttingRecipe.condenseRecipes(getTypedRecipesExcluding(RecipeType.STONECUTTING, AllRecipeTypes::shouldIgnoreInAutomation)))
.catalyst(AllBlocks.MECHANICAL_SAW::get)
.enableWhen(c -> c.allowStonecuttingOnSaw)
.build(),
woodCutting = register("wood_cutting", () -> new BlockCuttingCategory(Items.OAK_STAIRS))
.addRecipes(() -> CondensedBlockCuttingRecipe
.condenseRecipes(getTypedRecipesExcluding(SawTileEntity.woodcuttingRecipeType.get(),
recipe -> AllRecipeTypes.shouldIgnoreInAutomation(recipe))))
.catalyst(AllBlocks.MECHANICAL_SAW::get)
.enableWhenBool(c -> c.allowWoodcuttingOnSaw.get() && ModList.get()
.isLoaded("druidcraft"))
.build(),
woodCutting = register("wood_cutting", () -> new BlockCuttingCategory(Items.OAK_STAIRS))
.addRecipes(() -> CondensedBlockCuttingRecipe.condenseRecipes(getTypedRecipesExcluding(SawTileEntity.woodcuttingRecipeType.get(), AllRecipeTypes::shouldIgnoreInAutomation)))
.catalyst(AllBlocks.MECHANICAL_SAW::get)
.enableWhenBool(c -> c.allowWoodcuttingOnSaw.get() && ModList.get()
.isLoaded("druidcraft"))
.build(),
packing = register("packing", PackingCategory::standard).addTypedRecipes(AllRecipeTypes.COMPACTING)
.catalyst(AllBlocks.MECHANICAL_PRESS::get)
.catalyst(AllBlocks.BASIN::get)
.build(),
packing = register("packing", PackingCategory::standard).addTypedRecipes(AllRecipeTypes.COMPACTING)
.catalyst(AllBlocks.MECHANICAL_PRESS::get)
.catalyst(AllBlocks.BASIN::get)
.build(),
autoSquare = register("automatic_packing", PackingCategory::autoSquare)
.addAllRecipesIf(
r -> (r instanceof CraftingRecipe) && !(r instanceof MechanicalCraftingRecipe)
&& MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.shouldIgnoreInAutomation(r),
BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_PRESS::get)
.catalyst(AllBlocks.BASIN::get)
.enableWhen(c -> c.allowShapedSquareInPress)
.build(),
autoSquare = register("automatic_packing", PackingCategory::autoSquare)
.addAllRecipesIf(
r -> (r instanceof CraftingRecipe) && !(r instanceof MechanicalCraftingRecipe)
&& MechanicalPressTileEntity.canCompress(r) && !AllRecipeTypes.shouldIgnoreInAutomation(r),
BasinRecipe::convertShapeless)
.catalyst(AllBlocks.MECHANICAL_PRESS::get)
.catalyst(AllBlocks.BASIN::get)
.enableWhen(c -> c.allowShapedSquareInPress)
.build(),
polishing = register("sandpaper_polishing", PolishingCategory::new)
.addTypedRecipes(AllRecipeTypes.SANDPAPER_POLISHING)
.catalyst(AllItems.SAND_PAPER::get)
.catalyst(AllItems.RED_SAND_PAPER::get)
.build(),
polishing = register("sandpaper_polishing", PolishingCategory::new)
.addTypedRecipes(AllRecipeTypes.SANDPAPER_POLISHING)
.catalyst(AllItems.SAND_PAPER::get)
.catalyst(AllItems.RED_SAND_PAPER::get)
.build(),
item_application = register("item_application", ItemApplicationCategory::new)
.addTypedRecipes(AllRecipeTypes.ITEM_APPLICATION)
.addRecipes(LogStrippingFakeRecipes::createRecipes)
.build(),
item_application = register("item_application", ItemApplicationCategory::new)
.addTypedRecipes(AllRecipeTypes.ITEM_APPLICATION)
.addRecipes(LogStrippingFakeRecipes::createRecipes)
.build(),
deploying = register("deploying", DeployingCategory::new).addTypedRecipes(AllRecipeTypes.DEPLOYING)
.addTypedRecipes(AllRecipeTypes.SANDPAPER_POLISHING::getType, DeployerApplicationRecipe::convert)
.addTypedRecipes(AllRecipeTypes.ITEM_APPLICATION::getType, ManualApplicationRecipe::asDeploying)
.catalyst(AllBlocks.DEPLOYER::get)
.catalyst(AllBlocks.DEPOT::get)
.catalyst(AllItems.BELT_CONNECTOR::get)
.build(),
deploying = register("deploying", DeployingCategory::new).addTypedRecipes(AllRecipeTypes.DEPLOYING)
.addTypedRecipes(AllRecipeTypes.SANDPAPER_POLISHING::getType, DeployerApplicationRecipe::convert)
.addTypedRecipes(AllRecipeTypes.ITEM_APPLICATION::getType, ManualApplicationRecipe::asDeploying)
.catalyst(AllBlocks.DEPLOYER::get)
.catalyst(AllBlocks.DEPOT::get)
.catalyst(AllItems.BELT_CONNECTOR::get)
.build(),
mysteryConversion = register("mystery_conversion", MysteriousItemConversionCategory::new)
.addRecipes(() -> MysteriousItemConversionCategory.RECIPES)
.build(),
mysteryConversion = register("mystery_conversion", MysteriousItemConversionCategory::new)
.addRecipes(() -> MysteriousItemConversionCategory.RECIPES)
.build(),
spoutFilling = register("spout_filling", SpoutCategory::new).addTypedRecipes(AllRecipeTypes.FILLING)
.addRecipeListConsumer(recipes -> SpoutCategory.consumeRecipes(recipes::add, ingredientManager))
.catalyst(AllBlocks.SPOUT::get)
.build(),
spoutFilling = register("spout_filling", SpoutCategory::new).addTypedRecipes(AllRecipeTypes.FILLING)
.addRecipeListConsumer(recipes -> SpoutCategory.consumeRecipes(recipes::add, ingredientManager))
.catalyst(AllBlocks.SPOUT::get)
.build(),
draining = register("draining", ItemDrainCategory::new)
.addRecipeListConsumer(recipes -> ItemDrainCategory.consumeRecipes(recipes::add, ingredientManager))
.addTypedRecipes(AllRecipeTypes.EMPTYING)
.catalyst(AllBlocks.ITEM_DRAIN::get)
.build(),
draining = register("draining", ItemDrainCategory::new)
.addRecipeListConsumer(recipes -> ItemDrainCategory.consumeRecipes(recipes::add, ingredientManager))
.addTypedRecipes(AllRecipeTypes.EMPTYING)
.catalyst(AllBlocks.ITEM_DRAIN::get)
.build(),
autoShaped = register("automatic_shaped", MechanicalCraftingCategory::new)
.addAllRecipesIf(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>)
&& r.getIngredients()
.size() == 1
&& !AllRecipeTypes.shouldIgnoreInAutomation(r))
.addTypedRecipesIf(() -> RecipeType.CRAFTING,
recipe -> recipe instanceof IShapedRecipe<?> && !AllRecipeTypes.shouldIgnoreInAutomation(recipe))
.catalyst(AllBlocks.MECHANICAL_CRAFTER::get)
.enableWhen(c -> c.allowRegularCraftingInCrafter)
.build(),
autoShaped = register("automatic_shaped", MechanicalCraftingCategory::new)
.addAllRecipesIf(r -> r instanceof CraftingRecipe && !(r instanceof IShapedRecipe<?>)
&& r.getIngredients()
.size() == 1
&& !AllRecipeTypes.shouldIgnoreInAutomation(r))
.addTypedRecipesIf(() -> RecipeType.CRAFTING,
recipe -> recipe instanceof IShapedRecipe<?> && !AllRecipeTypes.shouldIgnoreInAutomation(recipe))
.catalyst(AllBlocks.MECHANICAL_CRAFTER::get)
.enableWhen(c -> c.allowRegularCraftingInCrafter)
.build(),
mechanicalCrafting = register("mechanical_crafting", MechanicalCraftingCategory::new)
.addTypedRecipes(AllRecipeTypes.MECHANICAL_CRAFTING)
.catalyst(AllBlocks.MECHANICAL_CRAFTER::get)
.build();
mechanicalCrafting = register("mechanical_crafting", MechanicalCraftingCategory::new)
.addTypedRecipes(AllRecipeTypes.MECHANICAL_CRAFTING)
.catalyst(AllBlocks.MECHANICAL_CRAFTER::get)
.build();
}
private <T extends Recipe<?>> CategoryBuilder<T> register(String name, Supplier<CreateRecipeCategory<T>> supplier) {
return new CategoryBuilder<T>(name, supplier);
return new CategoryBuilder<>(name, supplier);
}
@Override
@ -252,7 +252,7 @@ public class CreateJEI implements IModPlugin {
@Override
public void registerRecipeTransferHandlers(IRecipeTransferRegistration registration) {
registration.addRecipeTransferHandler(new BlueprintTransferHandler(), VanillaRecipeCategoryUid.CRAFTING);
registration.addRecipeTransferHandler(new BlueprintTransferHandler(), RecipeTypes.CRAFTING);
}
@Override
@ -272,15 +272,15 @@ public class CreateJEI implements IModPlugin {
@Override
public void registerRecipes(IRecipeRegistration registration) {
ingredientManager = registration.getIngredientManager();
allCategories.forEach(c -> c.recipes.forEach(s -> registration.addRecipes(s.get(), c.getUid())));
registration.addRecipes(ToolboxColoringRecipeMaker.createRecipes()
.collect(Collectors.toList()), VanillaRecipeCategoryUid.CRAFTING);
allCategories.forEach(c -> c.registerRecipes(registration));
registration.addRecipes(RecipeTypes.CRAFTING, ToolboxColoringRecipeMaker.createRecipes().toList());
}
@Override
public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) {
allCategories.forEach(c -> c.recipeCatalysts.forEach(s -> registration.addRecipeCatalyst(s.get(), c.getUid())));
allCategories.forEach(c -> c.recipeCatalysts.forEach(s -> registration.addRecipeCatalyst(s.get(), c.getRecipeType())));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@ -295,29 +295,30 @@ public class CreateJEI implements IModPlugin {
}
private class CategoryBuilder<T extends Recipe<?>> {
private CreateRecipeCategory<T> category;
private List<Consumer<List<Recipe<?>>>> recipeListConsumers = new ArrayList<>();
private Predicate<CRecipes> pred;
private final CreateRecipeCategory<T> category;
private final List<Consumer<List<T>>> recipeListConsumers = new ArrayList<>();
private Predicate<CRecipes> predicate;
public CategoryBuilder(String name, Supplier<CreateRecipeCategory<T>> category) {
this.category = category.get();
this.category.setCategoryId(name);
pred = Predicates.alwaysTrue();
mezz.jei.api.recipe.RecipeType<T> recipeType = this.category.getRecipeType();
predicate = cRecipes -> true;
}
public CategoryBuilder<T> addRecipeListConsumer(Consumer<List<Recipe<?>>> consumer) {
public CategoryBuilder<T> addRecipeListConsumer(Consumer<List<T>> consumer) {
recipeListConsumers.add(consumer);
return this;
}
public CategoryBuilder<T> addRecipes(Supplier<Collection<? extends Recipe<?>>> collection) {
public CategoryBuilder<T> addRecipes(Supplier<Collection<? extends T>> collection) {
return addRecipeListConsumer(recipes -> recipes.addAll(collection.get()));
}
public CategoryBuilder<T> addAllRecipesIf(Predicate<Recipe<?>> pred) {
return addRecipeListConsumer(recipes -> consumeAllRecipes(recipe -> {
if (pred.test(recipe)) {
recipes.add(recipe);
recipes.add((T) recipe);
}
}));
}
@ -335,19 +336,15 @@ public class CreateJEI implements IModPlugin {
}
public CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<? extends T>> recipeType) {
return addRecipeListConsumer(recipes -> consumeTypedRecipes(recipes::add, recipeType.get()));
return addRecipeListConsumer(recipes -> CreateJEI.<T>consumeTypedRecipes(recipes::add, recipeType.get()));
}
public CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<? extends T>> recipeType,
Function<Recipe<?>, T> converter) {
return addRecipeListConsumer(recipes -> consumeTypedRecipes(recipe -> {
recipes.add(converter.apply(recipe));
}, recipeType.get()));
public CategoryBuilder<T> addTypedRecipes(Supplier<RecipeType<? extends T>> recipeType, Function<Recipe<?>, T> converter) {
return addRecipeListConsumer(recipes -> CreateJEI.<T>consumeTypedRecipes(recipe -> recipes.add(converter.apply(recipe)), recipeType.get()));
}
public CategoryBuilder<T> addTypedRecipesIf(Supplier<RecipeType<? extends T>> recipeType,
Predicate<Recipe<?>> pred) {
return addRecipeListConsumer(recipes -> consumeTypedRecipes(recipe -> {
public CategoryBuilder<T> addTypedRecipesIf(Supplier<RecipeType<? extends T>> recipeType, Predicate<Recipe<?>> pred) {
return addRecipeListConsumer(recipes -> CreateJEI.<T>consumeTypedRecipes(recipe -> {
if (pred.test(recipe)) {
recipes.add(recipe);
}
@ -358,7 +355,7 @@ public class CreateJEI implements IModPlugin {
Supplier<RecipeType<? extends T>> excluded) {
return addRecipeListConsumer(recipes -> {
List<Recipe<?>> excludedRecipes = getTypedRecipes(excluded.get());
consumeTypedRecipes(recipe -> {
CreateJEI.<T>consumeTypedRecipes(recipe -> {
for (Recipe<?> excludedRecipe : excludedRecipes) {
if (doInputsMatch(recipe, excludedRecipe)) {
return;
@ -394,21 +391,20 @@ public class CreateJEI implements IModPlugin {
}
public CategoryBuilder<T> enableWhen(Function<CRecipes, ConfigBool> configValue) {
pred = c -> configValue.apply(c)
.get();
predicate = c -> configValue.apply(c).get();
return this;
}
public CategoryBuilder<T> enableWhenBool(Function<CRecipes, Boolean> configValue) {
pred = configValue::apply;
predicate = configValue::apply;
return this;
}
public CreateRecipeCategory<T> build() {
if (pred.test(AllConfigs.SERVER.recipes))
if (predicate.test(AllConfigs.SERVER.recipes))
category.recipes.add(() -> {
List<Recipe<?>> recipes = new ArrayList<>();
for (Consumer<List<Recipe<?>>> consumer : recipeListConsumers)
List<T> recipes = new ArrayList<>();
for (Consumer<List<T>> consumer : recipeListConsumers)
consumer.accept(recipes);
return recipes;
});
@ -426,13 +422,12 @@ public class CreateJEI implements IModPlugin {
.forEach(consumer);
}
public static void consumeTypedRecipes(Consumer<Recipe<?>> consumer, RecipeType<?> type) {
public static <T extends Recipe<?>> void consumeTypedRecipes(Consumer<T> consumer, RecipeType<?> type) {
Map<ResourceLocation, Recipe<?>> map = Minecraft.getInstance()
.getConnection()
.getRecipeManager().recipes.get(type);
if (map != null) {
map.values()
.forEach(consumer);
map.values().forEach(recipe -> consumer.accept((T) recipe));
}
}
@ -461,11 +456,9 @@ public class CreateJEI implements IModPlugin {
if (matchingStacks.length == 0) {
return false;
}
if (recipe2.getIngredients()
.get(0)
.test(matchingStacks[0]))
return true;
return false;
return recipe2.getIngredients()
.get(0)
.test(matchingStacks[0]);
}
}

View file

@ -2,7 +2,8 @@ package com.simibubi.create.compat.jei.category;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang3.mutable.MutableInt;
@ -11,6 +12,7 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.content.contraptions.processing.BasinRecipe;
import com.simibubi.create.content.contraptions.processing.HeatCondition;
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
import com.simibubi.create.foundation.fluid.FluidIngredient;
import com.simibubi.create.foundation.gui.AllGuiTextures;
@ -19,20 +21,20 @@ import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.Pair;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.gui.ingredient.IGuiFluidStackGroup;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.client.Minecraft;
import net.minecraft.core.NonNullList;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraftforge.fluids.FluidStack;
@ParametersAreNonnullByDefault
public class BasinCategory extends CreateRecipeCategory<BasinRecipe> {
private boolean needsHeating;
private final boolean needsHeating;
public BasinCategory(boolean needsHeating, IDrawable icon, IDrawable background) {
super(icon, background);
@ -45,140 +47,97 @@ public class BasinCategory extends CreateRecipeCategory<BasinRecipe> {
}
@Override
public void setIngredients(BasinRecipe recipe, IIngredients ingredients) {
List<Ingredient> itemIngredients = new ArrayList<>(recipe.getIngredients());
public void setRecipe(IRecipeLayoutBuilder builder, BasinRecipe recipe, IFocusGroup focuses) {
List<Pair<Ingredient, MutableInt>> condensedIngredients = ItemHelper.condenseIngredients(recipe.getIngredients());
HeatCondition requiredHeat = recipe.getRequiredHeat();
if (!requiredHeat.testBlazeBurner(HeatLevel.NONE))
itemIngredients.add(Ingredient.of(AllBlocks.BLAZE_BURNER.get()));
if (!requiredHeat.testBlazeBurner(HeatLevel.KINDLED))
itemIngredients.add(Ingredient.of(AllItems.BLAZE_CAKE.get()));
ingredients.setInputIngredients(itemIngredients);
ingredients.setInputLists(VanillaTypes.FLUID, recipe.getFluidIngredients()
.stream()
.map(FluidIngredient::getMatchingFluidStacks)
.collect(Collectors.toList()));
if (!recipe.getRollableResults()
.isEmpty())
ingredients.setOutput(VanillaTypes.ITEM, recipe.getResultItem());
if (!recipe.getFluidResults()
.isEmpty())
ingredients.setOutputs(VanillaTypes.FLUID, recipe.getFluidResults());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, BasinRecipe recipe, IIngredients iingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
IGuiFluidStackGroup fluidStacks = recipeLayout.getFluidStacks();
NonNullList<FluidIngredient> fluidIngredients = recipe.getFluidIngredients();
List<Pair<Ingredient, MutableInt>> ingredients = ItemHelper.condenseIngredients(recipe.getIngredients());
List<ItemStack> itemOutputs = recipe.getRollableResultsAsItemStacks();
NonNullList<FluidStack> fluidOutputs = recipe.getFluidResults();
int size = ingredients.size() + fluidIngredients.size();
int size = condensedIngredients.size() + recipe.getFluidIngredients().size();
int xOffset = size < 3 ? (3 - size) * 19 / 2 : 0;
int yOffset = 0;
int i = 0;
int i;
for (i = 0; i < ingredients.size(); i++) {
itemStacks.init(i, true, 16 + xOffset + (i % 3) * 19, 50 - (i / 3) * 19 + yOffset);
for (Pair<Ingredient, MutableInt> pair : condensedIngredients) {
List<ItemStack> stacks = new ArrayList<>();
Pair<Ingredient, MutableInt> pair = ingredients.get(i);
Ingredient ingredient = pair.getFirst();
MutableInt amount = pair.getSecond();
for (ItemStack itemStack : ingredient.getItems()) {
ItemStack stack = itemStack.copy();
stack.setCount(amount.getValue());
stacks.add(stack);
for (ItemStack itemStack : pair.getFirst().getItems()) {
ItemStack copy = itemStack.copy();
copy.setCount(pair.getSecond().getValue());
stacks.add(copy);
}
itemStacks.set(i, stacks);
builder
.addSlot(RecipeIngredientRole.INPUT, 17 + xOffset + (i % 3) * 19, 51 - (i / 3) * 19)
.setBackground(getRenderedSlot(), -1, -1)
.addItemStacks(stacks);
i++;
}
for (FluidIngredient fluidIngredient : recipe.getFluidIngredients()) {
builder
.addSlot(RecipeIngredientRole.INPUT, 17 + xOffset + (i % 3) * 19, 51 - (i / 3) * 19)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(VanillaTypes.FLUID, withImprovedVisibility(fluidIngredient.getMatchingFluidStacks()))
.addTooltipCallback(addFluidTooltip(fluidIngredient.getRequiredAmount()));
i++;
}
int j;
for (j = 0; j < fluidIngredients.size(); j++) {
int i2 = i + j;
fluidStacks.init(j, true, 17 + xOffset + (i2 % 3) * 19, 51 - (i2 / 3) * 19 + yOffset);
List<FluidStack> stacks = fluidIngredients.get(j)
.getMatchingFluidStacks();
fluidStacks.set(j, withImprovedVisibility(stacks));
size = recipe.getRollableResults().size() + recipe.getFluidResults().size();
i = 0;
for (ProcessingOutput result : recipe.getRollableResults()) {
int xPosition = 142 - (size % 2 != 0 && i == size - 1 ? 0 : i % 2 == 0 ? 10 : -9);
int yPosition = -19 * (i / 2) + 51;
builder
.addSlot(RecipeIngredientRole.OUTPUT, xPosition, yPosition)
.setBackground(getRenderedSlot(result), -1, -1)
.addItemStack(result.getStack())
.addTooltipCallback(addStochasticTooltip(result));
i++;
}
int outSize = fluidOutputs.size() + recipe.getRollableResults()
.size();
int outputIndex = 0;
if (!itemOutputs.isEmpty())
addStochasticTooltip(itemStacks, recipe.getRollableResults(), i);
for (; outputIndex < outSize; outputIndex++) {
int xPosition = 141 - (outSize % 2 != 0 && outputIndex == outSize - 1 ? 0 : outputIndex % 2 == 0 ? 10 : -9);
int yPosition = -19 * (outputIndex / 2) + 50 + yOffset;
for (FluidStack fluidResult : recipe.getFluidResults()) {
int xPosition = 142 - (size % 2 != 0 && i == size - 1 ? 0 : i % 2 == 0 ? 10 : -9);
int yPosition = -19 * (i / 2) + 51;
if (itemOutputs.size() > outputIndex) {
itemStacks.init(i, false, xPosition, yPosition + yOffset);
itemStacks.set(i, itemOutputs.get(outputIndex));
i++;
} else {
fluidStacks.init(j, false, xPosition + 1, yPosition + 1 + yOffset);
fluidStacks.set(j, withImprovedVisibility(fluidOutputs.get(outputIndex - itemOutputs.size())));
j++;
}
builder
.addSlot(RecipeIngredientRole.OUTPUT, xPosition, yPosition)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredient(VanillaTypes.FLUID, withImprovedVisibility(fluidResult))
.addTooltipCallback(addFluidTooltip(fluidResult.getAmount()));
i++;
}
addFluidTooltip(fluidStacks, fluidIngredients, fluidOutputs);
HeatCondition requiredHeat = recipe.getRequiredHeat();
if (!requiredHeat.testBlazeBurner(HeatLevel.NONE)) {
itemStacks.init(i, true, 133, 80);
itemStacks.set(i, AllBlocks.BLAZE_BURNER.asStack());
i++;
builder
.addSlot(RecipeIngredientRole.RENDER_ONLY, 134, 81)
.addItemStack(AllBlocks.BLAZE_BURNER.asStack());
}
if (!requiredHeat.testBlazeBurner(HeatLevel.KINDLED)) {
itemStacks.init(i, true, 152, 80);
itemStacks.set(i, AllItems.BLAZE_CAKE.asStack());
i++;
builder
.addSlot(RecipeIngredientRole.CATALYST, 153, 81)
.addItemStack(AllItems.BLAZE_CAKE.asStack());
}
}
@Override
public void draw(BasinRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
List<Pair<Ingredient, MutableInt>> actualIngredients = ItemHelper.condenseIngredients(recipe.getIngredients());
int size = actualIngredients.size() + recipe.getFluidIngredients()
.size();
int outSize = recipe.getFluidResults().size() + recipe.getRollableResults().size();
int xOffset = size < 3 ? (3 - size) * 19 / 2 : 0;
public void draw(BasinRecipe recipe, IRecipeSlotsView recipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
HeatCondition requiredHeat = recipe.getRequiredHeat();
int yOffset = 0;
for (int i = 0; i < size; i++)
AllGuiTextures.JEI_SLOT.render(matrixStack, 16 + xOffset + (i % 3) * 19, 50 - (i / 3) * 19 + yOffset);
boolean noHeat = requiredHeat == HeatCondition.NONE;
int vRows = (1 + outSize) / 2;
for (int i = 0; i < outSize; i++)
AllGuiTextures.JEI_SLOT.render(matrixStack,
141 - (outSize % 2 != 0 && i == outSize - 1 ? 0 : i % 2 == 0 ? 10 : -9), -19 * (i / 2) + 50 + yOffset);
int vRows = (1 + recipe.getFluidResults().size() + recipe.getRollableResults().size()) / 2;
if (vRows <= 2)
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 136, -19 * (vRows - 1) + 32 + yOffset);
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 136, -19 * (vRows - 1) + 32);
AllGuiTextures shadow = noHeat ? AllGuiTextures.JEI_SHADOW : AllGuiTextures.JEI_LIGHT;
shadow.render(matrixStack, 81, 58 + (noHeat ? 10 : 30));
if (!needsHeating)
return;
AllGuiTextures heatBar = noHeat ? AllGuiTextures.JEI_NO_HEAT_BAR : AllGuiTextures.JEI_HEAT_BAR;
heatBar.render(matrixStack, 4, 80);
Minecraft.getInstance().font.draw(matrixStack, Lang.translate(requiredHeat.getTranslationKey()), 9,
86, requiredHeat.getColor());
86, requiredHeat.getColor());
}
}

View file

@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.compat.jei.category.BlockCuttingCategory.CondensedBlockCuttingRecipe;
@ -11,10 +13,10 @@ import com.simibubi.create.compat.jei.category.animations.AnimatedSaw;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.item.ItemHelper;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
@ -22,9 +24,10 @@ import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.StonecutterRecipe;
@ParametersAreNonnullByDefault
public class BlockCuttingCategory extends CreateRecipeCategory<CondensedBlockCuttingRecipe> {
private AnimatedSaw saw = new AnimatedSaw();
private final AnimatedSaw saw = new AnimatedSaw();
public BlockCuttingCategory(Item symbol) {
super(doubleItemIcon(AllBlocks.MECHANICAL_SAW.get(), symbol), emptyBackground(177, 70)); // Items.STONE_BRICK_STAIRS
@ -34,38 +37,31 @@ public class BlockCuttingCategory extends CreateRecipeCategory<CondensedBlockCut
public Class<? extends CondensedBlockCuttingRecipe> getRecipeClass() {
return CondensedBlockCuttingRecipe.class;
}
@Override
public void setIngredients(CondensedBlockCuttingRecipe recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setOutputs(VanillaTypes.ITEM, recipe.getOutputs());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, CondensedBlockCuttingRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
itemStacks.init(0, true, 4, 4);
itemStacks.set(0, Arrays.asList(recipe.getIngredients().get(0).getItems()));
public void setRecipe(IRecipeLayoutBuilder builder, CondensedBlockCuttingRecipe recipe, IFocusGroup focuses) {
List<List<ItemStack>> results = recipe.getCondensedOutputs();
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++) {
int xOffset = (outputIndex % 5) * 19;
int yOffset = (outputIndex / 5) * -19;
itemStacks.init(outputIndex + 1, false, 77 + xOffset, 47 + yOffset);
itemStacks.set(outputIndex + 1, results.get(outputIndex));
builder
.addSlot(RecipeIngredientRole.INPUT, 5, 5)
.setBackground(getRenderedSlot(), -1 , -1)
.addItemStacks(Arrays.asList(recipe.getIngredients().get(0).getItems()));
int i = 0;
for (List<ItemStack> itemStacks : results) {
int xPos = 78 + (i % 5) * 19;
int yPos = 48 + (i / 5) * -19;
builder
.addSlot(RecipeIngredientRole.OUTPUT, xPos, yPos)
.setBackground(getRenderedSlot(), -1 , -1)
.addItemStacks(itemStacks);
i++;
}
}
@Override
public void draw(CondensedBlockCuttingRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SLOT.render(matrixStack, 4, 4);
int size = Math.min(recipe.getOutputs().size(), 15);
for (int i = 0; i < size; i++) {
int xOffset = (i % 5) * 19;
int yOffset = (i / 5) * -19;
AllGuiTextures.JEI_SLOT.render(matrixStack, 77 + xOffset, 47 + yOffset);
}
public void draw(CondensedBlockCuttingRecipe recipe, IRecipeSlotsView recipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 31, 6);
AllGuiTextures.JEI_SHADOW.render(matrixStack, 33 - 17, 37 + 13);
saw.draw(matrixStack, 33, 37);

View file

@ -2,26 +2,32 @@ package com.simibubi.create.compat.jei.category;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import javax.annotation.ParametersAreNonnullByDefault;
import org.jetbrains.annotations.NotNull;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllFluids;
import com.simibubi.create.Create;
import com.simibubi.create.compat.jei.DoubleItemIcon;
import com.simibubi.create.compat.jei.EmptyBackground;
import com.simibubi.create.content.contraptions.fluids.potion.PotionFluidHandler;
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
import com.simibubi.create.foundation.fluid.FluidIngredient;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.utility.Lang;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.gui.ingredient.IGuiFluidStackGroup;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.gui.ingredient.IRecipeSlotTooltipCallback;
import mezz.jei.api.recipe.RecipeType;
import mezz.jei.api.recipe.category.IRecipeCategory;
import mezz.jei.api.registration.IRecipeRegistration;
import net.minecraft.ChatFormatting;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.resources.ResourceLocation;
@ -30,15 +36,20 @@ import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.level.ItemLike;
import net.minecraftforge.fluids.FluidStack;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IRecipeCategory<T> {
public final List<Supplier<List<? extends Recipe<?>>>> recipes = new ArrayList<>();
public final List<Supplier<List<T>>> recipes = new ArrayList<>();
public final List<Supplier<? extends ItemStack>> recipeCatalysts = new ArrayList<>();
protected ResourceLocation uid;
protected String name;
private IDrawable background;
private IDrawable icon;
protected RecipeType<T> type;
private final IDrawable background;
private final IDrawable icon;
private static final IDrawable basicSlot = asDrawable(AllGuiTextures.JEI_SLOT);
private static final IDrawable chanceSlot = asDrawable(AllGuiTextures.JEI_CHANCE_SLOT);
public CreateRecipeCategory(IDrawable icon, IDrawable background) {
this.background = background;
@ -46,13 +57,22 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
}
public void setCategoryId(String name) {
this.uid = Create.asResource(name);
this.name = name;
this.type = RecipeType.create(Create.ID, name, getRecipeClass());
}
@Override
public ResourceLocation getUid() {
return uid;
return getRecipeType().getUid();
}
@Override
public abstract Class<? extends T> getRecipeClass();
@NotNull
@Override
public RecipeType<T> getRecipeType() {
return type;
}
@Override
@ -70,19 +90,23 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
return icon;
}
public static AllGuiTextures getRenderedSlot(Recipe<?> recipe, int index) {
AllGuiTextures jeiSlot = AllGuiTextures.JEI_SLOT;
if (!(recipe instanceof ProcessingRecipe))
return jeiSlot;
ProcessingRecipe<?> processingRecipe = (ProcessingRecipe<?>) recipe;
List<ProcessingOutput> rollableResults = processingRecipe.getRollableResults();
if (rollableResults.size() <= index)
return jeiSlot;
if (processingRecipe.getRollableResults()
.get(index)
.getChance() == 1)
return jeiSlot;
return AllGuiTextures.JEI_CHANCE_SLOT;
public void registerRecipes(IRecipeRegistration registration) {
recipes.forEach(s -> registration.addRecipes(getRecipeType(), s.get()));
}
public static IDrawable getRenderedSlot() {
return basicSlot;
}
public static IDrawable getRenderedSlot(ProcessingOutput output) {
return getRenderedSlot(output.getChance());
}
public static IDrawable getRenderedSlot(float chance) {
if (chance == 1)
return basicSlot;
return chanceSlot;
}
public static IDrawable emptyBackground(int width, int height) {
@ -97,25 +121,6 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
return new DoubleItemIcon(() -> new ItemStack(item), () -> ItemStack.EMPTY);
}
public static void addStochasticTooltip(IGuiItemStackGroup itemStacks, List<ProcessingOutput> results) {
addStochasticTooltip(itemStacks, results, 1);
}
public static void addStochasticTooltip(IGuiItemStackGroup itemStacks, List<ProcessingOutput> results,
int startIndex) {
itemStacks.addTooltipCallback((slotIndex, input, ingredient, tooltip) -> {
if (input)
return;
if (slotIndex < startIndex)
return;
ProcessingOutput output = results.get(slotIndex - startIndex);
float chance = output.getChance();
if (chance != 1)
tooltip.add(1, Lang.translate("recipe.processing.chance", chance < 0.01 ? "<1" : (int) (chance * 100))
.withStyle(ChatFormatting.GOLD));
});
}
public static IRecipeSlotTooltipCallback addStochasticTooltip(ProcessingOutput output) {
return (view, tooltip) -> {
float chance = output.getChance();
@ -138,46 +143,59 @@ public abstract class CreateRecipeCategory<T extends Recipe<?>> implements IReci
return display;
}
public static void addFluidTooltip(IGuiFluidStackGroup fluidStacks, List<FluidIngredient> inputs,
List<FluidStack> outputs) {
addFluidTooltip(fluidStacks, inputs, outputs, -1);
public static IRecipeSlotTooltipCallback addFluidTooltip() {
return addFluidTooltip(-1);
}
public static void addFluidTooltip(IGuiFluidStackGroup fluidStacks, List<FluidIngredient> inputs,
List<FluidStack> outputs, int index) {
List<Integer> amounts = new ArrayList<>();
inputs.forEach(f -> amounts.add(f.getRequiredAmount()));
outputs.forEach(f -> amounts.add(f.getAmount()));
fluidStacks.addTooltipCallback((slotIndex, input, fluid, tooltip) -> {
if (index != -1 && slotIndex != index)
public static IRecipeSlotTooltipCallback addFluidTooltip(int mbAmount) {
return (view, tooltip) -> {
Optional<FluidStack> displayed = view.getDisplayedIngredient(VanillaTypes.FLUID);
if (displayed.isEmpty())
return;
if (fluid.getFluid()
.isSame(AllFluids.POTION.get())) {
Component name = fluid.getDisplayName();
FluidStack fluidStack = displayed.get();
if (fluidStack.getFluid().isSame(AllFluids.POTION.get())) {
Component name = fluidStack.getDisplayName();
if (tooltip.isEmpty())
tooltip.add(0, name);
else
tooltip.set(0, name);
ArrayList<Component> potionTooltip = new ArrayList<>();
PotionFluidHandler.addPotionTooltip(fluid, potionTooltip, 1);
tooltip.addAll(1, potionTooltip.stream()
.collect(Collectors.toList()));
PotionFluidHandler.addPotionTooltip(fluidStack, potionTooltip, 1);
tooltip.addAll(1, potionTooltip.stream().toList());
}
int amount = amounts.get(index != -1 ? 0 : slotIndex);
int amount = mbAmount == -1 ? fluidStack.getAmount() : mbAmount;
Component text = new TextComponent(String.valueOf(amount)).append(Lang.translate("generic.unit.millibuckets")).withStyle(ChatFormatting.GOLD);
if (tooltip.isEmpty())
tooltip.add(0, text);
else {
List<Component> siblings = tooltip.get(0)
.getSiblings();
List<Component> siblings = tooltip.get(0).getSiblings();
siblings.add(new TextComponent(" "));
siblings.add(text);
}
});
};
}
private static IDrawable asDrawable(AllGuiTextures texture) {
return new IDrawable() {
@Override
public int getWidth() {
return texture.width;
}
@Override
public int getHeight() {
return texture.height;
}
@Override
public void draw(PoseStack poseStack, int xOffset, int yOffset) {
texture.render(poseStack, xOffset, yOffset);
}
};
}
}

View file

@ -1,24 +1,29 @@
package com.simibubi.create.compat.jei.category;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.compat.jei.category.animations.AnimatedCrushingWheels;
import com.simibubi.create.content.contraptions.components.crusher.AbstractCrushingRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.ponder.ui.LayoutHelper;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
@ParametersAreNonnullByDefault
public class CrushingCategory extends CreateRecipeCategory<AbstractCrushingRecipe> {
private AnimatedCrushingWheels crushingWheels = new AnimatedCrushingWheels();
private final AnimatedCrushingWheels crushingWheels = new AnimatedCrushingWheels();
public CrushingCategory() {
super(doubleItemIcon(AllBlocks.CRUSHING_WHEEL.get(), AllItems.CRUSHED_GOLD.get()), emptyBackground(177, 100));
@ -30,41 +35,45 @@ public class CrushingCategory extends CreateRecipeCategory<AbstractCrushingRecip
}
@Override
public void setIngredients(AbstractCrushingRecipe recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setOutputs(VanillaTypes.ITEM, recipe.getRollableResultsAsItemStacks());
public void setRecipe(IRecipeLayoutBuilder builder, AbstractCrushingRecipe recipe, IFocusGroup focuses) {
builder
.addSlot(RecipeIngredientRole.INPUT, 51, 3)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getIngredients().get(0));
int xOffset = getBackground().getWidth() / 2;
int yOffset = 86;
layoutOutput(recipe).forEach(layoutEntry -> builder
.addSlot(RecipeIngredientRole.OUTPUT, (xOffset) + layoutEntry.posX() + 1, yOffset + layoutEntry.posY() + 1)
.setBackground(getRenderedSlot(layoutEntry.output()), -1, -1)
.addItemStack(layoutEntry.output().getStack())
.addTooltipCallback(addStochasticTooltip(layoutEntry.output()))
);
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, AbstractCrushingRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
itemStacks.init(0, true, 50, 2);
itemStacks.set(0, Arrays.asList(recipe.getIngredients()
.get(0)
.getItems()));
private List<LayoutEntry> layoutOutput(ProcessingRecipe<?> recipe) {
int size = recipe.getRollableResults().size();
List<LayoutEntry> positions = new ArrayList<>(size);
List<ProcessingOutput> results = recipe.getRollableResults();
int size = results.size();
int offset = -size * 19 / 2;
for (int outputIndex = 0; outputIndex < size; outputIndex++) {
itemStacks.init(outputIndex + 1, false, getBackground().getWidth() / 2 + offset + 19 * outputIndex, 78);
itemStacks.set(outputIndex + 1, results.get(outputIndex)
.getStack());
LayoutHelper layout = LayoutHelper.centeredHorizontal(size, 1, 18, 18, 1);
for (ProcessingOutput result : recipe.getRollableResults()) {
positions.add(new LayoutEntry(result, layout.getX(), layout.getY()));
layout.next();
}
addStochasticTooltip(itemStacks, results);
return positions;
}
@Override
public void draw(AbstractCrushingRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
List<ProcessingOutput> results = recipe.getRollableResults();
AllGuiTextures.JEI_SLOT.render(matrixStack, 50, 2);
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 72, 7);
private record LayoutEntry(
ProcessingOutput output,
int posX,
int posY
) {}
int size = results.size();
int offset = -size * 19 / 2;
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++)
getRenderedSlot(recipe, outputIndex).render(matrixStack, getBackground().getWidth() / 2 + offset + 19 * outputIndex, 78);
@Override
public void draw(AbstractCrushingRecipe recipe, IRecipeSlotsView recipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 72, 7);
crushingWheels.draw(matrixStack, 62, 59);
}

View file

@ -1,29 +1,28 @@
package com.simibubi.create.compat.jei.category;
import java.util.Arrays;
import java.util.stream.Collectors;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.compat.jei.category.animations.AnimatedDeployer;
import com.simibubi.create.content.contraptions.components.deployer.DeployerApplicationRecipe;
import com.simibubi.create.foundation.fluid.FluidIngredient;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.utility.Lang;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.builder.IRecipeSlotBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.ChatFormatting;
@ParametersAreNonnullByDefault
public class DeployingCategory extends CreateRecipeCategory<DeployerApplicationRecipe> {
AnimatedDeployer deployer;
private final AnimatedDeployer deployer = new AnimatedDeployer();
public DeployingCategory() {
super(itemIcon(AllBlocks.DEPLOYER.get()), emptyBackground(177, 70));
deployer = new AnimatedDeployer();
}
@Override
@ -32,49 +31,29 @@ public class DeployingCategory extends CreateRecipeCategory<DeployerApplicationR
}
@Override
public void setIngredients(DeployerApplicationRecipe recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setInputLists(VanillaTypes.FLUID, recipe.getFluidIngredients()
.stream()
.map(FluidIngredient::getMatchingFluidStacks)
.collect(Collectors.toList()));
if (!recipe.getRollableResults()
.isEmpty())
ingredients.setOutput(VanillaTypes.ITEM, recipe.getResultItem());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, DeployerApplicationRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
itemStacks.init(0, true, 26, 50);
itemStacks.set(0, Arrays.asList(recipe.getProcessedItem()
.getItems()));
itemStacks.init(1, true, 50, 4);
itemStacks.set(1, Arrays.asList(recipe.getRequiredHeldItem()
.getItems()));
itemStacks.init(2, false, 131, 50);
itemStacks.set(2, recipe.getResultItem());
public void setRecipe(IRecipeLayoutBuilder builder, DeployerApplicationRecipe recipe, IFocusGroup focuses) {
builder
.addSlot(RecipeIngredientRole.INPUT, 27, 51)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getProcessedItem());
IRecipeSlotBuilder handItemSlot = builder
.addSlot(RecipeIngredientRole.INPUT, 51, 5)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getRequiredHeldItem());
builder
.addSlot(RecipeIngredientRole.OUTPUT, 132, 51)
.setBackground(getRenderedSlot(recipe.getRollableResults().get(0)), -1, -1)
.addItemStack(recipe.getResultItem())
.addTooltipCallback(addStochasticTooltip(recipe.getRollableResults().get(0)));
if (recipe.shouldKeepHeldItem()) {
itemStacks.addTooltipCallback((slotIndex, input, ingredient, tooltip) -> {
if (!input)
return;
if (slotIndex != 1)
return;
tooltip.add(1, Lang.translate("recipe.deploying.not_consumed")
.withStyle(ChatFormatting.GOLD));
});
handItemSlot.addTooltipCallback((recipeSlotView, tooltip) -> tooltip.add(1, Lang.translate("recipe.deploying.not_consumed").withStyle(ChatFormatting.GOLD)));
}
addStochasticTooltip(itemStacks, recipe.getRollableResults(), 2);
}
@Override
public void draw(DeployerApplicationRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SLOT.render(matrixStack, 50, 4);
AllGuiTextures.JEI_SLOT.render(matrixStack, 26, 50);
getRenderedSlot(recipe, 0).render(matrixStack, 131, 50);
public void draw(DeployerApplicationRecipe recipe, IRecipeSlotsView recipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SHADOW.render(matrixStack, 62, 57);
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 126, 29);
deployer.draw(matrixStack, getBackground().getWidth() / 2 - 13, 22);

View file

@ -1,5 +1,7 @@
package com.simibubi.create.compat.jei.category;
import org.jetbrains.annotations.NotNull;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics;
@ -27,7 +29,7 @@ public class FanBlastingCategory extends ProcessingViaFanCategory<AbstractCookin
}
@Override
protected void renderAttachedBlock(PoseStack matrixStack) {
protected void renderAttachedBlock(@NotNull PoseStack matrixStack) {
GuiGameElement.of(Fluids.LAVA)
.scale(SCALE)
.atLocal(0, 0, 2)

View file

@ -1,5 +1,7 @@
package com.simibubi.create.compat.jei.category;
import org.jetbrains.annotations.NotNull;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics;
@ -27,7 +29,7 @@ public class FanHauntingCategory extends ProcessingViaFanCategory.MultiOutput<Ha
}
@Override
protected void renderAttachedBlock(PoseStack matrixStack) {
protected void renderAttachedBlock(@NotNull PoseStack matrixStack) {
GuiGameElement.of(Blocks.SOUL_FIRE.defaultBlockState())
.scale(SCALE)
.atLocal(0, 0, 2)

View file

@ -1,5 +1,7 @@
package com.simibubi.create.compat.jei.category;
import org.jetbrains.annotations.NotNull;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics;
@ -27,7 +29,7 @@ public class FanSmokingCategory extends ProcessingViaFanCategory<SmokingRecipe>
}
@Override
protected void renderAttachedBlock(PoseStack matrixStack) {
protected void renderAttachedBlock(@NotNull PoseStack matrixStack) {
GuiGameElement.of(Blocks.FIRE.defaultBlockState())
.scale(SCALE)
.atLocal(0, 0, 2)

View file

@ -1,5 +1,7 @@
package com.simibubi.create.compat.jei.category;
import org.jetbrains.annotations.NotNull;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics;
@ -21,7 +23,7 @@ public class FanWashingCategory extends ProcessingViaFanCategory.MultiOutput<Spl
}
@Override
protected void renderAttachedBlock(PoseStack matrixStack) {
protected void renderAttachedBlock(@NotNull PoseStack matrixStack) {
GuiGameElement.of(Fluids.WATER)
.scale(SCALE)
.atLocal(0, 0, 2)

View file

@ -1,8 +1,9 @@
package com.simibubi.create.compat.jei.category;
import java.util.Arrays;
import java.util.Optional;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import com.simibubi.create.AllItems;
@ -23,6 +24,7 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;
@ParametersAreNonnullByDefault
public class ItemApplicationCategory extends CreateRecipeCategory<ItemApplicationRecipe> {
public ItemApplicationCategory() {
@ -37,31 +39,27 @@ public class ItemApplicationCategory extends CreateRecipeCategory<ItemApplicatio
@Override
public void setRecipe(IRecipeLayoutBuilder builder, ItemApplicationRecipe recipe, IFocusGroup focuses) {
builder.addSlot(RecipeIngredientRole.INPUT, 27, 38)
.addItemStacks(Arrays.asList(recipe.getProcessedItem()
.getItems()));
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getProcessedItem());
builder.addSlot(RecipeIngredientRole.INPUT, 51, 5)
.addItemStacks(Arrays.asList(recipe.getRequiredHeldItem()
.getItems()))
.addTooltipCallback(
recipe.shouldKeepHeldItem()
? (view, tooltip) -> tooltip.add(1, Lang.translate("recipe.deploying.not_consumed")
.withStyle(ChatFormatting.GOLD))
: (view, tooltip) -> {
});
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getRequiredHeldItem())
.addTooltipCallback(
recipe.shouldKeepHeldItem()
? (view, tooltip) -> tooltip.add(1, Lang.translate("recipe.deploying.not_consumed")
.withStyle(ChatFormatting.GOLD))
: (view, tooltip) -> {}
);
builder.addSlot(RecipeIngredientRole.OUTPUT, 132, 38)
.addItemStack(recipe.getResultItem())
.addTooltipCallback(addStochasticTooltip(recipe.getRollableResults()
.get(0)));
.setBackground(getRenderedSlot(recipe.getRollableResults().get(0)), -1, -1)
.addItemStack(recipe.getResultItem())
.addTooltipCallback(addStochasticTooltip(recipe.getRollableResults().get(0)));
}
@Override
public void draw(ItemApplicationRecipe recipe, IRecipeSlotsView recipeSlotsView, PoseStack matrixStack,
double mouseX, double mouseY) {
AllGuiTextures.JEI_SLOT.render(matrixStack, 50, 4);
AllGuiTextures.JEI_SLOT.render(matrixStack, 26, 37);
getRenderedSlot(recipe, 0).render(matrixStack, 131, 37);
public void draw(ItemApplicationRecipe recipe, IRecipeSlotsView recipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SHADOW.render(matrixStack, 62, 47);
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 74, 10);

View file

@ -1,11 +1,9 @@
package com.simibubi.create.compat.jei.category;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import com.google.common.collect.ImmutableList;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create;
@ -16,10 +14,10 @@ import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuild
import com.simibubi.create.foundation.gui.AllGuiTextures;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiFluidStackGroup;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import mezz.jei.api.runtime.IIngredientManager;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
@ -32,6 +30,7 @@ import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
@ParametersAreNonnullByDefault
public class ItemDrainCategory extends CreateRecipeCategory<EmptyingRecipe> {
AnimatedItemDrain drain;
@ -90,41 +89,24 @@ public class ItemDrainCategory extends CreateRecipeCategory<EmptyingRecipe> {
}
@Override
public void setIngredients(EmptyingRecipe recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
if (!recipe.getRollableResults()
.isEmpty())
ingredients.setOutput(VanillaTypes.ITEM, recipe.getResultItem());
if (!recipe.getFluidResults()
.isEmpty())
ingredients.setOutputs(VanillaTypes.FLUID, recipe.getFluidResults());
public void setRecipe(IRecipeLayoutBuilder builder, EmptyingRecipe recipe, IFocusGroup focuses) {
builder
.addSlot(RecipeIngredientRole.INPUT, 27, 8)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getIngredients().get(0));
builder
.addSlot(RecipeIngredientRole.OUTPUT, 132, 8)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredient(VanillaTypes.FLUID, withImprovedVisibility(recipe.getResultingFluid()))
.addTooltipCallback(addFluidTooltip(recipe.getResultingFluid().getAmount()));
builder
.addSlot(RecipeIngredientRole.OUTPUT, 132, 27)
.setBackground(getRenderedSlot(), -1, -1)
.addItemStack(recipe.getResultItem());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, EmptyingRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
IGuiFluidStackGroup fluidStacks = recipeLayout.getFluidStacks();
FluidStack fluidOutput = recipe.getResultingFluid();
List<ItemStack> matchingIngredients = Arrays.asList(recipe.getIngredients()
.get(0)
.getItems());
fluidStacks.init(0, false, 132, 8);
fluidStacks.set(0, withImprovedVisibility(fluidOutput));
itemStacks.init(0, true, 26, 7);
itemStacks.set(0, matchingIngredients);
itemStacks.init(1, false, 131, 26);
itemStacks.set(1, recipe.getResultItem());
addFluidTooltip(fluidStacks, Collections.emptyList(), ImmutableList.of(fluidOutput));
}
@Override
public void draw(EmptyingRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SLOT.render(matrixStack, 131, 7);
AllGuiTextures.JEI_SLOT.render(matrixStack, 26, 7);
getRenderedSlot(recipe, 0).render(matrixStack, 131, 26);
public void draw(EmptyingRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SHADOW.render(matrixStack, 62, 37);
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 73, 4);
drain.withFluid(recipe.getResultingFluid())

View file

@ -1,9 +1,12 @@
package com.simibubi.create.compat.jei.category;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import org.jetbrains.annotations.NotNull;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
@ -11,15 +14,15 @@ import com.simibubi.create.compat.jei.category.animations.AnimatedCrafter;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.ingredients.IIngredientRenderer;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.core.NonNullList;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.world.entity.player.Player;
@ -29,6 +32,7 @@ import net.minecraft.world.item.crafting.CraftingRecipe;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraftforge.common.crafting.IShapedRecipe;
@ParametersAreNonnullByDefault
public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRecipe> {
private final AnimatedCrafter crafter = new AnimatedCrafter();
@ -38,35 +42,33 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
}
@Override
public void setIngredients(CraftingRecipe recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setOutput(VanillaTypes.ITEM, recipe.getResultItem());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, CraftingRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
NonNullList<Ingredient> recipeIngredients = recipe.getIngredients();
itemStacks.init(0, false, 133, 80);
itemStacks.set(0, recipe.getResultItem());
public void setRecipe(IRecipeLayoutBuilder builder, CraftingRecipe recipe, IFocusGroup focuses) {
builder
.addSlot(RecipeIngredientRole.OUTPUT, 134, 81)
.addItemStack(recipe.getResultItem());
int x = getXPadding(recipe);
int y = getYPadding(recipe);
float scale = getScale(recipe);
int size = recipeIngredients.size();
IIngredientRenderer<ItemStack> renderer = new CrafterIngredientRenderer(recipe);
for (int i = 0; i < size; i++) {
IIngredientRenderer<ItemStack> renderer = new CrafterIngredientRenderer(recipe);
int i = 0;
for (Ingredient ingredient : recipe.getIngredients()) {
float f = 19 * scale;
int slotSize = (int) (16 * scale);
int xPosition = (int) (x + 1 + (i % getWidth(recipe)) * f);
int yPosition = (int) (y + 1 + (i / getWidth(recipe)) * f);
itemStacks.init(i + 1, true, renderer, xPosition, yPosition, slotSize, slotSize, 0, 0);
itemStacks.set(i + 1, Arrays.asList(recipeIngredients.get(i)
.getItems()));
builder
.addSlot(RecipeIngredientRole.INPUT, xPosition, yPosition)
.setCustomRenderer(VanillaTypes.ITEM, renderer)
.addIngredients(ingredient);
i++;
}
}
static int maxSize = 100;
@ -94,7 +96,7 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
}
@Override
public void draw(CraftingRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
public void draw(CraftingRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
matrixStack.pushPose();
float scale = getScale(recipe);
matrixStack.translate(getXPadding(recipe), getYPadding(recipe), 0);
@ -139,13 +141,15 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
private static final class CrafterIngredientRenderer implements IIngredientRenderer<ItemStack> {
private final CraftingRecipe recipe;
private final float scale;
public CrafterIngredientRenderer(CraftingRecipe recipe) {
this.recipe = recipe;
scale = getScale(recipe);
}
@Override
public void render(PoseStack matrixStack, int xPosition, int yPosition, ItemStack ingredient) {
public void render(PoseStack matrixStack, @NotNull ItemStack ingredient) {
matrixStack.pushPose();
float scale = getScale(recipe);
matrixStack.scale(scale, scale, scale);
@ -160,8 +164,8 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
Minecraft minecraft = Minecraft.getInstance();
Font font = getFontRenderer(minecraft, ingredient);
ItemRenderer itemRenderer = minecraft.getItemRenderer();
itemRenderer.renderAndDecorateFakeItem(ingredient, xPosition, yPosition);
itemRenderer.renderGuiItemDecorations(font, ingredient, xPosition, yPosition, null);
itemRenderer.renderAndDecorateFakeItem(ingredient, 0, 0);
itemRenderer.renderGuiItemDecorations(font, ingredient, 0, 0, null);
RenderSystem.disableBlend();
modelViewStack.popPose();
RenderSystem.applyModelViewMatrix();
@ -170,6 +174,16 @@ public class MechanicalCraftingCategory extends CreateRecipeCategory<CraftingRec
matrixStack.popPose();
}
@Override
public int getWidth() {
return (int) (16 * scale);
}
@Override
public int getHeight() {
return (int) (16 * scale);
}
@Override
public List<Component> getTooltip(ItemStack ingredient, TooltipFlag tooltipFlag) {
Minecraft minecraft = Minecraft.getInstance();

View file

@ -1,8 +1,9 @@
package com.simibubi.create.compat.jei.category;
import java.util.Arrays;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
@ -11,14 +12,15 @@ import com.simibubi.create.content.contraptions.components.crusher.AbstractCrush
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
@ParametersAreNonnullByDefault
public class MillingCategory extends CreateRecipeCategory<AbstractCrushingRecipe> {
private AnimatedMillstone millstone = new AnimatedMillstone();
private final AnimatedMillstone millstone = new AnimatedMillstone();
public MillingCategory() {
super(doubleItemIcon(AllBlocks.MILLSTONE.get(), AllItems.WHEAT_FLOUR.get()), emptyBackground(177, 53));
@ -30,54 +32,34 @@ public class MillingCategory extends CreateRecipeCategory<AbstractCrushingRecipe
}
@Override
public void setIngredients(AbstractCrushingRecipe recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setOutputs(VanillaTypes.ITEM, recipe.getRollableResultsAsItemStacks());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, AbstractCrushingRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
itemStacks.init(0, true, 14, 8);
itemStacks.set(0, Arrays.asList(recipe.getIngredients()
.get(0)
.getItems()));
public void setRecipe(IRecipeLayoutBuilder builder, AbstractCrushingRecipe recipe, IFocusGroup focuses) {
builder
.addSlot(RecipeIngredientRole.INPUT, 15, 9)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getIngredients().get(0));
List<ProcessingOutput> results = recipe.getRollableResults();
boolean single = results.size() == 1;
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++) {
int xOffset = outputIndex % 2 == 0 ? 0 : 19;
int yOffset = (outputIndex / 2) * -19;
int i = 0;
for (ProcessingOutput output : results) {
int xOffset = i % 2 == 0 ? 0 : 19;
int yOffset = (i / 2) * -19;
itemStacks.init(outputIndex + 1, false, single ? 139 : 133 + xOffset, 27 + yOffset);
itemStacks.set(outputIndex + 1, results.get(outputIndex)
.getStack());
builder
.addSlot(RecipeIngredientRole.OUTPUT, single ? 139 : 133 + xOffset, 27 + yOffset)
.setBackground(getRenderedSlot(output), -1, -1)
.addItemStack(output.getStack())
.addTooltipCallback(addStochasticTooltip(output));
i++;
}
addStochasticTooltip(itemStacks, results);
}
@Override
public void draw(AbstractCrushingRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
int size = recipe.getRollableResultsAsItemStacks()
.size();
AllGuiTextures.JEI_SLOT.render(matrixStack, 14, 8);
public void draw(AbstractCrushingRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_ARROW.render(matrixStack, 85, 32);
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 43, 4);
millstone.draw(matrixStack, 48, 27);
if (size == 1) {
getRenderedSlot(recipe, 0).render(matrixStack, 139, 27);
return;
}
for (int i = 0; i < size; i++) {
int xOffset = i % 2 == 0 ? 0 : 19;
int yOffset = (i / 2) * -19;
getRenderedSlot(recipe, i).render(matrixStack, 133 + xOffset, 27 + yOffset);
}
}
}

View file

@ -1,5 +1,7 @@
package com.simibubi.create.compat.jei.category;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.compat.jei.category.animations.AnimatedBlazeBurner;
@ -7,10 +9,12 @@ import com.simibubi.create.compat.jei.category.animations.AnimatedMixer;
import com.simibubi.create.content.contraptions.processing.BasinRecipe;
import com.simibubi.create.content.contraptions.processing.HeatCondition;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Blocks;
@ParametersAreNonnullByDefault
public class MixingCategory extends BasinCategory {
private final AnimatedMixer mixer = new AnimatedMixer();
@ -18,7 +22,7 @@ public class MixingCategory extends BasinCategory {
MixingType type;
enum MixingType {
AUTO_SHAPELESS, MIXING, AUTO_BREWING;
AUTO_SHAPELESS, MIXING, AUTO_BREWING
}
public static MixingCategory autoShapeless() {
@ -40,8 +44,9 @@ public class MixingCategory extends BasinCategory {
}
@Override
public void draw(BasinRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
super.draw(recipe, matrixStack, mouseX, mouseY);
public void draw(BasinRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
super.draw(recipe, iRecipeSlotsView, matrixStack, mouseX, mouseY);
HeatCondition requiredHeat = recipe.getRequiredHeat();
if (requiredHeat != HeatCondition.NONE)
heater.withHeat(requiredHeat.visualizeAsBlazeBurner())

View file

@ -1,21 +1,22 @@
package com.simibubi.create.compat.jei.category;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.compat.jei.ConversionRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
@ParametersAreNonnullByDefault
public class MysteriousItemConversionCategory extends CreateRecipeCategory<ConversionRecipe> {
public static final List<ConversionRecipe> RECIPES = new ArrayList<>();
@ -37,25 +38,19 @@ public class MysteriousItemConversionCategory extends CreateRecipeCategory<Conve
}
@Override
public void setIngredients(ConversionRecipe recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setOutputs(VanillaTypes.ITEM, recipe.getRollableResultsAsItemStacks());
public void setRecipe(IRecipeLayoutBuilder builder, ConversionRecipe recipe, IFocusGroup focuses) {
builder
.addSlot(RecipeIngredientRole.INPUT, 27, 17)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getIngredients().get(0));
builder
.addSlot(RecipeIngredientRole.OUTPUT, 132, 17)
.setBackground(getRenderedSlot(), -1, -1)
.addItemStack(recipe.getRollableResults().get(0).getStack());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, ConversionRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
List<ProcessingOutput> results = recipe.getRollableResults();
itemStacks.init(0, true, 26, 16);
itemStacks.set(0, Arrays.asList(recipe.getIngredients().get(0).getItems()));
itemStacks.init(1, false, 131, 16);
itemStacks.set(1, results.get(0).getStack());
}
@Override
public void draw(ConversionRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SLOT.render(matrixStack, 26, 16);
AllGuiTextures.JEI_SLOT.render(matrixStack, 131, 16);
public void draw(ConversionRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_LONG_ARROW.render(matrixStack, 52, 20);
AllGuiTextures.JEI_QUESTION_MARK.render(matrixStack, 77, 5);
}

View file

@ -1,6 +1,6 @@
package com.simibubi.create.compat.jei.category;
import java.util.Arrays;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
@ -10,22 +10,24 @@ import com.simibubi.create.content.contraptions.processing.BasinRecipe;
import com.simibubi.create.content.contraptions.processing.HeatCondition;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.core.NonNullList;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Blocks;
@ParametersAreNonnullByDefault
public class PackingCategory extends BasinCategory {
private AnimatedPress press = new AnimatedPress(true);
private final AnimatedPress press = new AnimatedPress(true);
private final AnimatedBlazeBurner heater = new AnimatedBlazeBurner();
private PackingType type;
private final PackingType type;
enum PackingType {
AUTO_SQUARE, COMPACTING;
AUTO_SQUARE, COMPACTING
}
public static PackingCategory standard() {
@ -43,51 +45,49 @@ public class PackingCategory extends BasinCategory {
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, BasinRecipe recipe, IIngredients ingredients) {
public void setRecipe(IRecipeLayoutBuilder builder, BasinRecipe recipe, IFocusGroup focuses) {
if (type == PackingType.COMPACTING) {
super.setRecipe(recipeLayout, recipe, ingredients);
super.setRecipe(builder, recipe, focuses);
return;
}
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
int i = 0;
NonNullList<Ingredient> ingredients2 = recipe.getIngredients();
int size = ingredients2.size();
NonNullList<Ingredient> ingredients = recipe.getIngredients();
int size = ingredients.size();
int rows = size == 4 ? 2 : 3;
while (i < size) {
Ingredient ingredient = ingredients2.get(i);
itemStacks.init(i, true, (rows == 2 ? 26 : 17) + (i % rows) * 19, 50 - (i / rows) * 19);
itemStacks.set(i, Arrays.asList(ingredient.getItems()));
Ingredient ingredient = ingredients.get(i);
builder
.addSlot(RecipeIngredientRole.INPUT, (rows == 2 ? 27 : 18) + (i % rows) * 19, 51 - (i / rows) * 19)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(ingredient);
i++;
}
itemStacks.init(i, false, 141, 50);
itemStacks.set(i, recipe.getResultItem());
builder
.addSlot(RecipeIngredientRole.OUTPUT, 142, 51)
.setBackground(getRenderedSlot(), -1, -1)
.addItemStack(recipe.getResultItem());
}
@Override
public void draw(BasinRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
public void draw(BasinRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
if (type == PackingType.COMPACTING) {
super.draw(recipe, matrixStack, mouseX, mouseY);
super.draw(recipe, iRecipeSlotsView, matrixStack, mouseX, mouseY);
} else {
NonNullList<Ingredient> ingredients2 = recipe.getIngredients();
int size = ingredients2.size();
int rows = size == 4 ? 2 : 3;
for (int i = 0; i < size; i++)
AllGuiTextures.JEI_SLOT.render(matrixStack, (rows == 2 ? 26 : 17) + (i % rows) * 19,
50 - (i / rows) * 19);
AllGuiTextures.JEI_SLOT.render(matrixStack, 141, 50);
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 136, 32);
AllGuiTextures.JEI_SHADOW.render(matrixStack, 81, 68);
}
HeatCondition requiredHeat = recipe.getRequiredHeat();
if (requiredHeat != HeatCondition.NONE)
heater.withHeat(requiredHeat.visualizeAsBlazeBurner())
.draw(matrixStack, getBackground().getWidth() / 2 + 3, 55);
press.draw(matrixStack, getBackground().getWidth() / 2 + 3, 34);
}
}

View file

@ -1,7 +1,6 @@
package com.simibubi.create.compat.jei.category;
import java.util.Arrays;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
@ -10,18 +9,19 @@ import com.simibubi.create.content.curiosities.tools.SandPaperPolishingRecipe;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.gui.element.GuiGameElement;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.core.NonNullList;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
@ParametersAreNonnullByDefault
public class PolishingCategory extends CreateRecipeCategory<SandPaperPolishingRecipe> {
private ItemStack renderedSandpaper;
private final ItemStack renderedSandpaper;
public PolishingCategory() {
super(itemIcon(AllItems.SAND_PAPER.get()), emptyBackground(177, 55));
@ -34,31 +34,22 @@ public class PolishingCategory extends CreateRecipeCategory<SandPaperPolishingRe
}
@Override
public void setIngredients(SandPaperPolishingRecipe recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setOutputs(VanillaTypes.ITEM, recipe.getRollableResultsAsItemStacks());
public void setRecipe(IRecipeLayoutBuilder builder, SandPaperPolishingRecipe recipe, IFocusGroup focuses) {
builder
.addSlot(RecipeIngredientRole.INPUT, 27, 29)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getIngredients().get(0));
ProcessingOutput output = recipe.getRollableResults().get(0);
builder
.addSlot(RecipeIngredientRole.OUTPUT, 132, 29)
.setBackground(getRenderedSlot(output), -1, -1)
.addItemStack(output.getStack())
.addTooltipCallback(addStochasticTooltip(output));
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, SandPaperPolishingRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
List<ProcessingOutput> results = recipe.getRollableResults();
itemStacks.init(0, true, 26, 28);
itemStacks.set(0, Arrays.asList(recipe.getIngredients()
.get(0)
.getItems()));
itemStacks.init(1, false, 131, 28);
itemStacks.set(1, results.get(0)
.getStack());
addStochasticTooltip(itemStacks, results);
}
@Override
public void draw(SandPaperPolishingRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SLOT.render(matrixStack, 26, 28);
getRenderedSlot(recipe, 0).render(matrixStack, 131, 28);
public void draw(SandPaperPolishingRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SHADOW.render(matrixStack, 61, 21);
AllGuiTextures.JEI_LONG_ARROW.render(matrixStack, 52, 32);

View file

@ -1,8 +1,9 @@
package com.simibubi.create.compat.jei.category;
import java.util.Arrays;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
@ -11,14 +12,15 @@ import com.simibubi.create.content.contraptions.components.press.PressingRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
@ParametersAreNonnullByDefault
public class PressingCategory extends CreateRecipeCategory<PressingRecipe> {
private AnimatedPress press = new AnimatedPress(false);
private final AnimatedPress press = new AnimatedPress(false);
public PressingCategory() {
super(doubleItemIcon(AllBlocks.MECHANICAL_PRESS.get(), AllItems.IRON_SHEET.get()), emptyBackground(177, 70));
@ -30,38 +32,28 @@ public class PressingCategory extends CreateRecipeCategory<PressingRecipe> {
}
@Override
public void setIngredients(PressingRecipe recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setOutputs(VanillaTypes.ITEM, recipe.getRollableResultsAsItemStacks());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, PressingRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
itemStacks.init(0, true, 26, 50);
itemStacks.set(0, Arrays.asList(recipe.getIngredients()
.get(0)
.getItems()));
public void setRecipe(IRecipeLayoutBuilder builder, PressingRecipe recipe, IFocusGroup focuses) {
builder
.addSlot(RecipeIngredientRole.INPUT, 27, 51)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getIngredients().get(0));
List<ProcessingOutput> results = recipe.getRollableResults();
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++) {
itemStacks.init(outputIndex + 1, false, 131 + 19 * outputIndex, 50);
itemStacks.set(outputIndex + 1, results.get(outputIndex)
.getStack());
int i = 0;
for (ProcessingOutput output : results) {
builder.addSlot(RecipeIngredientRole.OUTPUT, 131 + 19 * i, 50)
.setBackground(getRenderedSlot(output), -1, -1)
.addItemStack(output.getStack())
.addTooltipCallback(addStochasticTooltip(output));
i++;
}
addStochasticTooltip(itemStacks, results);
}
@Override
public void draw(PressingRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SLOT.render(matrixStack, 26, 50);
getRenderedSlot(recipe, 0).render(matrixStack, 131, 50);
if (recipe.getRollableResults()
.size() > 1)
getRenderedSlot(recipe, 1).render(matrixStack, 131 + 19, 50);
public void draw(PressingRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SHADOW.render(matrixStack, 61, 41);
AllGuiTextures.JEI_LONG_ARROW.render(matrixStack, 52, 54);
press.draw(matrixStack, getBackground().getWidth() / 2 - 17, 22);
}

View file

@ -3,6 +3,8 @@ package com.simibubi.create.compat.jei.category;
import java.util.List;
import java.util.function.Supplier;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import com.simibubi.create.AllBlockPartials;
@ -13,14 +15,15 @@ import com.simibubi.create.content.contraptions.processing.ProcessingRecipe;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.utility.Lang;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.drawable.IDrawable;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Recipe;
@ParametersAreNonnullByDefault
public abstract class ProcessingViaFanCategory<T extends Recipe<?>> extends CreateRecipeCategory<T> {
protected static final int SCALE = 24;
@ -39,24 +42,19 @@ public abstract class ProcessingViaFanCategory<T extends Recipe<?>> extends Crea
}
@Override
public void setIngredients(T recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setOutput(VanillaTypes.ITEM, recipe.getResultItem());
public void setRecipe(IRecipeLayoutBuilder builder, T recipe, IFocusGroup focuses) {
builder
.addSlot(RecipeIngredientRole.INPUT, 21, 48)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getIngredients().get(0));
builder
.addSlot(RecipeIngredientRole.OUTPUT, 141, 48)
.setBackground(getRenderedSlot(), -1, -1)
.addItemStack(recipe.getResultItem());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, T recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
itemStacks.init(0, true, 20, 47);
itemStacks.set(0, ingredients.getInputs(VanillaTypes.ITEM).get(0));
itemStacks.init(1, false, 140, 47);
itemStacks.set(1, ingredients.getOutputs(VanillaTypes.ITEM).get(0));
}
@Override
public void draw(T recipe, PoseStack matrixStack, double mouseX, double mouseY) {
public void draw(T recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
renderWidgets(matrixStack, recipe, mouseX, mouseY);
matrixStack.pushPose();
@ -83,8 +81,6 @@ public abstract class ProcessingViaFanCategory<T extends Recipe<?>> extends Crea
AllGuiTextures.JEI_SHADOW.render(matrixStack, 46, 29);
getBlockShadow().render(matrixStack, 65, 39);
AllGuiTextures.JEI_LONG_ARROW.render(matrixStack, 54, 51);
AllGuiTextures.JEI_SLOT.render(matrixStack, 20, 47);
AllGuiTextures.JEI_SLOT.render(matrixStack, 140, 47);
}
protected AllGuiTextures getBlockShadow() {
@ -103,57 +99,40 @@ public abstract class ProcessingViaFanCategory<T extends Recipe<?>> extends Crea
super(icon);
}
public MultiOutput(int width, IDrawable icon) {
super(width, icon);
}
@Override
public void setIngredients(T recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setOutputs(VanillaTypes.ITEM, recipe.getRollableResultsAsItemStacks());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, T recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
public void setRecipe(IRecipeLayoutBuilder builder, T recipe, IFocusGroup focuses) {
List<ProcessingOutput> results = recipe.getRollableResults();
int xOffsetAmount = 1 - Math.min(3, results.size());
itemStacks.init(0, true, 5 * xOffsetAmount + 20, 47);
itemStacks.set(0, ingredients.getInputs(VanillaTypes.ITEM).get(0));
builder
.addSlot(RecipeIngredientRole.INPUT, 5 * xOffsetAmount + 21, 48)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getIngredients().get(0));
int xOffsetOutput = 9 * xOffsetAmount;
int i = 0;
boolean excessive = results.size() > 9;
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++) {
int xOffset = (outputIndex % 3) * 19 + xOffsetOutput;
int yOffset = (outputIndex / 3) * -19 + (excessive ? 8 : 0);
for (ProcessingOutput output : results) {
int xOffset = (i % 3) * 19 + 9 * xOffsetAmount;
int yOffset = (i / 3) * -19 + (excessive ? 8 : 0);
itemStacks.init(outputIndex + 1, false, 140 + xOffset, 47 + yOffset);
itemStacks.set(outputIndex + 1, results.get(outputIndex).getStack());
builder
.addSlot(RecipeIngredientRole.OUTPUT, 141 + xOffset, 48 + yOffset)
.setBackground(getRenderedSlot(output), -1, -1)
.addItemStack(output.getStack())
.addTooltipCallback(addStochasticTooltip(output));
i++;
}
addStochasticTooltip(itemStacks, results);
}
@Override
protected void renderWidgets(PoseStack matrixStack, T recipe, double mouseX, double mouseY) {
int size = recipe.getRollableResultsAsItemStacks()
.size();
int size = recipe.getRollableResultsAsItemStacks().size();
int xOffsetAmount = 1 - Math.min(3, size);
AllGuiTextures.JEI_SHADOW.render(matrixStack, 46, 29);
getBlockShadow().render(matrixStack, 65, 39);
AllGuiTextures.JEI_LONG_ARROW.render(matrixStack, 7 * xOffsetAmount + 54, 51);
AllGuiTextures.JEI_SLOT.render(matrixStack, 5 * xOffsetAmount + 20, 47);
int xOffsetOutput = 9 * xOffsetAmount;
boolean excessive = size > 9;
for (int i = 0; i < size; i++) {
int xOffset = (i % 3) * 19 + xOffsetOutput;
int yOffset = (i / 3) * -19 + (excessive ? 8 : 0);
getRenderedSlot(recipe, i).render(matrixStack, 140 + xOffset, 47 + yOffset);
}
}
}

View file

@ -1,8 +1,9 @@
package com.simibubi.create.compat.jei.category;
import java.util.Arrays;
import java.util.List;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.compat.jei.category.animations.AnimatedSaw;
@ -10,15 +11,16 @@ import com.simibubi.create.content.contraptions.components.saw.CuttingRecipe;
import com.simibubi.create.content.contraptions.processing.ProcessingOutput;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.world.item.Items;
@ParametersAreNonnullByDefault
public class SawingCategory extends CreateRecipeCategory<CuttingRecipe> {
private AnimatedSaw saw = new AnimatedSaw();
private final AnimatedSaw saw = new AnimatedSaw();
public SawingCategory() {
super(doubleItemIcon(AllBlocks.MECHANICAL_SAW.get(), Items.OAK_LOG), emptyBackground(177, 70));
@ -30,44 +32,31 @@ public class SawingCategory extends CreateRecipeCategory<CuttingRecipe> {
}
@Override
public void setIngredients(CuttingRecipe recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setOutputs(VanillaTypes.ITEM, recipe.getRollableResultsAsItemStacks());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, CuttingRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
itemStacks.init(0, true, 43, 4);
itemStacks.set(0, Arrays.asList(recipe.getIngredients()
.get(0)
.getItems()));
public void setRecipe(IRecipeLayoutBuilder builder, CuttingRecipe recipe, IFocusGroup focuses) {
builder
.addSlot(RecipeIngredientRole.INPUT, 44, 5)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getIngredients().get(0));
List<ProcessingOutput> results = recipe.getRollableResults();
for (int outputIndex = 0; outputIndex < results.size(); outputIndex++) {
int xOffset = outputIndex % 2 == 0 ? 0 : 19;
int yOffset = (outputIndex / 2) * -19;
itemStacks.init(outputIndex + 1, false, 117 + xOffset, 47 + yOffset);
itemStacks.set(outputIndex + 1, results.get(outputIndex)
.getStack());
int i = 0;
for (ProcessingOutput output : results) {
int xOffset = i % 2 == 0 ? 0 : 19;
int yOffset = (i / 2) * -19;
builder
.addSlot(RecipeIngredientRole.OUTPUT, 118 + xOffset, 48 + yOffset)
.setBackground(getRenderedSlot(output), -1, -1)
.addItemStack(output.getStack())
.addTooltipCallback(addStochasticTooltip(output));
i++;
}
addStochasticTooltip(itemStacks, results);
}
@Override
public void draw(CuttingRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SLOT.render(matrixStack, 43, 4);
int size = recipe.getRollableResults()
.size();
for (int i = 0; i < size; i++) {
int xOffset = i % 2 == 0 ? 0 : 19;
int yOffset = (i / 2) * -19;
getRenderedSlot(recipe, i).render(matrixStack, 117 + xOffset, 47 + yOffset);
}
public void draw(CuttingRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 70, 6);
AllGuiTextures.JEI_SHADOW.render(matrixStack, 72 - 17, 42 + 13);
saw.draw(matrixStack, 72, 42);
}

View file

@ -1,29 +1,28 @@
package com.simibubi.create.compat.jei.category;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableList;
import javax.annotation.ParametersAreNonnullByDefault;
import org.jetbrains.annotations.NotNull;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllItems;
import com.simibubi.create.compat.jei.EmptyBackground;
import com.simibubi.create.compat.jei.category.sequencedAssembly.SequencedAssemblySubCategory;
import com.simibubi.create.content.contraptions.itemAssembly.SequencedAssemblyRecipe;
import com.simibubi.create.content.contraptions.itemAssembly.SequencedRecipe;
import com.simibubi.create.foundation.fluid.FluidIngredient;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.gui.AllIcons;
import com.simibubi.create.foundation.utility.Lang;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiFluidStackGroup;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
@ -31,9 +30,8 @@ import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.Ingredient;
@ParametersAreNonnullByDefault
public class SequencedAssemblyCategory extends CreateRecipeCategory<SequencedAssemblyRecipe> {
Map<ResourceLocation, SequencedAssemblySubCategory> subCategories = new HashMap<>();
@ -48,31 +46,26 @@ public class SequencedAssemblyCategory extends CreateRecipeCategory<SequencedAss
}
@Override
public void setIngredients(SequencedAssemblyRecipe recipe, IIngredients ingredients) {
List<Ingredient> assemblyIngredients = getAllItemIngredients(recipe);
List<FluidIngredient> assemblyFluidIngredients = getAllFluidIngredients(recipe);
ingredients.setInputIngredients(assemblyIngredients);
if (!assemblyFluidIngredients.isEmpty())
ingredients.setInputLists(VanillaTypes.FLUID, assemblyFluidIngredients.stream()
.map(FluidIngredient::getMatchingFluidStacks)
.collect(Collectors.toList()));
ingredients.setOutputs(VanillaTypes.ITEM,
ImmutableList.of(recipe.getResultItem(), recipe.getTransitionalItem()));
}
public void setRecipe(IRecipeLayoutBuilder builder, SequencedAssemblyRecipe recipe, IFocusGroup focuses) {
boolean noRandomOutput = recipe.getOutputChance() == 1;
int xOffset = noRandomOutput ? 0 : -7;
@Override
public void setRecipe(IRecipeLayout recipeLayout, SequencedAssemblyRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
IGuiFluidStackGroup fluidStacks = recipeLayout.getFluidStacks();
int xOffset = recipe.getOutputChance() == 1 ? 0 : -7;
builder
.addSlot(RecipeIngredientRole.INPUT, 27 + xOffset, 91)
.setBackground(getRenderedSlot(), -1, -1)
.addItemStacks(List.of(recipe.getIngredient().getItems()));
builder
.addSlot(RecipeIngredientRole.OUTPUT, 132 + xOffset, 91)
.setBackground(getRenderedSlot(recipe.getOutputChance()), -1 , -1)
.addItemStack(recipe.getResultItem())
.addTooltipCallback((recipeSlotView, tooltip) -> {
if (noRandomOutput)
return;
itemStacks.init(0, true, 26 + xOffset, 90);
itemStacks.set(0, Arrays.asList(recipe.getIngredient()
.getItems()));
ItemStack result = recipe.getResultItem();
itemStacks.init(1, false, 131 + xOffset, 90);
itemStacks.set(1, result);
float chance = recipe.getOutputChance();
tooltip.add(1, Lang.translate("recipe.processing.chance", chance < 0.01 ? "<1" : (int) (chance * 100))
.withStyle(ChatFormatting.GOLD));
});
int width = 0;
int margin = 3;
@ -80,34 +73,12 @@ public class SequencedAssemblyCategory extends CreateRecipeCategory<SequencedAss
width += getSubCategory(sequencedRecipe).getWidth() + margin;
width -= margin;
int x = width / -2 + getBackground().getWidth() / 2;
int index = 2;
int fluidIndex = 0;
for (SequencedRecipe<?> sequencedRecipe : recipe.getSequence()) {
SequencedAssemblySubCategory subCategory = getSubCategory(sequencedRecipe);
index += subCategory.addItemIngredients(sequencedRecipe, itemStacks, x, index);
fluidIndex += subCategory.addFluidIngredients(sequencedRecipe, fluidStacks, x, fluidIndex);
subCategory.setRecipe(builder, sequencedRecipe, focuses, x);
x += subCategory.getWidth() + margin;
}
// In case machines should be displayed as ingredients
// List<List<ItemStack>> inputs = ingredients.getInputs(VanillaTypes.ITEM);
// int catalystX = -2;
// int catalystY = 14;
// for (; index < inputs.size(); index++) {
// itemStacks.init(index, true, catalystX, catalystY);
// itemStacks.set(index, inputs.get(index));
// catalystY += 19;
// }
itemStacks.addTooltipCallback((slotIndex, input, ingredient, tooltip) -> {
if (slotIndex != 1)
return;
float chance = recipe.getOutputChance();
if (chance != 1)
tooltip.add(1, Lang.translate("recipe.processing.chance", chance < 0.01 ? "<1" : (int) (chance * 100))
.withStyle(ChatFormatting.GOLD));
});
}
private SequencedAssemblySubCategory getSubCategory(SequencedRecipe<?> sequencedRecipe) {
@ -124,7 +95,7 @@ public class SequencedAssemblyCategory extends CreateRecipeCategory<SequencedAss
final String[] romans = { "I", "II", "III", "IV", "V", "VI", "-" };
@Override
public void draw(SequencedAssemblyRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
public void draw(SequencedAssemblyRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
Font font = Minecraft.getInstance().font;
matrixStack.pushPose();
@ -133,8 +104,6 @@ public class SequencedAssemblyCategory extends CreateRecipeCategory<SequencedAss
matrixStack.translate(0, 15, 0);
boolean singleOutput = recipe.getOutputChance() == 1;
int xOffset = singleOutput ? 0 : -7;
AllGuiTextures.JEI_SLOT.render(matrixStack, 26 + xOffset, 75);
(singleOutput ? AllGuiTextures.JEI_SLOT : AllGuiTextures.JEI_CHANCE_SLOT).render(matrixStack, 131 + xOffset, 75);
AllGuiTextures.JEI_LONG_ARROW.render(matrixStack, 52 + xOffset, 79);
if (!singleOutput) {
AllGuiTextures.JEI_CHANCE_SLOT.render(matrixStack, 150 + xOffset, 75);
@ -178,8 +147,9 @@ public class SequencedAssemblyCategory extends CreateRecipeCategory<SequencedAss
}
@Override
public List<Component> getTooltipStrings(SequencedAssemblyRecipe recipe, double mouseX, double mouseY) {
List<Component> tooltip = new ArrayList<Component>();
@NotNull
public List<Component> getTooltipStrings(SequencedAssemblyRecipe recipe, IRecipeSlotsView iRecipeSlotsView, double mouseX, double mouseY) {
List<Component> tooltip = new ArrayList<>();
TranslatableComponent junk = Lang.translate("recipe.assembly.junk");
@ -235,19 +205,4 @@ public class SequencedAssemblyCategory extends CreateRecipeCategory<SequencedAss
return tooltip;
}
private List<FluidIngredient> getAllFluidIngredients(SequencedAssemblyRecipe recipe) {
List<FluidIngredient> assemblyFluidIngredients = new ArrayList<>();
recipe.addAdditionalFluidIngredients(assemblyFluidIngredients);
return assemblyFluidIngredients;
}
private List<Ingredient> getAllItemIngredients(SequencedAssemblyRecipe recipe) {
List<Ingredient> assemblyIngredients = new ArrayList<>();
assemblyIngredients.add(recipe.getIngredient());
assemblyIngredients.add(Ingredient.of(recipe.getTransitionalItem()));
recipe.addAdditionalIngredientsAndMachines(assemblyIngredients);
return assemblyIngredients;
}
}

View file

@ -1,13 +1,10 @@
package com.simibubi.create.compat.jei.category;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import com.google.common.collect.ImmutableList;
import javax.annotation.ParametersAreNonnullByDefault;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create;
@ -20,10 +17,10 @@ import com.simibubi.create.foundation.fluid.FluidIngredient;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.IRecipeLayout;
import mezz.jei.api.gui.ingredient.IGuiFluidStackGroup;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.ingredients.IIngredients;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.ingredient.IRecipeSlotsView;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import mezz.jei.api.runtime.IIngredientManager;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
@ -36,9 +33,10 @@ import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
@ParametersAreNonnullByDefault
public class SpoutCategory extends CreateRecipeCategory<FillingRecipe> {
AnimatedSpout spout;
private final AnimatedSpout spout;
public SpoutCategory() {
super(doubleItemIcon(AllBlocks.SPOUT.get(), Items.WATER_BUCKET), emptyBackground(177, 70));
@ -102,45 +100,24 @@ public class SpoutCategory extends CreateRecipeCategory<FillingRecipe> {
}
@Override
public void setIngredients(FillingRecipe recipe, IIngredients ingredients) {
ingredients.setInputIngredients(recipe.getIngredients());
ingredients.setInputLists(VanillaTypes.FLUID, recipe.getFluidIngredients()
.stream()
.map(FluidIngredient::getMatchingFluidStacks)
.collect(Collectors.toList()));
if (!recipe.getRollableResults()
.isEmpty())
ingredients.setOutput(VanillaTypes.ITEM, recipe.getResultItem());
if (!recipe.getFluidResults()
.isEmpty())
ingredients.setOutputs(VanillaTypes.FLUID, recipe.getFluidResults());
public void setRecipe(IRecipeLayoutBuilder builder, FillingRecipe recipe, IFocusGroup focuses) {
builder
.addSlot(RecipeIngredientRole.INPUT, 27, 51)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(recipe.getIngredients().get(0));
builder
.addSlot(RecipeIngredientRole.INPUT, 27, 32)
.setBackground(getRenderedSlot(), -1, -1)
.addIngredients(VanillaTypes.FLUID, withImprovedVisibility(recipe.getRequiredFluid().getMatchingFluidStacks()))
.addTooltipCallback(addFluidTooltip(recipe.getRequiredFluid().getRequiredAmount()));
builder
.addSlot(RecipeIngredientRole.OUTPUT, 132, 51)
.setBackground(getRenderedSlot(), -1, -1)
.addItemStack(recipe.getResultItem());
}
@Override
public void setRecipe(IRecipeLayout recipeLayout, FillingRecipe recipe, IIngredients ingredients) {
IGuiItemStackGroup itemStacks = recipeLayout.getItemStacks();
IGuiFluidStackGroup fluidStacks = recipeLayout.getFluidStacks();
FluidIngredient fluidIngredient = recipe.getRequiredFluid();
List<ItemStack> matchingIngredients = Arrays.asList(recipe.getIngredients()
.get(0)
.getItems());
fluidStacks.init(0, true, 27, 32);
fluidStacks.set(0, withImprovedVisibility(fluidIngredient.getMatchingFluidStacks()));
itemStacks.init(0, true, 26, 50);
itemStacks.set(0, matchingIngredients);
itemStacks.init(1, false, 131, 50);
itemStacks.set(1, recipe.getResultItem());
addFluidTooltip(fluidStacks, ImmutableList.of(fluidIngredient), Collections.emptyList());
}
@Override
public void draw(FillingRecipe recipe, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SLOT.render(matrixStack, 26, 31);
AllGuiTextures.JEI_SLOT.render(matrixStack, 26, 50);
getRenderedSlot(recipe, 0).render(matrixStack, 131, 50);
public void draw(FillingRecipe recipe, IRecipeSlotsView iRecipeSlotsView, PoseStack matrixStack, double mouseX, double mouseY) {
AllGuiTextures.JEI_SHADOW.render(matrixStack, 62, 57);
AllGuiTextures.JEI_DOWN_ARROW.render(matrixStack, 126, 29);
spout.withFluids(recipe.getRequiredFluid()

View file

@ -1,9 +1,5 @@
package com.simibubi.create.compat.jei.category.sequencedAssembly;
import java.util.Arrays;
import java.util.Collections;
import com.google.common.collect.ImmutableList;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.compat.jei.category.CreateRecipeCategory;
import com.simibubi.create.compat.jei.category.animations.AnimatedDeployer;
@ -11,19 +7,20 @@ import com.simibubi.create.compat.jei.category.animations.AnimatedPress;
import com.simibubi.create.compat.jei.category.animations.AnimatedSaw;
import com.simibubi.create.compat.jei.category.animations.AnimatedSpout;
import com.simibubi.create.content.contraptions.components.deployer.DeployerApplicationRecipe;
import com.simibubi.create.content.contraptions.itemAssembly.IAssemblyRecipe;
import com.simibubi.create.content.contraptions.itemAssembly.SequencedRecipe;
import com.simibubi.create.foundation.fluid.FluidIngredient;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.utility.Lang;
import mezz.jei.api.gui.ingredient.IGuiFluidStackGroup;
import mezz.jei.api.gui.ingredient.IGuiItemStackGroup;
import mezz.jei.api.constants.VanillaTypes;
import mezz.jei.api.gui.builder.IRecipeLayoutBuilder;
import mezz.jei.api.gui.builder.IRecipeSlotBuilder;
import mezz.jei.api.recipe.IFocusGroup;
import mezz.jei.api.recipe.RecipeIngredientRole;
import net.minecraft.ChatFormatting;
public abstract class SequencedAssemblySubCategory {
private int width;
private final int width;
public SequencedAssemblySubCategory(int width) {
this.width = width;
@ -33,13 +30,7 @@ public abstract class SequencedAssemblySubCategory {
return width;
}
public int addItemIngredients(SequencedRecipe<?> recipe, IGuiItemStackGroup itemStacks, int x, int index) {
return 0;
}
public int addFluidIngredients(SequencedRecipe<?> recipe, IGuiFluidStackGroup fluidStacks, int x, int index) {
return 0;
}
public void setRecipe(IRecipeLayoutBuilder builder, SequencedRecipe<?> recipe, IFocusGroup focuses, int x) {}
public abstract void draw(SequencedRecipe<?> recipe, PoseStack ms, double mouseX, double mouseY, int index);
@ -74,22 +65,21 @@ public abstract class SequencedAssemblySubCategory {
}
@Override
public int addFluidIngredients(SequencedRecipe<?> recipe, IGuiFluidStackGroup fluidStacks, int x, int index) {
public void setRecipe(IRecipeLayoutBuilder builder, SequencedRecipe<?> recipe, IFocusGroup focuses, int x) {
FluidIngredient fluidIngredient = recipe.getRecipe()
.getFluidIngredients()
.get(0);
fluidStacks.init(index, true, x + 4, 15);
fluidStacks.set(index,
CreateRecipeCategory.withImprovedVisibility(fluidIngredient.getMatchingFluidStacks()));
CreateRecipeCategory.addFluidTooltip(fluidStacks, ImmutableList.of(fluidIngredient),
Collections.emptyList(), index);
return 1;
.getFluidIngredients()
.get(0);
builder
.addSlot(RecipeIngredientRole.INPUT, x + 4, 15)
.setBackground(CreateRecipeCategory.getRenderedSlot(), -1, -1)
.addIngredients(VanillaTypes.FLUID, CreateRecipeCategory.withImprovedVisibility(fluidIngredient.getMatchingFluidStacks()))
.addTooltipCallback(CreateRecipeCategory.addFluidTooltip(fluidIngredient.getRequiredAmount()));
}
@Override
public void draw(SequencedRecipe<?> recipe, PoseStack ms, double mouseX, double mouseY, int index) {
spout.offset = index;
AllGuiTextures.JEI_SLOT.render(ms, 3, 14);
ms.pushPose();
ms.translate(-7, 50, 0);
ms.scale(.75f, .75f, .75f);
@ -113,26 +103,17 @@ public abstract class SequencedAssemblySubCategory {
}
@Override
public int addItemIngredients(SequencedRecipe<?> recipe, IGuiItemStackGroup itemStacks, int x, int index) {
itemStacks.init(index, true, x + 3, 14);
itemStacks.set(index, Arrays.asList(recipe.getRecipe()
.getIngredients()
.get(1)
.getItems()));
IAssemblyRecipe contained = recipe.getAsAssemblyRecipe();
if (contained instanceof DeployerApplicationRecipe && ((DeployerApplicationRecipe) contained).shouldKeepHeldItem()) {
itemStacks.addTooltipCallback((slotIndex, input, ingredient, tooltip) -> {
if (!input)
return;
if (slotIndex != index)
return;
tooltip.add(1, Lang.translate("recipe.deploying.not_consumed")
.withStyle(ChatFormatting.GOLD));
});
public void setRecipe(IRecipeLayoutBuilder builder, SequencedRecipe<?> recipe, IFocusGroup focuses, int x) {
IRecipeSlotBuilder slot = builder
.addSlot(RecipeIngredientRole.INPUT, x + 4, 15)
.setBackground(CreateRecipeCategory.getRenderedSlot(), -1, -1)
.addIngredients(recipe.getRecipe().getIngredients().get(1));
if (recipe.getAsAssemblyRecipe() instanceof DeployerApplicationRecipe deployerRecipe && deployerRecipe.shouldKeepHeldItem()) {
slot.addTooltipCallback(
(recipeSlotView, tooltip) -> tooltip.add(1, Lang.translate("recipe.deploying.not_consumed").withStyle(ChatFormatting.GOLD))
);
}
return 1;
}
@Override
@ -143,7 +124,6 @@ public abstract class SequencedAssemblySubCategory {
ms.scale(.75f, .75f, .75f);
deployer.draw(ms, getWidth() / 2, 0);
ms.popPose();
AllGuiTextures.JEI_SLOT.render(ms, 3, 14);
}
}

View file

@ -3,6 +3,7 @@ package com.simibubi.create.foundation.utility;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import net.minecraft.client.Minecraft;
import net.minecraft.util.Mth;
public class CameraAngleAnimationService {
@ -14,6 +15,9 @@ public class CameraAngleAnimationService {
public static void tick() {
yRotation.tickChaser();
xRotation.tickChaser();
if (Minecraft.getInstance().player != null) {
if (!yRotation.settled())
Minecraft.getInstance().player.setYRot(yRotation.getValue(1));
@ -21,9 +25,6 @@ public class CameraAngleAnimationService {
if (!xRotation.settled())
Minecraft.getInstance().player.setXRot(xRotation.getValue(1));
}
yRotation.tickChaser();
xRotation.tickChaser();
}
public static boolean isYawAnimating() {
@ -51,27 +52,28 @@ public class CameraAngleAnimationService {
}
public static void setYawTarget(float yaw) {
yRotation.startWithValue(getCurrentYaw());
setupChaser(yRotation, yaw);
float currentYaw = getCurrentYaw();
yRotation.startWithValue(currentYaw);
setupChaser(yRotation, currentYaw + AngleHelper.getShortestAngleDiff(currentYaw, Mth.wrapDegrees(yaw)));
}
public static void setPitchTarget(float pitch) {
xRotation.startWithValue(getCurrentPitch());
setupChaser(xRotation, pitch);
float currentPitch = getCurrentPitch();
xRotation.startWithValue(currentPitch);
setupChaser(xRotation, currentPitch + AngleHelper.getShortestAngleDiff(currentPitch, Mth.wrapDegrees(pitch)));
}
private static float getCurrentYaw() {
if (Minecraft.getInstance().player == null)
return 0;
return Minecraft.getInstance().player.getYRot();
return Mth.wrapDegrees(Minecraft.getInstance().player.getYRot());
}
private static float getCurrentPitch() {
if (Minecraft.getInstance().player == null)
return 0;
return Minecraft.getInstance().player.getXRot();
return Mth.wrapDegrees(Minecraft.getInstance().player.getXRot());
}
private static void setupChaser(LerpedFloat rotation, float target) {