diff --git a/CHANGELOG.md b/CHANGELOG.md index 88afe56..5a2e422 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ -## Fixed +## Added -- Minor issue with stack copying +- Oritech JEI Compact + +## Removed + +- AdvancedAE JEI Compact due to AdvancedAE adding it's self diff --git a/build.gradle b/build.gradle index bddd33f..feb9341 100644 --- a/build.gradle +++ b/build.gradle @@ -43,8 +43,8 @@ neoForge { systemProperty 'neoforge.enabledGameTestNamespaces', project.mod_id // Add --width and --height to the client run configuration - programArgument '--width=1920' - programArgument '--height=1080' +// programArgument '--width=1920' +// programArgument '--height=1080' } server { @@ -89,26 +89,39 @@ dependencies { localRuntime "mezz.jei:jei-${minecraft_version}-neoforge:${jei_version}" def extendedAEAtRuntime = true - def advancedAEAtRuntime = true + def oritechAtRuntime = true compileOnly("curse.maven:applied-energistics-2-223794:5662490") - compileOnly("curse.maven:glodium-957920:5614731") compileOnly("curse.maven:extendedae-892005:5680210") if (extendedAEAtRuntime) localRuntime("curse.maven:extendedae-892005:5680210") - compileOnly("curse.maven:advancedae-1084104:5715851") - if (advancedAEAtRuntime) localRuntime("curse.maven:advancedae-1084104:5881249") + if (extendedAEAtRuntime) runtimeOnly("curse.maven:applied-energistics-2-223794:5662490") + if (extendedAEAtRuntime || oritechAtRuntime) runtimeOnly("curse.maven:geckolib-388172:5874016") + + compileOnly("curse.maven:oritech-1030830:5952879") + // All these are required for depending on oritech + compileOnly("curse.maven:architectury-api-419699:5786327") + compileOnly("org.sinytra.forgified-fabric-api:forgified-fabric-api:0.104.0+2.0.19+1.21.1") + compileOnly("curse.maven:geckolib-388172:5874016") + compileOnly("curse.maven:owo-lib-532610:5945693") + + if (oritechAtRuntime) { + localRuntime("curse.maven:oritech-1030830:5952879") + runtimeOnly("curse.maven:architectury-api-419699:5786327") + runtimeOnly("curse.maven:owo-lib-532610:5945693") + runtimeOnly("curse.maven:athena-841890:5629395") + runtimeOnly("org.sinytra.forgified-fabric-api:forgified-fabric-api:0.104.0+2.0.19+1.21.1") + } + - if (extendedAEAtRuntime || advancedAEAtRuntime) runtimeOnly("curse.maven:applied-energistics-2-223794:5662490") - if (extendedAEAtRuntime || advancedAEAtRuntime) runtimeOnly("curse.maven:glodium-957920:5614731") - if (extendedAEAtRuntime || advancedAEAtRuntime) runtimeOnly("curse.maven:geckolib-388172:5874016") } repositories { mavenLocal() maven { url "https://modmaven.dev" } maven { url "https://cursemaven.com" } + maven { url "https://maven.su5ed.dev/releases" } } // This block of code expands all declared replace properties in the specified resource targets. diff --git a/gradle.properties b/gradle.properties index 0ebf7b9..0837f66 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,10 +16,10 @@ loader_version_range=[4,) mod_id=ftbjeiextras mod_name=FTB Jei Extras mod_license=All Rights Reserved -mod_version=21.1.3 +mod_version=21.1.4 mod_group_id=dev.ftb.mods mod_authors=FTB Team mod_description=Stand in mod to add extra JEI support for mods that don't have it. -jei_version=19.17.0.193 +jei_version=19.21.0.247 curseforge_id=1103259 diff --git a/src/main/java/dev/ftb/mods/ftbjeiextras/advancedae/AdvancedAePlugin.java b/src/main/java/dev/ftb/mods/ftbjeiextras/advancedae/AdvancedAePlugin.java deleted file mode 100644 index 1d4ceab..0000000 --- a/src/main/java/dev/ftb/mods/ftbjeiextras/advancedae/AdvancedAePlugin.java +++ /dev/null @@ -1,40 +0,0 @@ -package dev.ftb.mods.ftbjeiextras.advancedae; - -import dev.ftb.mods.ftbjeiextras.loader.IConditionalModPlugin; -import mezz.jei.api.registration.IRecipeCatalystRegistration; -import mezz.jei.api.registration.IRecipeCategoryRegistration; -import mezz.jei.api.registration.IRecipeRegistration; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.RecipeHolder; -import net.neoforged.fml.ModList; -import net.pedroksl.advanced_ae.common.definitions.AAEBlocks; -import net.pedroksl.advanced_ae.recipes.ReactionChamberRecipe; - -public class AdvancedAePlugin implements IConditionalModPlugin { - @Override - public void registerCategories(IRecipeCategoryRegistration registration) { - registration.addRecipeCategories(new ReactionChamberRecipeCategory(registration.getJeiHelpers())); - } - - @Override - public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) { - registration.addRecipeCatalyst(new ItemStack(AAEBlocks.REACTION_CHAMBER), ReactionChamberRecipeCategory.TYPE); - } - - @Override - public void registerRecipes(IRecipeRegistration registration) { - ClientLevel level = Minecraft.getInstance().level; - assert level != null; - - var recipeManager = level.getRecipeManager(); - - registration.addRecipes(ReactionChamberRecipeCategory.TYPE, recipeManager.getAllRecipesFor(ReactionChamberRecipe.TYPE).stream().map(RecipeHolder::value).toList()); - } - - @Override - public boolean shouldLoad() { - return ModList.get().isLoaded("advanced_ae"); - } -} diff --git a/src/main/java/dev/ftb/mods/ftbjeiextras/advancedae/ReactionChamberRecipeCategory.java b/src/main/java/dev/ftb/mods/ftbjeiextras/advancedae/ReactionChamberRecipeCategory.java deleted file mode 100644 index 913e643..0000000 --- a/src/main/java/dev/ftb/mods/ftbjeiextras/advancedae/ReactionChamberRecipeCategory.java +++ /dev/null @@ -1,150 +0,0 @@ -package dev.ftb.mods.ftbjeiextras.advancedae; - -import appeng.core.AppEng; -import com.mojang.blaze3d.systems.RenderSystem; -import dev.ftb.mods.ftbjeiextras.modspecific.GlodiumHelpers; -import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; -import mezz.jei.api.gui.drawable.IDrawable; -import mezz.jei.api.gui.drawable.IDrawableAnimated; -import mezz.jei.api.gui.drawable.IDrawableStatic; -import mezz.jei.api.gui.ingredient.IRecipeSlotsView; -import mezz.jei.api.helpers.IGuiHelper; -import mezz.jei.api.helpers.IJeiHelpers; -import mezz.jei.api.recipe.IFocusGroup; -import mezz.jei.api.recipe.RecipeIngredientRole; -import mezz.jei.api.recipe.RecipeType; -import mezz.jei.api.recipe.category.IRecipeCategory; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.inventory.InventoryMenu; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; -import net.neoforged.neoforge.fluids.FluidStack; -import net.pedroksl.advanced_ae.AdvancedAE; -import net.pedroksl.advanced_ae.common.definitions.AAEBlocks; -import net.pedroksl.advanced_ae.common.definitions.AAEText; -import net.pedroksl.advanced_ae.recipes.ReactionChamberRecipe; -import org.jetbrains.annotations.Nullable; - -import java.util.List; -import java.util.Optional; - -public class ReactionChamberRecipeCategory implements IRecipeCategory { - public static final RecipeType TYPE = RecipeType.create("advanced_ae", "reaction", ReactionChamberRecipe.class); - - private static final ResourceLocation BG_ASSET = AppEng.makeId("textures/guis/reaction_chamber.png"); - private static final ResourceLocation BOLT_ASSET = AdvancedAE.makeId("textures/guis/emi.png"); // Bad name - - private IDrawableStatic background; - private IDrawable icon; - private IDrawableAnimated charge; - private IDrawableStatic boltIcon; - - private final IGuiHelper guiHelper; - - public ReactionChamberRecipeCategory(IJeiHelpers helpers) { - guiHelper = helpers.getGuiHelper(); - background = guiHelper.createDrawable(BG_ASSET, 5, 15, 168, 75); - icon = guiHelper.createDrawableItemStack(new ItemStack(AAEBlocks.REACTION_CHAMBER)); - charge = guiHelper.createAnimatedDrawable(guiHelper.createDrawable(BG_ASSET, 176, 0, 6, 18), 40, IDrawableAnimated.StartDirection.BOTTOM, false); - - boltIcon = guiHelper.createDrawable(BOLT_ASSET, 0, 0, 16, 16); - } - - @Override - public RecipeType getRecipeType() { - return TYPE; - } - - @Override - public Component getTitle() { - return Component.translatable(AAEText.EmiReactionChamber.getTranslationKey()); - } - - @Override - public IDrawable getBackground() { - return background; - } - - @Override - public @Nullable IDrawable getIcon() { - return icon; - } - - @Override - public void setRecipe(IRecipeLayoutBuilder builder, ReactionChamberRecipe recipe, IFocusGroup focuses) { - int x = 37; - for (var in : recipe.getInputs()) { - if (in.isEmpty()) { - continue; - } - - builder.addSlot(RecipeIngredientRole.INPUT, x, 9).addIngredients(GlodiumHelpers.of(in)); - x += 18; - } - - builder.addSlot(RecipeIngredientRole.OUTPUT, 113, 28).addItemStack(recipe.getResultItem()); - } - - @Override - public void draw(ReactionChamberRecipe recipe, IRecipeSlotsView recipeSlotsView, GuiGraphics guiGraphics, double mouseX, double mouseY) { - this.charge.draw(guiGraphics, 135, 27); - guiGraphics.drawString(Minecraft.getInstance().font, AAEText.ReactionChamberEnergy.text(recipe.getEnergy() / 1000), 35, 68, AAEText.TOOLTIP_DEFAULT_COLOR, false); - - guiHelper.drawableBuilder(BOLT_ASSET, 0, 0, 16, 16) - .setTextureSize(32, 32) - .build() - .draw(guiGraphics, 22, 65); - - int fluidX = 4; - int fluidY = 6; - int fluidWidth = 16; - int fluidMaxHeight = 58; - int maxAmount = 16000; - - if (recipe.getFluid() != null) { - var fluid = recipe.getFluid(); - FluidStack[] stacks = fluid.getIngredient().getStacks(); - - for (FluidStack stack : stacks) { - if (stack.isEmpty()) continue; - - IClientFluidTypeExtensions props = IClientFluidTypeExtensions.of(stack.getFluidType()); - ResourceLocation FLUID_TEXTURE = props.getStillTexture().withPrefix("textures/").withSuffix(".png"); - RenderSystem.setShader(GameRenderer::getPositionTexColorShader); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - - int color = IClientFluidTypeExtensions.of(stack.getFluid()).getTintColor(); - RenderSystem.setShaderColor((color >> 16 & 0xff) / 255f, (color >> 8 & 0xff) / 255f, (color & 0xff) / 255f, 0.9f); - - int fluidAmount = stack.getAmount(); - int fluidHeight = (int) ((fluidAmount / (float) maxAmount) * fluidMaxHeight * 2); - int renderY = fluidY + fluidMaxHeight - fluidHeight; - - guiHelper.drawableBuilder(FLUID_TEXTURE, 0, 0, fluidWidth, fluidHeight) - .setTextureSize(16, 16) - .build() - .draw(guiGraphics, fluidX, renderY); - - RenderSystem.setShaderColor(1, 1, 1, 1); - RenderSystem.disableBlend(); - - if (mouseX >= fluidX && mouseX <= fluidX + fluidWidth && mouseY >= fluidY && mouseY <= fluidY + fluidMaxHeight) { - List textComponents = List.of( - Component.literal("Fluid: ").append(Component.translatable(stack.getFluidType().getDescriptionId())), - Component.literal("Amount: " + stack.getAmount()) - ); - guiGraphics.renderTooltip(Minecraft.getInstance().font, textComponents, Optional.empty(), (int) mouseX, (int) mouseY); - } - break; - } - } - - } -} diff --git a/src/main/java/dev/ftb/mods/ftbjeiextras/advancedae/package-info.java b/src/main/java/dev/ftb/mods/ftbjeiextras/advancedae/package-info.java deleted file mode 100644 index afb3b0b..0000000 --- a/src/main/java/dev/ftb/mods/ftbjeiextras/advancedae/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -@MethodsReturnNonnullByDefault -@ParametersAreNonnullByDefault -package dev.ftb.mods.ftbjeiextras.advancedae; - -import net.minecraft.MethodsReturnNonnullByDefault; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/dev/ftb/mods/ftbjeiextras/loader/ExtendedPluginLoader.java b/src/main/java/dev/ftb/mods/ftbjeiextras/loader/ExtendedPluginLoader.java index 135e757..63d5001 100644 --- a/src/main/java/dev/ftb/mods/ftbjeiextras/loader/ExtendedPluginLoader.java +++ b/src/main/java/dev/ftb/mods/ftbjeiextras/loader/ExtendedPluginLoader.java @@ -1,8 +1,8 @@ package dev.ftb.mods.ftbjeiextras.loader; import dev.ftb.mods.ftbjeiextras.FTBJeiExtras; -import dev.ftb.mods.ftbjeiextras.advancedae.AdvancedAePlugin; import dev.ftb.mods.ftbjeiextras.extendedae.ExtendedAePlugin; +import dev.ftb.mods.ftbjeiextras.oritech.OritechPlugin; import mezz.jei.api.IModPlugin; import mezz.jei.api.JeiPlugin; import mezz.jei.api.helpers.IPlatformFluidHelper; @@ -23,7 +23,7 @@ public class ExtendedPluginLoader implements IModPlugin { final List containedPlugins = List.of( new ExtendedAePlugin(), - new AdvancedAePlugin() + new OritechPlugin() ); @Override diff --git a/src/main/java/dev/ftb/mods/ftbjeiextras/oritech/OritechParticleCollisionRecipe.java b/src/main/java/dev/ftb/mods/ftbjeiextras/oritech/OritechParticleCollisionRecipe.java new file mode 100644 index 0000000..b87a317 --- /dev/null +++ b/src/main/java/dev/ftb/mods/ftbjeiextras/oritech/OritechParticleCollisionRecipe.java @@ -0,0 +1,108 @@ +package dev.ftb.mods.ftbjeiextras.oritech; + +import dev.ftb.mods.ftbjeiextras.FTBJeiExtras; +import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; +import mezz.jei.api.gui.drawable.IDrawable; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.gui.placement.HorizontalAlignment; +import mezz.jei.api.gui.widgets.IRecipeExtrasBuilder; +import mezz.jei.api.helpers.IGuiHelper; +import mezz.jei.api.helpers.IJeiHelpers; +import mezz.jei.api.recipe.IFocusGroup; +import mezz.jei.api.recipe.RecipeIngredientRole; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.recipe.category.IRecipeCategory; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.RecipeHolder; +import org.jetbrains.annotations.Nullable; +import rearth.oritech.Oritech; +import rearth.oritech.init.BlockContent; +import rearth.oritech.init.recipes.OritechRecipe; + +public class OritechParticleCollisionRecipe implements IRecipeCategory> { + + private static final ResourceLocation PARTICLE = Oritech.id("textures/gui/modular/particle_recipe_overlay.png"); + + private final IGuiHelper guiHelper; + private final IDrawable background; + private final IDrawable icon; + private final Component title; + private final IDrawable particle; + + private final RecipeType> recipeType; + + public OritechParticleCollisionRecipe(IJeiHelpers helpers, RecipeType> recipeType) { + this.guiHelper = helpers.getGuiHelper(); + this.icon = guiHelper.createDrawableItemStack(new ItemStack(BlockContent.ACCELERATOR_CONTROLLER)); + this.background = guiHelper.createBlankDrawable(150, 66); + this.recipeType = recipeType; + this.title = Component.translatable("emi.category.oritech." + recipeType.getUid().getPath()); + this.particle = guiHelper + .drawableBuilder(PARTICLE, 0, 0, 36, 24) + .setTextureSize(36, 24) + .build(); + } + + @Override + public RecipeType> getRecipeType() { + return recipeType; + } + + @Override + public Component getTitle() { + return title; + } + + @Override + public IDrawable getBackground() { + return background; + } + + @Override + public @Nullable IDrawable getIcon() { + return icon; + } + + @Override + public void setRecipe(IRecipeLayoutBuilder builder, RecipeHolder recipeHolder, IFocusGroup focuses) { + OritechRecipe recipe = recipeHolder.value(); + + builder.addSlot(RecipeIngredientRole.INPUT, 42, 20) + .addIngredients(recipe.getInputs().get(0)); + + builder.addSlot(RecipeIngredientRole.OUTPUT, 96, 20) + .addIngredients(recipe.getInputs().get(1)); + + builder.addSlot(RecipeIngredientRole.OUTPUT, 69, 20) + .addItemStack(recipe.getResults().get(0)); + + } + + @Override + public void createRecipeExtras(IRecipeExtrasBuilder builder, RecipeHolder recipeHolder, IFocusGroup focuses) { + OritechRecipe recipe = recipeHolder.value(); + + builder.addText(Component.translatable("emi.title.oritech.collisionspeed", recipe.getTime()), getWidth(), getHeight()) + .setShadow(true) + .setTextAlignment(HorizontalAlignment.CENTER) + .setColor(0xFFFFFF) + .setPosition(0, getHeight() - Minecraft.getInstance().font.lineHeight * 2); + } + + @Override + public void draw(RecipeHolder recipeHolder, IRecipeSlotsView recipeSlotsView, GuiGraphics guiGraphics, double mouseX, double mouseY) { + + particle.draw(guiGraphics, 59, 17); + + guiHelper.getSlotDrawable() + .draw(guiGraphics, 41, 19); + + guiHelper.getSlotDrawable() + .draw(guiGraphics, 95, 19); + + } +} diff --git a/src/main/java/dev/ftb/mods/ftbjeiextras/oritech/OritechPlugin.java b/src/main/java/dev/ftb/mods/ftbjeiextras/oritech/OritechPlugin.java new file mode 100644 index 0000000..3d37ce5 --- /dev/null +++ b/src/main/java/dev/ftb/mods/ftbjeiextras/oritech/OritechPlugin.java @@ -0,0 +1,113 @@ +package dev.ftb.mods.ftbjeiextras.oritech; + +import dev.ftb.mods.ftbjeiextras.loader.IConditionalModPlugin; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.registration.IRecipeCatalystRegistration; +import mezz.jei.api.registration.IRecipeCategoryRegistration; +import mezz.jei.api.registration.IRecipeRegistration; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.RecipeHolder; +import net.minecraft.world.item.crafting.RecipeManager; +import net.neoforged.fml.ModList; +import rearth.oritech.block.entity.generators.BioGeneratorEntity; +import rearth.oritech.block.entity.generators.FuelGeneratorEntity; +import rearth.oritech.block.entity.generators.LavaGeneratorEntity; +import rearth.oritech.block.entity.generators.SteamEngineEntity; +import rearth.oritech.block.entity.processing.AssemblerBlockEntity; +import rearth.oritech.block.entity.processing.AtomicForgeBlockEntity; +import rearth.oritech.block.entity.processing.CentrifugeBlockEntity; +import rearth.oritech.block.entity.processing.FoundryBlockEntity; +import rearth.oritech.block.entity.processing.FragmentForgeBlockEntity; +import rearth.oritech.block.entity.processing.PulverizerBlockEntity; +import rearth.oritech.init.BlockContent; +import rearth.oritech.init.recipes.OritechRecipe; +import rearth.oritech.init.recipes.RecipeContent; + +import java.util.function.Supplier; + +public class OritechPlugin implements IConditionalModPlugin { + + private static final Supplier>> PULVERIZER = RecipeType.createFromDeferredVanilla(() -> RecipeContent.PULVERIZER); + private static final Supplier>> GRINDER = RecipeType.createFromDeferredVanilla(() -> RecipeContent.GRINDER); + private static final Supplier>> ASSEMBLER = RecipeType.createFromDeferredVanilla(() -> RecipeContent.ASSEMBLER); + private static final Supplier>> FOUNDRY = RecipeType.createFromDeferredVanilla(() -> RecipeContent.FOUNDRY); + private static final Supplier>> CENTRIFUGE = RecipeType.createFromDeferredVanilla(() -> RecipeContent.CENTRIFUGE); + private static final Supplier>> CENTRIFUGE_FLUID = RecipeType.createFromDeferredVanilla(() -> RecipeContent.CENTRIFUGE_FLUID); + private static final Supplier>> ATOMIC_FORGE = RecipeType.createFromDeferredVanilla(() -> RecipeContent.ATOMIC_FORGE); + + private static final Supplier>> BIO_GENERATOR = RecipeType.createFromDeferredVanilla(() -> RecipeContent.BIO_GENERATOR); + private static final Supplier>> FUEL_GENERATOR = RecipeType.createFromDeferredVanilla(() -> RecipeContent.FUEL_GENERATOR); + private static final Supplier>> LAVA_GENERATOR = RecipeType.createFromDeferredVanilla(() -> RecipeContent.LAVA_GENERATOR); + private static final Supplier>> STEAM_ENGINE = RecipeType.createFromDeferredVanilla(() -> RecipeContent.STEAM_ENGINE); + + public static final Supplier>> PARTICLE_COLLISION = RecipeType.createFromDeferredVanilla(() -> RecipeContent.PARTICLE_COLLISION); + + @Override + public void registerCategories(IRecipeCategoryRegistration registration) { + registration.addRecipeCategories( + new OritechRecipeCategory(registration.getJeiHelpers(), PULVERIZER.get(), PulverizerBlockEntity.class, BlockContent.PULVERIZER_BLOCK), + new OritechRecipeCategory(registration.getJeiHelpers(), GRINDER.get(), FragmentForgeBlockEntity.class, BlockContent.FRAGMENT_FORGE_BLOCK), + new OritechRecipeCategory(registration.getJeiHelpers(), ASSEMBLER.get(), AssemblerBlockEntity.class, BlockContent.ASSEMBLER_BLOCK), + new OritechRecipeCategory(registration.getJeiHelpers(), FOUNDRY.get(), FoundryBlockEntity.class, BlockContent.FOUNDRY_BLOCK), + new OritechRecipeCategory(registration.getJeiHelpers(), CENTRIFUGE.get(), CentrifugeBlockEntity.class, BlockContent.CENTRIFUGE_BLOCK), + new OritechRecipeCategory(registration.getJeiHelpers(), CENTRIFUGE_FLUID.get(), CentrifugeBlockEntity.class, BlockContent.CENTRIFUGE_BLOCK), + new OritechRecipeCategory(registration.getJeiHelpers(), ATOMIC_FORGE.get(), AtomicForgeBlockEntity.class, BlockContent.ATOMIC_FORGE_BLOCK), + + new OritechRecipeCategory(registration.getJeiHelpers(), BIO_GENERATOR.get(), BioGeneratorEntity.class, BlockContent.BIO_GENERATOR_BLOCK), + new OritechRecipeCategory(registration.getJeiHelpers(), FUEL_GENERATOR.get(), FuelGeneratorEntity.class, BlockContent.FUEL_GENERATOR_BLOCK), + new OritechRecipeCategory(registration.getJeiHelpers(), LAVA_GENERATOR.get(), LavaGeneratorEntity.class, BlockContent.LAVA_GENERATOR_BLOCK), + new OritechRecipeCategory(registration.getJeiHelpers(), STEAM_ENGINE.get(), SteamEngineEntity.class, BlockContent.STEAM_ENGINE_BLOCK), + + new OritechParticleCollisionRecipe(registration.getJeiHelpers(), PARTICLE_COLLISION.get()) + ); + } + + @Override + public boolean shouldLoad() { + return ModList.get().isLoaded("oritech"); + } + + @Override + public void registerRecipes(IRecipeRegistration registration) { + ClientLevel level = Minecraft.getInstance().level; + assert level != null; + + RecipeManager recipeManager = level.getRecipeManager(); + + registration.addRecipes(PULVERIZER.get(), recipeManager.getAllRecipesFor(RecipeContent.PULVERIZER)); + registration.addRecipes(GRINDER.get(), recipeManager.getAllRecipesFor(RecipeContent.GRINDER)); + registration.addRecipes(ASSEMBLER.get(), recipeManager.getAllRecipesFor(RecipeContent.ASSEMBLER)); + registration.addRecipes(FOUNDRY.get(), recipeManager.getAllRecipesFor(RecipeContent.FOUNDRY)); + registration.addRecipes(CENTRIFUGE.get(), recipeManager.getAllRecipesFor(RecipeContent.CENTRIFUGE)); + registration.addRecipes(CENTRIFUGE_FLUID.get(), recipeManager.getAllRecipesFor(RecipeContent.CENTRIFUGE_FLUID)); + registration.addRecipes(ATOMIC_FORGE.get(), recipeManager.getAllRecipesFor(RecipeContent.ATOMIC_FORGE)); + + registration.addRecipes(BIO_GENERATOR.get(), recipeManager.getAllRecipesFor(RecipeContent.BIO_GENERATOR)); + registration.addRecipes(FUEL_GENERATOR.get(), recipeManager.getAllRecipesFor(RecipeContent.FUEL_GENERATOR)); + registration.addRecipes(LAVA_GENERATOR.get(), recipeManager.getAllRecipesFor(RecipeContent.LAVA_GENERATOR)); + registration.addRecipes(STEAM_ENGINE.get(), recipeManager.getAllRecipesFor(RecipeContent.STEAM_ENGINE)); + + registration.addRecipes(PARTICLE_COLLISION.get(), recipeManager.getAllRecipesFor(RecipeContent.PARTICLE_COLLISION)); + + } + + @Override + public void registerRecipeCatalysts(IRecipeCatalystRegistration registration) { + registration.addRecipeCatalyst(new ItemStack(BlockContent.PULVERIZER_BLOCK), PULVERIZER.get()); + registration.addRecipeCatalyst(new ItemStack(BlockContent.FRAGMENT_FORGE_BLOCK), GRINDER.get()); + registration.addRecipeCatalyst(new ItemStack(BlockContent.ASSEMBLER_BLOCK), ASSEMBLER.get()); + registration.addRecipeCatalyst(new ItemStack(BlockContent.FOUNDRY_BLOCK), FOUNDRY.get()); + registration.addRecipeCatalyst(new ItemStack(BlockContent.CENTRIFUGE_BLOCK), CENTRIFUGE.get()); + registration.addRecipeCatalyst(new ItemStack(BlockContent.CENTRIFUGE_BLOCK), CENTRIFUGE_FLUID.get()); + registration.addRecipeCatalyst(new ItemStack(BlockContent.ATOMIC_FORGE_BLOCK), ATOMIC_FORGE.get()); + + registration.addRecipeCatalyst(new ItemStack(BlockContent.BIO_GENERATOR_BLOCK), BIO_GENERATOR.get()); + registration.addRecipeCatalyst(new ItemStack(BlockContent.FUEL_GENERATOR_BLOCK), FUEL_GENERATOR.get()); + registration.addRecipeCatalyst(new ItemStack(BlockContent.LAVA_GENERATOR_BLOCK), LAVA_GENERATOR.get()); + registration.addRecipeCatalyst(new ItemStack(BlockContent.STEAM_ENGINE_BLOCK), STEAM_ENGINE.get()); + + registration.addRecipeCatalyst(new ItemStack(BlockContent.ACCELERATOR_CONTROLLER), PARTICLE_COLLISION.get()); + } +} diff --git a/src/main/java/dev/ftb/mods/ftbjeiextras/oritech/OritechRecipeCategory.java b/src/main/java/dev/ftb/mods/ftbjeiextras/oritech/OritechRecipeCategory.java new file mode 100644 index 0000000..db71ccc --- /dev/null +++ b/src/main/java/dev/ftb/mods/ftbjeiextras/oritech/OritechRecipeCategory.java @@ -0,0 +1,261 @@ +package dev.ftb.mods.ftbjeiextras.oritech; + +import com.mojang.blaze3d.systems.RenderSystem; +import dev.architectury.fluid.FluidStack; +import mezz.jei.api.gui.builder.IRecipeLayoutBuilder; +import mezz.jei.api.gui.drawable.IDrawable; +import mezz.jei.api.gui.ingredient.IRecipeSlotsView; +import mezz.jei.api.gui.placement.HorizontalAlignment; +import mezz.jei.api.gui.widgets.IRecipeExtrasBuilder; +import mezz.jei.api.helpers.IGuiHelper; +import mezz.jei.api.helpers.IJeiHelpers; +import mezz.jei.api.ingredients.IIngredientRenderer; +import mezz.jei.api.neoforge.NeoForgeTypes; +import mezz.jei.api.recipe.IFocusGroup; +import mezz.jei.api.recipe.RecipeIngredientRole; +import mezz.jei.api.recipe.RecipeType; +import mezz.jei.api.recipe.category.IRecipeCategory; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.core.BlockPos; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.RecipeHolder; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.material.Fluid; +import net.neoforged.neoforge.client.extensions.common.IClientFluidTypeExtensions; +import org.jetbrains.annotations.Nullable; +import rearth.oritech.block.base.entity.MachineBlockEntity; +import rearth.oritech.block.base.entity.UpgradableGeneratorBlockEntity; +import rearth.oritech.client.ui.BasicMachineScreen; +import rearth.oritech.init.recipes.OritechRecipe; +import rearth.oritech.util.InventorySlotAssignment; +import rearth.oritech.util.ScreenProvider; + +import java.lang.reflect.InvocationTargetException; +import java.util.List; +import java.util.Optional; + +public class OritechRecipeCategory implements IRecipeCategory> { + + public static final ResourceLocation GUI_COMPONENTS = BasicMachineScreen.GUI_COMPONENTS; + + private final int offsetX = 23; + private final int offsetY = 17; + + private final MachineBlockEntity screenProvider; + private final RecipeType> recipeType; + private final IDrawable icon; + private final IDrawable background; + private final IJeiHelpers jeiHelpers; + private final IGuiHelper guiHelper; + private final Component title; + + private final List slots; + private final InventorySlotAssignment slotOffsets; + + + public OritechRecipeCategory(IJeiHelpers helpers, RecipeType> recipeType, Class screenProviderSource, ItemLike machine) { + this.jeiHelpers = helpers; + this.guiHelper = helpers.getGuiHelper(); + this.recipeType = recipeType; + this.background = guiHelper.createBlankDrawable(150, 66); + this.icon = guiHelper.createDrawableItemStack(new ItemStack(machine)); + this.title = Component.translatable("emi.category.oritech." + recipeType.getUid().getPath()); + + var blockState = Blocks.STONE.defaultBlockState(); + if (machine instanceof Block blockItem) + blockState = blockItem.defaultBlockState(); + var finalBlockState = blockState; + + try { + this.screenProvider = screenProviderSource.getDeclaredConstructor(BlockPos.class, BlockState.class).newInstance(new BlockPos(0, 0, 0), finalBlockState); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException | + NoSuchMethodException e) { + throw new RuntimeException(e); + } + + this.slots = screenProvider.getGuiSlots(); + this.slotOffsets = screenProvider.getSlots(); + + } + + @Override + public RecipeType> getRecipeType() { + return recipeType; + } + + @Override + public Component getTitle() { + return title; + } + + @Override + public IDrawable getBackground() { + return background; + } + + @Override + public @Nullable IDrawable getIcon() { + return icon; + } + + @Override + public void setRecipe(IRecipeLayoutBuilder builder, RecipeHolder recipeHolder, IFocusGroup focuses) { + OritechRecipe recipe = recipeHolder.value(); + + List inputs = recipe.getInputs(); + for (int i = 0; i < inputs.size(); i++) { + var input = inputs.get(i); + if (input.isEmpty()) continue; + + var pos = slots.get(slotOffsets.inputStart() + i); + builder.addSlot(RecipeIngredientRole.INPUT, pos.x() - offsetX, pos.y() - offsetY) + .addIngredients(input); + } + + List outputs = recipe.getResults(); + for (int i = 0; i < outputs.size(); i++) { + var output = outputs.get(i); + if (output.isEmpty()) continue; + + var pos = slots.get(slotOffsets.outputStart() + i); + builder.addSlot(RecipeIngredientRole.OUTPUT, pos.x() - offsetX, pos.y() - offsetY) + .addItemStack(output); + + } + + FluidStack fluidInput = recipe.getFluidInput(); + if (fluidInput != null && fluidInput.getAmount() > 0) { + builder.addSlot(RecipeIngredientRole.INPUT, 10, 6) + .addFluidStack(fluidInput.getFluid(), fluidInput.getAmount()) + .setCustomRenderer(NeoForgeTypes.FLUID_STACK, new CustomFluidRender(fluidInput)); + } + + FluidStack fluidOutput = recipe.getFluidOutput(); + + if (fluidOutput != null && fluidOutput.getAmount() > 0) { + builder.addSlot(RecipeIngredientRole.OUTPUT, 120, 6) + .addFluidStack(fluidOutput.getFluid(), fluidOutput.getAmount()) + .setCustomRenderer(NeoForgeTypes.FLUID_STACK, new CustomFluidRender(fluidOutput)); + } + } + + @Override + public void createRecipeExtras(IRecipeExtrasBuilder builder, RecipeHolder recipeHolder, IFocusGroup focuses) { + OritechRecipe recipe = recipeHolder.value(); + + boolean isGenerating = screenProvider instanceof UpgradableGeneratorBlockEntity; + + if (isGenerating) { + builder.addAnimatedRecipeFlame(recipe.getTime()) + .setPosition(76 - offsetX, 41 - offsetY); + } else { + builder.addAnimatedRecipeArrow(recipe.getTime()) + .setPosition(80 - offsetX, 41 - offsetY); + } + + var duration = String.format("%.0f", recipe.getTime() / 20f); + builder.addText(Component.translatable("emi.title.oritech.cookingtime", duration, recipe.getTime()), getWidth(), getHeight()) + .setShadow(true) + .setTextAlignment(HorizontalAlignment.CENTER) + .setColor(0xFFFFFF) + .setPosition(0, getHeight() - Minecraft.getInstance().font.lineHeight); + + } + + @Override + public void draw(RecipeHolder recipeHolder, IRecipeSlotsView recipeSlotsView, GuiGraphics guiGraphics, double mouseX, double mouseY) { + OritechRecipe recipe = recipeHolder.value(); + + List inputs = recipe.getInputs(); + for (int i = 0; i < inputs.size(); i++) { + var input = inputs.get(i); + if (input.isEmpty()) continue; + + var pos = slots.get(slotOffsets.inputStart() + i); + guiHelper.getSlotDrawable() + .draw(guiGraphics, pos.x() - offsetX - 1, pos.y() - offsetY - 1); + } + + + FluidStack fluidOutput = recipe.getFluidOutput(); + + if (fluidOutput != null && fluidOutput.getAmount() > 0) { + drawFluid(guiGraphics, fluidOutput, 120, 6, 16, 50, mouseX, mouseY); + } + + List outputs = recipe.getResults(); + for (int i = 0; i < outputs.size(); i++) { + var output = outputs.get(i); + if (output.isEmpty()) continue; + + var pos = slots.get(slotOffsets.outputStart() + i); + guiHelper.getSlotDrawable() + .draw(guiGraphics, pos.x() - offsetX - 1, pos.y() - offsetY - 1); + } + } + + private void drawFluid(GuiGraphics guiGraphics, FluidStack fluidInput, int fluidX, int fluidY, int fluidWidth, int fluidMaxHeight, double mouseX, double mouseY) { + IClientFluidTypeExtensions props = IClientFluidTypeExtensions.of(fluidInput.getFluid().getFluidType()); + ResourceLocation FLUID_TEXTURE = props.getStillTexture().withPrefix("textures/").withSuffix(".png"); + RenderSystem.setShader(GameRenderer::getPositionTexColorShader); + RenderSystem.enableBlend(); + RenderSystem.defaultBlendFunc(); + + int color = IClientFluidTypeExtensions.of(fluidInput.getFluid()).getTintColor(); + RenderSystem.setShaderColor((color >> 16 & 0xff) / 255f, (color >> 8 & 0xff) / 255f, (color & 0xff) / 255f, 0.9f); + + guiHelper.drawableBuilder(FLUID_TEXTURE, 0, 0, 16, 50) + .setTextureSize(16, 16) + .build() + .draw(guiGraphics, 0, 0); + + RenderSystem.setShaderColor(1, 1, 1, 1); + RenderSystem.disableBlend(); + + guiHelper.drawableBuilder(GUI_COMPONENTS, 48, 0, fluidWidth, fluidMaxHeight) + .setTextureSize(98, 96) + .build() + .draw(guiGraphics, fluidX, fluidY); + + } + + private class CustomFluidRender implements IIngredientRenderer { + private final FluidStack fluidInput; + + public CustomFluidRender(FluidStack fluidInput) { + this.fluidInput = fluidInput; + } + + @Override + public void render(GuiGraphics guiGraphics, net.neoforged.neoforge.fluids.FluidStack ingredient) { + drawFluid(guiGraphics, fluidInput, 0, 0, 16, 50, 0, 0); + } + + @Override + public List getTooltip(net.neoforged.neoforge.fluids.FluidStack ingredient, TooltipFlag tooltipFlag) { + return List.of( + Component.literal("Fluid: ").append(Component.translatable(fluidInput.getFluid().getFluidType().getDescriptionId())), + Component.literal("Amount: " + fluidInput.getAmount()) + ); + } + + @Override + public int getWidth() { + return 14; + } + + @Override + public int getHeight() { + return 50; + } + } +}