From 6e2df56748233842055a9d35aadd5d6c619965eb Mon Sep 17 00:00:00 2001 From: Ruben Taelman Date: Fri, 6 Dec 2024 14:54:49 +0100 Subject: [PATCH] Add dedicated REI support, Closes CyclopsMC/IntegratedDynamics#1348 --- build.gradle | 8 +- .../GeneralConfig.java | 3 + .../modcompat/common/JeiReiHelpers.java | 59 +++++++++ .../jei/JEIIntegratedDynamicsConfig.java | 28 +---- .../DryingBasinRecipeCategory.java | 4 +- ...LogicProgrammerGhostIngredientHandler.java | 18 +-- .../LogicProgrammerTransferHandler.java | 14 +-- .../MechanicalDryingBasinRecipeCategory.java | 6 +- .../MechanicalSqueezerRecipeCategory.java | 8 +- .../rei/ReiIntegratedDynamicsConfig.java | 86 +++++++++++++ .../dryingbasin/ReiDryingBasinCategory.java | 91 ++++++++++++++ .../rei/dryingbasin/ReiDryingBasinRecipe.java | 50 ++++++++ .../ReiDraggableStackVisitor.java | 97 +++++++++++++++ .../ReiLogicProgrammerTransferHandler.java | 114 ++++++++++++++++++ .../ReiMechanicalDryingBasinCategory.java | 95 +++++++++++++++ .../ReiMechanicalDryingBasinRecipe.java | 50 ++++++++ .../ReiMechanicalSqueezerCategory.java | 106 ++++++++++++++++ .../ReiMechanicalSqueezerRecipe.java | 51 ++++++++ .../rei/squeezer/ReiSqueezerCategory.java | 98 +++++++++++++++ .../rei/squeezer/ReiSqueezerRecipe.java | 51 ++++++++ .../integrateddynamicscompat/lang/en_us.json | 1 + 21 files changed, 973 insertions(+), 65 deletions(-) create mode 100644 src/main/java/org/cyclops/integrateddynamicscompat/modcompat/common/JeiReiHelpers.java create mode 100644 src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/ReiIntegratedDynamicsConfig.java create mode 100644 src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/dryingbasin/ReiDryingBasinCategory.java create mode 100644 src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/dryingbasin/ReiDryingBasinRecipe.java create mode 100644 src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/logicprogrammer/ReiDraggableStackVisitor.java create mode 100644 src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/logicprogrammer/ReiLogicProgrammerTransferHandler.java create mode 100644 src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicaldryingbasin/ReiMechanicalDryingBasinCategory.java create mode 100644 src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicaldryingbasin/ReiMechanicalDryingBasinRecipe.java create mode 100644 src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicalsqueezer/ReiMechanicalSqueezerCategory.java create mode 100644 src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicalsqueezer/ReiMechanicalSqueezerRecipe.java create mode 100644 src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/squeezer/ReiSqueezerCategory.java create mode 100644 src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/squeezer/ReiSqueezerRecipe.java diff --git a/build.gradle b/build.gradle index 69d4604d..1285745a 100644 --- a/build.gradle +++ b/build.gradle @@ -136,7 +136,7 @@ dependencies { exclude group: 'org.cyclops.cyclopscore', module: 'cyclopscore' } - implementation(fg.deobf("mezz.jei:jei-${project.jei_version}")) { // https://dvs1.progwml6.com/files/maven/mezz/jei/ + compileOnly(fg.deobf("mezz.jei:jei-${project.jei_version}")) { // https://dvs1.progwml6.com/files/maven/mezz/jei/ transitive = false } compileOnly "mcjty.theoneprobe:theoneprobe:${project.theoneprobe_version}" // https://maven.k-4u.nl/mcjty/theoneprobe/theoneprobe/ @@ -154,9 +154,9 @@ dependencies { implementation fg.deobf("com.github.glitchfiend:TerraBlender-forge:${project.terrablender_version}") - compileOnly fg.deobf("me.shedaniel:RoughlyEnoughItems-forge:${rei_version}") // https://maven.shedaniel.me/me/shedaniel/RoughlyEnoughItems-forge/ - compileOnly fg.deobf("me.shedaniel.cloth:cloth-config-forge:$cloth_config_version"); - compileOnly fg.deobf("dev.architectury:architectury-forge:$architectury_version"); + implementation fg.deobf("me.shedaniel:RoughlyEnoughItems-forge:${rei_version}") // https://maven.shedaniel.me/me/shedaniel/RoughlyEnoughItems-forge/ + implementation fg.deobf("me.shedaniel.cloth:cloth-config-forge:$cloth_config_version"); + implementation fg.deobf("dev.architectury:architectury-forge:$architectury_version"); implementation fg.deobf("curse.maven:jade-324717:${jade_version}") } diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/GeneralConfig.java b/src/main/java/org/cyclops/integrateddynamicscompat/GeneralConfig.java index f00d10f2..085e2b74 100644 --- a/src/main/java/org/cyclops/integrateddynamicscompat/GeneralConfig.java +++ b/src/main/java/org/cyclops/integrateddynamicscompat/GeneralConfig.java @@ -17,6 +17,9 @@ public class GeneralConfig extends DummyConfig { @ConfigurableProperty(category = "core", comment = "If JEI recipe filling should heuristically try to determine item tags from recipes.", requiresMcRestart = true) public static boolean jeiHeuristicTags = true; + @ConfigurableProperty(category = "core", comment = "If REI recipe filling should heuristically try to determine item tags from recipes.", requiresMcRestart = true) + public static boolean reiHeuristicTags = true; + /** * Create a new instance. */ diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/common/JeiReiHelpers.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/common/JeiReiHelpers.java new file mode 100644 index 00000000..08a55691 --- /dev/null +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/common/JeiReiHelpers.java @@ -0,0 +1,59 @@ +package org.cyclops.integrateddynamicscompat.modcompat.common; + +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.registries.ForgeRegistries; +import org.cyclops.cyclopscore.helper.MinecraftHelpers; +import org.cyclops.integrateddynamics.client.gui.container.ContainerScreenLogicProgrammerBase; +import org.cyclops.integrateddynamics.core.helper.L10NValues; +import org.cyclops.integrateddynamics.inventory.container.ContainerLogicProgrammerBase; +import org.cyclops.integrateddynamicscompat.IntegratedDynamicsCompat; +import org.cyclops.integrateddynamicscompat.network.packet.CPacketSetSlot; + +import java.text.DecimalFormat; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * @author rubensworks + */ +public class JeiReiHelpers { + + public static ResourceLocation itemsToTag(List items) { + return ForgeRegistries.ITEMS.tags().stream() + .map(tag -> { + if (tag.stream().collect(Collectors.toList()).equals(items)) { + return Optional.of(tag.getKey().location()); + } + return Optional.empty(); + }) + .filter(Optional::isPresent) + .map(Optional::get) + .findFirst() + .orElse(null); + } + + public static void setStackInSlot(ContainerScreenLogicProgrammerBase screen, int slot, ItemStack itemStack) { + ContainerLogicProgrammerBase container = screen.getMenu(); + int slotPositionsCount = container.slots.size() - 36 - 4; /* subtract player inv, and 4 fixed slots in LP */ + int slotId = container.slots.size() - 36 - slotPositionsCount + slot; + container.setItem(slotId, 0, itemStack.copy()); + IntegratedDynamicsCompat._instance.getPacketHandler().sendToServer( + new CPacketSetSlot(container.containerId, slotId, itemStack)); + } + + public static MutableComponent getDurationSecondsTextComponent(int durationTicks) { + String seconds = new DecimalFormat("#.##").format((double) durationTicks / MinecraftHelpers.SECOND_IN_TICKS); + return Component.translatable("gui.integrateddynamics.jei.category.time.seconds", seconds); + } + + public static MutableComponent getEnergyTextComponent(int durationTicks, int energyPerTick) { + return Component.literal(String.format("%,d", durationTicks * energyPerTick)) + .append(Component.translatable(L10NValues.GENERAL_ENERGY_UNIT)); + } + +} diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/JEIIntegratedDynamicsConfig.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/JEIIntegratedDynamicsConfig.java index 4dd7eb5f..deb73e4e 100644 --- a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/JEIIntegratedDynamicsConfig.java +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/JEIIntegratedDynamicsConfig.java @@ -2,24 +2,12 @@ import mezz.jei.api.IModPlugin; import mezz.jei.api.JeiPlugin; -import mezz.jei.api.registration.IGuiHandlerRegistration; -import mezz.jei.api.registration.IRecipeCatalystRegistration; -import mezz.jei.api.registration.IRecipeCategoryRegistration; -import mezz.jei.api.registration.IRecipeRegistration; -import mezz.jei.api.registration.IRecipeTransferRegistration; +import mezz.jei.api.registration.*; import mezz.jei.api.runtime.IJeiRuntime; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.MutableComponent; import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; -import org.cyclops.cyclopscore.helper.MinecraftHelpers; import org.cyclops.integrateddynamics.RegistryEntries; -import org.cyclops.integrateddynamics.client.gui.container.ContainerScreenLogicProgrammer; -import org.cyclops.integrateddynamics.client.gui.container.ContainerScreenLogicProgrammerPortable; -import org.cyclops.integrateddynamics.client.gui.container.ContainerScreenMechanicalDryingBasin; -import org.cyclops.integrateddynamics.client.gui.container.ContainerScreenMechanicalSqueezer; -import org.cyclops.integrateddynamics.client.gui.container.ContainerScreenOnTheDynamicsOfIntegration; -import org.cyclops.integrateddynamics.core.helper.L10NValues; +import org.cyclops.integrateddynamics.client.gui.container.*; import org.cyclops.integrateddynamics.inventory.container.ContainerLogicProgrammer; import org.cyclops.integrateddynamics.inventory.container.ContainerLogicProgrammerPortable; import org.cyclops.integrateddynamics.inventory.container.ContainerMechanicalDryingBasin; @@ -36,8 +24,6 @@ import org.cyclops.integrateddynamicscompat.modcompat.jei.squeezer.SqueezerRecipeCategory; import org.cyclops.integrateddynamicscompat.modcompat.jei.squeezer.SqueezerRecipeJEI; -import java.text.DecimalFormat; - /** * Helper for registering JEI manager. * @author rubensworks @@ -98,14 +84,4 @@ public ResourceLocation getPluginUid() { public void onRuntimeAvailable(IJeiRuntime jeiRuntime) { this.jeiRuntime = jeiRuntime; } - - public static MutableComponent getDurationSecondsTextComponent(int durationTicks) { - String seconds = new DecimalFormat("#.##").format((double) durationTicks / MinecraftHelpers.SECOND_IN_TICKS); - return Component.translatable("gui.jei.category.smelting.time.seconds", seconds); - } - - public static MutableComponent getEnergyTextComponent(int durationTicks, int energyPerTick) { - return Component.literal(String.format("%,d", durationTicks * energyPerTick)) - .append(Component.translatable(L10NValues.GENERAL_ENERGY_UNIT)); - } } diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/dryingbasin/DryingBasinRecipeCategory.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/dryingbasin/DryingBasinRecipeCategory.java index 3d14506b..36aebbd9 100644 --- a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/dryingbasin/DryingBasinRecipeCategory.java +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/dryingbasin/DryingBasinRecipeCategory.java @@ -21,7 +21,7 @@ import net.minecraft.world.item.ItemStack; import org.cyclops.integrateddynamics.RegistryEntries; import org.cyclops.integrateddynamicscompat.Reference; -import org.cyclops.integrateddynamicscompat.modcompat.jei.JEIIntegratedDynamicsConfig; +import org.cyclops.integrateddynamicscompat.modcompat.common.JeiReiHelpers; import javax.annotation.Nonnull; @@ -90,7 +90,7 @@ public void draw(DryingBasinRecipeJEI recipe, IRecipeSlotsView recipeSlotsView, // Draw duration Font fontRenderer = Minecraft.getInstance().font; - MutableComponent duration = JEIIntegratedDynamicsConfig.getDurationSecondsTextComponent(recipe.getDuration()); + MutableComponent duration = JeiReiHelpers.getDurationSecondsTextComponent(recipe.getDuration()); fontRenderer.draw(matrixStack, duration, (background.getWidth() - fontRenderer.width(duration)) / 2 + 3, 42, 0xFF808080); } diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/logicprogrammer/LogicProgrammerGhostIngredientHandler.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/logicprogrammer/LogicProgrammerGhostIngredientHandler.java index 2b36cb8f..65c4f2c9 100644 --- a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/logicprogrammer/LogicProgrammerGhostIngredientHandler.java +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/logicprogrammer/LogicProgrammerGhostIngredientHandler.java @@ -5,8 +5,8 @@ import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; +import net.minecraftforge.common.capabilities.ForgeCapabilities; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandlerItem; import org.apache.commons.compress.utils.Lists; @@ -14,8 +14,7 @@ import org.cyclops.integrateddynamics.api.logicprogrammer.ILogicProgrammerElement; import org.cyclops.integrateddynamics.client.gui.container.ContainerScreenLogicProgrammerBase; import org.cyclops.integrateddynamics.inventory.container.ContainerLogicProgrammerBase; -import org.cyclops.integrateddynamicscompat.IntegratedDynamicsCompat; -import org.cyclops.integrateddynamicscompat.network.packet.CPacketSetSlot; +import org.cyclops.integrateddynamicscompat.modcompat.common.JeiReiHelpers; import java.util.List; @@ -38,7 +37,7 @@ public List> getTargets(T screen, I ingredient, boolean doStart) { } else if (ingredient instanceof FluidStack) { itemStack = new ItemStack(Items.BUCKET); IFluidHandlerItem fluidHandler = itemStack - .getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY) + .getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM) .orElseThrow(() -> new IllegalStateException("Could not find a fluid handler on the bucket item, some mod must be messing with things.")); fluidHandler.fill((FluidStack) ingredient, IFluidHandler.FluidAction.EXECUTE); itemStack = fluidHandler.getContainer(); @@ -68,7 +67,7 @@ public Rect2i getArea() { @Override public void accept(I ingredient) { - setStackInSlot(screen, finalSlot, finalItemStack); + JeiReiHelpers.setStackInSlot(screen, finalSlot, finalItemStack); } }); } @@ -88,13 +87,4 @@ public void onComplete() { public boolean shouldHighlightTargets() { return true; } - - protected void setStackInSlot(T screen, int slot, ItemStack itemStack) { - ContainerLogicProgrammerBase container = screen.getMenu(); - int slotPositionsCount = container.slots.size() - 36 - 4; /* subtract player inv, and 4 fixed slots in LP */ - int slotId = container.slots.size() - 36 - slotPositionsCount + slot; - container.setItem(slotId, 0, itemStack.copy()); - IntegratedDynamicsCompat._instance.getPacketHandler().sendToServer( - new CPacketSetSlot(container.containerId, slotId, itemStack)); - } } diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/logicprogrammer/LogicProgrammerTransferHandler.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/logicprogrammer/LogicProgrammerTransferHandler.java index b9af277b..772dd0ec 100644 --- a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/logicprogrammer/LogicProgrammerTransferHandler.java +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/logicprogrammer/LogicProgrammerTransferHandler.java @@ -20,13 +20,13 @@ import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.registries.ForgeRegistries; import org.cyclops.integrateddynamics.api.logicprogrammer.ILogicProgrammerElement; import org.cyclops.integrateddynamics.core.ingredient.ItemMatchProperties; import org.cyclops.integrateddynamics.core.logicprogrammer.ValueTypeRecipeLPElement; import org.cyclops.integrateddynamics.inventory.container.ContainerLogicProgrammerBase; import org.cyclops.integrateddynamicscompat.GeneralConfig; import org.cyclops.integrateddynamicscompat.IntegratedDynamicsCompat; +import org.cyclops.integrateddynamicscompat.modcompat.common.JeiReiHelpers; import org.cyclops.integrateddynamicscompat.network.packet.CPacketValueTypeRecipeLPElementSetRecipe; import javax.annotation.Nullable; @@ -87,17 +87,7 @@ protected ResourceLocation getHeuristicItemsTag(IRecipeSlotView jeiIngredient) { .map(ItemStack::getItem) .collect(Collectors.toList()); if (items.size() > 1) { - return ForgeRegistries.ITEMS.tags().stream() - .map(tag -> { - if (tag.stream().collect(Collectors.toList()).equals(items)) { - return Optional.of(tag.getKey().location()); - } - return Optional.empty(); - }) - .filter(Optional::isPresent) - .map(Optional::get) - .findFirst() - .orElse(null); + return JeiReiHelpers.itemsToTag(items); } return null; } diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/mechanicaldryingbasin/MechanicalDryingBasinRecipeCategory.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/mechanicaldryingbasin/MechanicalDryingBasinRecipeCategory.java index fb71445b..d2dfe656 100644 --- a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/mechanicaldryingbasin/MechanicalDryingBasinRecipeCategory.java +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/mechanicaldryingbasin/MechanicalDryingBasinRecipeCategory.java @@ -22,7 +22,7 @@ import org.cyclops.integrateddynamics.RegistryEntries; import org.cyclops.integrateddynamics.block.BlockMechanicalDryingBasinConfig; import org.cyclops.integrateddynamicscompat.Reference; -import org.cyclops.integrateddynamicscompat.modcompat.jei.JEIIntegratedDynamicsConfig; +import org.cyclops.integrateddynamicscompat.modcompat.common.JeiReiHelpers; import javax.annotation.Nonnull; @@ -91,10 +91,10 @@ public void draw(MechanicalDryingBasinRecipeJEI recipe, IRecipeSlotsView recipeS // Draw energy and duration Font fontRenderer = Minecraft.getInstance().font; - MutableComponent energy = JEIIntegratedDynamicsConfig.getEnergyTextComponent(recipe.getDuration(), BlockMechanicalDryingBasinConfig.consumptionRate); + MutableComponent energy = JeiReiHelpers.getEnergyTextComponent(recipe.getDuration(), BlockMechanicalDryingBasinConfig.consumptionRate); fontRenderer.draw(matrixStack, energy, (background.getWidth() - fontRenderer.width(energy)) / 2 + 3, 0, 0xFF808080); - MutableComponent duration = JEIIntegratedDynamicsConfig.getDurationSecondsTextComponent(recipe.getDuration()); + MutableComponent duration = JeiReiHelpers.getDurationSecondsTextComponent(recipe.getDuration()); fontRenderer.draw(matrixStack, duration, (background.getWidth() - fontRenderer.width(duration)) / 2 + 3, 42, 0xFF808080); } diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/mechanicalsqueezer/MechanicalSqueezerRecipeCategory.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/mechanicalsqueezer/MechanicalSqueezerRecipeCategory.java index 638aac4f..ce1eb3a4 100644 --- a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/mechanicalsqueezer/MechanicalSqueezerRecipeCategory.java +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/jei/mechanicalsqueezer/MechanicalSqueezerRecipeCategory.java @@ -20,10 +20,10 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.world.item.ItemStack; import org.cyclops.integrateddynamics.RegistryEntries; -import org.cyclops.integrateddynamics.block.BlockMechanicalDryingBasinConfig; +import org.cyclops.integrateddynamics.block.BlockMechanicalSqueezerConfig; import org.cyclops.integrateddynamics.core.recipe.type.RecipeSqueezer; import org.cyclops.integrateddynamicscompat.Reference; -import org.cyclops.integrateddynamicscompat.modcompat.jei.JEIIntegratedDynamicsConfig; +import org.cyclops.integrateddynamicscompat.modcompat.common.JeiReiHelpers; import javax.annotation.Nonnull; @@ -95,10 +95,10 @@ public void draw(MechanicalSqueezerRecipeJEI recipe, IRecipeSlotsView recipeSlot // Draw energy and duration Font fontRenderer = Minecraft.getInstance().font; - MutableComponent energy = JEIIntegratedDynamicsConfig.getEnergyTextComponent(recipe.getDuration(), BlockMechanicalDryingBasinConfig.consumptionRate); + MutableComponent energy = JeiReiHelpers.getEnergyTextComponent(recipe.getDuration(), BlockMechanicalSqueezerConfig.consumptionRate); fontRenderer.draw(matrixStack, energy, (background.getWidth() - fontRenderer.width(energy)) / 2 - 10, 0, 0xFF808080); - MutableComponent duration = JEIIntegratedDynamicsConfig.getDurationSecondsTextComponent(recipe.getDuration()); + MutableComponent duration = JeiReiHelpers.getDurationSecondsTextComponent(recipe.getDuration()); fontRenderer.draw(matrixStack, duration, (background.getWidth() - fontRenderer.width(duration)) / 2 - 10, 42, 0xFF808080); } diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/ReiIntegratedDynamicsConfig.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/ReiIntegratedDynamicsConfig.java new file mode 100644 index 00000000..42b61b7c --- /dev/null +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/ReiIntegratedDynamicsConfig.java @@ -0,0 +1,86 @@ +package org.cyclops.integrateddynamicscompat.modcompat.rei; + +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.plugins.REIClientPlugin; +import me.shedaniel.rei.api.client.registry.category.CategoryRegistry; +import me.shedaniel.rei.api.client.registry.display.DisplayRegistry; +import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry; +import me.shedaniel.rei.api.client.registry.transfer.TransferHandlerRegistry; +import me.shedaniel.rei.api.client.registry.transfer.simple.SimpleTransferHandler; +import me.shedaniel.rei.api.common.util.EntryStacks; +import me.shedaniel.rei.forge.REIPluginClient; +import org.cyclops.integrateddynamics.RegistryEntries; +import org.cyclops.integrateddynamics.client.gui.container.ContainerScreenMechanicalDryingBasin; +import org.cyclops.integrateddynamics.client.gui.container.ContainerScreenMechanicalSqueezer; +import org.cyclops.integrateddynamics.core.recipe.type.RecipeDryingBasin; +import org.cyclops.integrateddynamics.core.recipe.type.RecipeMechanicalDryingBasin; +import org.cyclops.integrateddynamics.core.recipe.type.RecipeMechanicalSqueezer; +import org.cyclops.integrateddynamics.core.recipe.type.RecipeSqueezer; +import org.cyclops.integrateddynamics.inventory.container.ContainerMechanicalDryingBasin; +import org.cyclops.integrateddynamics.inventory.container.ContainerMechanicalSqueezer; +import org.cyclops.integrateddynamicscompat.modcompat.rei.dryingbasin.ReiDryingBasinCategory; +import org.cyclops.integrateddynamicscompat.modcompat.rei.dryingbasin.ReiDryingBasinRecipe; +import org.cyclops.integrateddynamicscompat.modcompat.rei.logicprogrammer.ReiDraggableStackVisitor; +import org.cyclops.integrateddynamicscompat.modcompat.rei.logicprogrammer.ReiLogicProgrammerTransferHandler; +import org.cyclops.integrateddynamicscompat.modcompat.rei.mechanicaldryingbasin.ReiMechanicalDryingBasinCategory; +import org.cyclops.integrateddynamicscompat.modcompat.rei.mechanicaldryingbasin.ReiMechanicalDryingBasinRecipe; +import org.cyclops.integrateddynamicscompat.modcompat.rei.mechanicalsqueezer.ReiMechanicalSqueezerCategory; +import org.cyclops.integrateddynamicscompat.modcompat.rei.mechanicalsqueezer.ReiMechanicalSqueezerRecipe; +import org.cyclops.integrateddynamicscompat.modcompat.rei.squeezer.ReiSqueezerCategory; +import org.cyclops.integrateddynamicscompat.modcompat.rei.squeezer.ReiSqueezerRecipe; + +@REIPluginClient +public class ReiIntegratedDynamicsConfig implements REIClientPlugin { + @Override + public void registerTransferHandlers(TransferHandlerRegistry registry) { + registry.register(new ReiLogicProgrammerTransferHandler()); + + registry.register(SimpleTransferHandler.create( + ContainerMechanicalDryingBasin.class, + ReiMechanicalDryingBasinCategory.ID, + new SimpleTransferHandler.IntRange(0, 1) + )); + registry.register(SimpleTransferHandler.create( + ContainerMechanicalSqueezer.class, + ReiMechanicalSqueezerCategory.ID, + new SimpleTransferHandler.IntRange(0, 1) + )); + } + + @Override + public void registerScreens(ScreenRegistry registry) { + registry.registerDraggableStackVisitor(new ReiDraggableStackVisitor()); + + registry.registerContainerClickArea( + new Rectangle(84, 31, 10, 27), + ContainerScreenMechanicalDryingBasin.class, + ReiMechanicalDryingBasinCategory.ID + ); + registry.registerContainerClickArea( + new Rectangle(73, 36, 12, 18), + ContainerScreenMechanicalSqueezer.class, + ReiMechanicalSqueezerCategory.ID + ); + } + + @Override + public void registerCategories(CategoryRegistry registry) { + registry.add(new ReiDryingBasinCategory()); + registry.add(new ReiSqueezerCategory()); + registry.add(new ReiMechanicalDryingBasinCategory()); + registry.add(new ReiMechanicalSqueezerCategory()); + + registry.addWorkstations(ReiDryingBasinCategory.ID, EntryStacks.of(RegistryEntries.BLOCK_DRYING_BASIN)); + registry.addWorkstations(ReiSqueezerCategory.ID, EntryStacks.of(RegistryEntries.BLOCK_SQUEEZER)); + registry.addWorkstations(ReiMechanicalDryingBasinCategory.ID, EntryStacks.of(RegistryEntries.BLOCK_MECHANICAL_DRYING_BASIN)); + registry.addWorkstations(ReiMechanicalSqueezerCategory.ID, EntryStacks.of(RegistryEntries.BLOCK_MECHANICAL_SQUEEZER)); + } + + @Override + public void registerDisplays(DisplayRegistry registry) { + registry.registerRecipeFiller(RecipeDryingBasin.class, RegistryEntries.RECIPETYPE_DRYING_BASIN, ReiDryingBasinRecipe::new); + registry.registerRecipeFiller(RecipeSqueezer.class, RegistryEntries.RECIPETYPE_SQUEEZER, ReiSqueezerRecipe::new); + registry.registerRecipeFiller(RecipeMechanicalDryingBasin.class, RegistryEntries.RECIPETYPE_MECHANICAL_DRYING_BASIN, ReiMechanicalDryingBasinRecipe::new); + registry.registerRecipeFiller(RecipeMechanicalSqueezer.class, RegistryEntries.RECIPETYPE_MECHANICAL_SQUEEZER, ReiMechanicalSqueezerRecipe::new); + } +} diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/dryingbasin/ReiDryingBasinCategory.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/dryingbasin/ReiDryingBasinCategory.java new file mode 100644 index 00000000..d475d8e5 --- /dev/null +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/dryingbasin/ReiDryingBasinCategory.java @@ -0,0 +1,91 @@ +package org.cyclops.integrateddynamicscompat.modcompat.rei.dryingbasin; + +import com.google.common.collect.Lists; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.Renderer; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.client.registry.display.DisplayCategory; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.util.EntryStacks; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import org.cyclops.cyclopscore.helper.RenderHelpers; +import org.cyclops.integrateddynamics.Reference; +import org.cyclops.integrateddynamics.RegistryEntries; +import org.cyclops.integrateddynamicscompat.modcompat.common.JeiReiHelpers; + +import java.util.List; + +/** + * @author rubensworks + */ +public class ReiDryingBasinCategory implements DisplayCategory { + + public static final CategoryIdentifier ID = CategoryIdentifier + .of(new ResourceLocation(Reference.MOD_ID, "drying_basin")); + + private final Renderer icon; + + public ReiDryingBasinCategory() { + this.icon = EntryStacks.of(RegistryEntries.BLOCK_DRYING_BASIN); + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return ID; + } + + @Override + public Component getTitle() { + return Component.translatable(RegistryEntries.BLOCK_DRYING_BASIN.getDescriptionId()); + } + + @Override + public Renderer getIcon() { + return this.icon; + } + + @Override + public List setupDisplay(ReiDryingBasinRecipe display, Rectangle bounds) { + Point startPoint = new Point(bounds.getCenterX() - 93/2, bounds.getCenterY() - 53/2); + List widgets = Lists.newArrayList(); + + widgets.add(Widgets.createRecipeBase(bounds)); + widgets.add(Widgets.createDrawableWidget((graphics, poseStack, mouseX, mouseY, delta) -> { + ResourceLocation texture = new ResourceLocation(org.cyclops.integrateddynamicscompat.Reference.MOD_ID, "textures/gui/drying_basin_gui_jei.png"); + RenderHelpers.bindTexture(texture); + + // Background + graphics.blit(poseStack, startPoint.x, startPoint.y, 0, 0, 93, 53); + + // Progress bar + int height = Mth.ceil(System.currentTimeMillis() / 250d % 18d); + graphics.blit(poseStack, startPoint.x + 43, startPoint.y + 11 + (18 - height), 94, (18 - height), 11, height); + })); + + widgets.add(Widgets.createSlot(new Point(startPoint.x + 2, startPoint.y + 8)) + .entries(display.getInputEntries().get(0)) + .markInput()); + + widgets.add(Widgets.createSlot(new Point(startPoint.x + 76, startPoint.y + 8)) + .entries(display.getOutputEntries().get(0)) + .markInput()); + + widgets.add(Widgets.createSlot(new Rectangle(startPoint.x + 6, startPoint.y + 28, 8, 9)) + .entries(display.getInputEntries().get(1)) + .markInput()); + + widgets.add(Widgets.createSlot(new Rectangle(startPoint.x + 80, startPoint.y + 28, 8, 9)) + .entries(display.getOutputEntries().get(1)) + .markInput()); + + widgets.add(Widgets.createLabel(new Point(bounds.getCenterX(), startPoint.y + 42), JeiReiHelpers.getDurationSecondsTextComponent(display.getRecipe().getDuration())) + .color(0xFF808080) + .noShadow()); + + return widgets; + } +} diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/dryingbasin/ReiDryingBasinRecipe.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/dryingbasin/ReiDryingBasinRecipe.java new file mode 100644 index 00000000..1163f13b --- /dev/null +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/dryingbasin/ReiDryingBasinRecipe.java @@ -0,0 +1,50 @@ +package org.cyclops.integrateddynamicscompat.modcompat.rei.dryingbasin; + +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import org.apache.commons.compress.utils.Lists; +import org.cyclops.integrateddynamics.core.recipe.type.RecipeDryingBasin; + +import java.util.List; + +/** + * @author rubensworks + */ +public class ReiDryingBasinRecipe implements Display { + + private final RecipeDryingBasin recipe; + private final List inputs; + private final List outputs; + + public ReiDryingBasinRecipe(RecipeDryingBasin recipe) { + this.recipe = recipe; + this.inputs = Lists.newArrayList(); + this.outputs = Lists.newArrayList(); + + this.inputs.add(EntryIngredients.ofIngredient(recipe.getInputIngredient())); + this.inputs.add(EntryIngredients.of(recipe.getInputFluid().getFluid(), recipe.getInputFluid().getAmount())); + this.outputs.add(EntryIngredients.of(recipe.getOutputItemFirst())); + this.outputs.add(EntryIngredients.of(recipe.getOutputFluid().getFluid(), recipe.getOutputFluid().getAmount())); + } + + public RecipeDryingBasin getRecipe() { + return recipe; + } + + @Override + public List getInputEntries() { + return this.inputs; + } + + @Override + public List getOutputEntries() { + return this.outputs; + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return ReiDryingBasinCategory.ID; + } +} diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/logicprogrammer/ReiDraggableStackVisitor.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/logicprogrammer/ReiDraggableStackVisitor.java new file mode 100644 index 00000000..ab77e315 --- /dev/null +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/logicprogrammer/ReiDraggableStackVisitor.java @@ -0,0 +1,97 @@ +package org.cyclops.integrateddynamicscompat.modcompat.rei.logicprogrammer; + +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.drag.DraggableStack; +import me.shedaniel.rei.api.client.gui.drag.DraggableStackVisitor; +import me.shedaniel.rei.api.client.gui.drag.DraggedAcceptorResult; +import me.shedaniel.rei.api.client.gui.drag.DraggingContext; +import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; +import net.minecraft.client.gui.screens.Screen; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraftforge.common.capabilities.ForgeCapabilities; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.IFluidHandlerItem; +import org.apache.commons.compress.utils.Lists; +import org.cyclops.cyclopscore.helper.GuiHelpers; +import org.cyclops.cyclopscore.inventory.slot.SlotExtended; +import org.cyclops.integrateddynamics.api.logicprogrammer.ILogicProgrammerElement; +import org.cyclops.integrateddynamics.client.gui.container.ContainerScreenLogicProgrammerBase; +import org.cyclops.integrateddynamics.inventory.container.ContainerLogicProgrammerBase; +import org.cyclops.integrateddynamicscompat.modcompat.common.JeiReiHelpers; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.stream.Stream; + +/** + * @author rubensworks + */ +public class ReiDraggableStackVisitor implements DraggableStackVisitor> { + @Override + public boolean isHandingScreen(R r) { + return r instanceof ContainerScreenLogicProgrammerBase; + } + + @Nullable + public static ItemStack convertItemStack(DraggableStack stack) { + ItemStack itemStack = null; + if (stack.getStack().getType() == VanillaEntryTypes.ITEM) { + itemStack = stack.getStack().castValue(); + } else if (stack.getStack().getType() == VanillaEntryTypes.FLUID) { + itemStack = new ItemStack(Items.BUCKET); + IFluidHandlerItem fluidHandler = itemStack + .getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM) + .orElseThrow(() -> new IllegalStateException("Could not find a fluid handler on the bucket item, some mod must be messing with things.")); + fluidHandler.fill(stack.getStack().castValue(), IFluidHandler.FluidAction.EXECUTE); + itemStack = fluidHandler.getContainer(); + } + return itemStack; + } + + @Override + public Stream getDraggableAcceptingBounds(DraggingContext> context, DraggableStack stack) { + List targets = Lists.newArrayList(); + + // Determine current LP element + ContainerScreenLogicProgrammerBase screen = context.getScreen(); + ContainerLogicProgrammerBase container = screen.getMenu(); + ILogicProgrammerElement element = container.getActiveElement(); + if (element != null) { + // Determine the stack to insert in slots + ItemStack itemStack = convertItemStack(stack); + if (itemStack != null) { + // Determine slots in which the stack could be placed + int slotPositionsCount = container.slots.size() - 36 - 4; /* subtract player inv, and 4 fixed slots in LP */ + for (int slot = 0; slot < slotPositionsCount; slot++) { + int slotId = container.slots.size() - 36 - slotPositionsCount + slot; + Slot slotContainer = container.getSlot(slotId); + + Rectangle bounds = new Rectangle( + screen.getGuiLeft() + slotContainer.x - 1, + screen.getGuiTop() + slotContainer.y - 1, + GuiHelpers.SLOT_SIZE, + GuiHelpers.SLOT_SIZE + ); + if (element.isItemValidForSlot(slot, itemStack)) { + targets.add(DraggableStackVisitor.BoundsProvider.ofRectangle(bounds)); + } + } + } + } + + return targets.stream(); + } + + @Override + public DraggedAcceptorResult acceptDraggedStack(DraggingContext> context, DraggableStack stack) { + ContainerScreenLogicProgrammerBase screen = context.getScreen(); + if (screen.getSlotUnderMouse() instanceof SlotExtended slotExtended && slotExtended.isPhantom()) { + JeiReiHelpers.setStackInSlot(screen, slotExtended.getContainerSlot(), convertItemStack(stack)); + return DraggedAcceptorResult.CONSUMED; + } + + return DraggedAcceptorResult.PASS; + } +} diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/logicprogrammer/ReiLogicProgrammerTransferHandler.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/logicprogrammer/ReiLogicProgrammerTransferHandler.java new file mode 100644 index 00000000..75155f8f --- /dev/null +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/logicprogrammer/ReiLogicProgrammerTransferHandler.java @@ -0,0 +1,114 @@ +package org.cyclops.integrateddynamicscompat.modcompat.rei.logicprogrammer; + +import com.google.common.collect.Lists; +import me.shedaniel.rei.api.client.registry.transfer.TransferHandler; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.entry.EntryStack; +import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.fluids.FluidStack; +import org.cyclops.integrateddynamics.api.logicprogrammer.ILogicProgrammerElement; +import org.cyclops.integrateddynamics.core.ingredient.ItemMatchProperties; +import org.cyclops.integrateddynamics.core.logicprogrammer.ValueTypeRecipeLPElement; +import org.cyclops.integrateddynamics.inventory.container.ContainerLogicProgrammerBase; +import org.cyclops.integrateddynamicscompat.GeneralConfig; +import org.cyclops.integrateddynamicscompat.IntegratedDynamicsCompat; +import org.cyclops.integrateddynamicscompat.modcompat.common.JeiReiHelpers; +import org.cyclops.integrateddynamicscompat.network.packet.CPacketValueTypeRecipeLPElementSetRecipe; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author rubensworks + */ +public class ReiLogicProgrammerTransferHandler implements TransferHandler { + @Override + public Result handle(Context context) { + if (context.getMenu() instanceof ContainerLogicProgrammerBase container) { + ILogicProgrammerElement element = container.getActiveElement(); + + if (element instanceof ValueTypeRecipeLPElement) { + return handleRecipeElement((ValueTypeRecipeLPElement) element, container, context.getDisplay(), context.isActuallyCrafting()); + } + } + return Result.createNotApplicable(); + } + + private Result handleRecipeElement(ValueTypeRecipeLPElement element, ContainerLogicProgrammerBase container, Display display, boolean doTransfer) { + List itemInputs = Lists.newArrayList(); + List fluidInputs = Lists.newArrayList(); + List itemOutputs = Lists.newArrayList(); + List fluidOutputs = Lists.newArrayList(); + + for (EntryIngredient entry : display.getInputEntries()) { + handleEntry(entry, true, itemInputs, fluidInputs, itemOutputs, fluidOutputs); + } + for (EntryIngredient entry : display.getOutputEntries()) { + handleEntry(entry, false, itemInputs, fluidInputs, itemOutputs, fluidOutputs); + } + + if (!element.isValidForRecipeGrid(itemInputs, fluidInputs, itemOutputs, fluidOutputs)) { + return Result.createFailed(Component.translatable("error.jei.integrateddynamics.recipetransfer.recipe.toobig.desc")); + } + + if (doTransfer) { + element.setRecipeGrid(container, itemInputs, fluidInputs, itemOutputs, fluidOutputs); + IntegratedDynamicsCompat._instance.getPacketHandler().sendToServer( + new CPacketValueTypeRecipeLPElementSetRecipe(container.containerId, itemInputs, fluidInputs, itemOutputs, fluidOutputs)); + } + + return Result.createSuccessful().blocksFurtherHandling(); + } + + private void handleEntry(EntryIngredient entry, boolean input, List itemInputs, List fluidInputs, List itemOutputs, List fluidOutputs) { + if (entry.isEmpty()) { + // We assume only item slots can be empty + itemInputs.add(new ItemMatchProperties(ItemStack.EMPTY)); + } else { + EntryStack typedIngredient = entry.stream().findFirst().get(); + if (typedIngredient.getType() == VanillaEntryTypes.ITEM) { + // Collect items + if (input) { + ResourceLocation heuristicTag = getHeuristicItemsTag(entry); + if (heuristicTag != null) { + itemInputs.add(new ItemMatchProperties(ItemStack.EMPTY, false, heuristicTag.toString(), 1)); + } else { + itemInputs.add(new ItemMatchProperties(((ItemStack) typedIngredient.castValue()).copy())); + } + } else { + itemOutputs.add(((ItemStack) typedIngredient.castValue()).copy()); + } + } else if (typedIngredient.getType() == VanillaEntryTypes.FLUID) { + // Collect fluids + if (input) { + fluidInputs.add(((FluidStack) typedIngredient.castValue()).copy()); + } else { + fluidOutputs.add(((FluidStack) typedIngredient.castValue()).copy()); + } + } + } + } + + @Nullable + protected ResourceLocation getHeuristicItemsTag(EntryIngredient jeiIngredient) { + // Allow disabling this heuristic + if (!GeneralConfig.reiHeuristicTags) { + return null; + } + + List items = jeiIngredient.stream() + .map(typedIngredient -> (ItemStack) typedIngredient.castValue()) + .map(ItemStack::getItem) + .collect(Collectors.toList()); + if (items.size() > 1) { + return JeiReiHelpers.itemsToTag(items); + } + return null; + } +} diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicaldryingbasin/ReiMechanicalDryingBasinCategory.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicaldryingbasin/ReiMechanicalDryingBasinCategory.java new file mode 100644 index 00000000..fe981b3e --- /dev/null +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicaldryingbasin/ReiMechanicalDryingBasinCategory.java @@ -0,0 +1,95 @@ +package org.cyclops.integrateddynamicscompat.modcompat.rei.mechanicaldryingbasin; + +import com.google.common.collect.Lists; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.Renderer; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.client.registry.display.DisplayCategory; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.util.EntryStacks; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import org.cyclops.cyclopscore.helper.RenderHelpers; +import org.cyclops.integrateddynamics.Reference; +import org.cyclops.integrateddynamics.RegistryEntries; +import org.cyclops.integrateddynamics.block.BlockMechanicalDryingBasinConfig; +import org.cyclops.integrateddynamicscompat.modcompat.common.JeiReiHelpers; + +import java.util.List; + +/** + * @author rubensworks + */ +public class ReiMechanicalDryingBasinCategory implements DisplayCategory { + + public static final CategoryIdentifier ID = CategoryIdentifier + .of(new ResourceLocation(Reference.MOD_ID, "mechanical_drying_basin")); + + private final Renderer icon; + + public ReiMechanicalDryingBasinCategory() { + this.icon = EntryStacks.of(RegistryEntries.BLOCK_MECHANICAL_DRYING_BASIN); + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return ID; + } + + @Override + public Component getTitle() { + return Component.translatable(RegistryEntries.BLOCK_MECHANICAL_DRYING_BASIN.getDescriptionId()); + } + + @Override + public Renderer getIcon() { + return this.icon; + } + + @Override + public List setupDisplay(ReiMechanicalDryingBasinRecipe display, Rectangle bounds) { + Point startPoint = new Point(bounds.getCenterX() - 93/2, bounds.getCenterY() - 53/2); + List widgets = Lists.newArrayList(); + + widgets.add(Widgets.createRecipeBase(bounds)); + widgets.add(Widgets.createDrawableWidget((graphics, poseStack, mouseX, mouseY, delta) -> { + ResourceLocation texture = new ResourceLocation(org.cyclops.integrateddynamicscompat.Reference.MOD_ID, "textures/gui/drying_basin_gui_jei.png"); + RenderHelpers.bindTexture(texture); + + // Background + graphics.blit(poseStack, startPoint.x, startPoint.y, 0, 0, 93, 53); + + // Progress bar + int height = Mth.ceil(System.currentTimeMillis() / 250d % 18d); + graphics.blit(poseStack, startPoint.x + 43, startPoint.y + 11 + (18 - height), 94, (18 - height), 11, height); + })); + + widgets.add(Widgets.createSlot(new Point(startPoint.x + 2, startPoint.y + 8)) + .entries(display.getInputEntries().get(0)) + .markInput()); + + widgets.add(Widgets.createSlot(new Point(startPoint.x + 76, startPoint.y + 8)) + .entries(display.getOutputEntries().get(0)) + .markInput()); + + widgets.add(Widgets.createSlot(new Rectangle(startPoint.x + 6, startPoint.y + 28, 8, 9)) + .entries(display.getInputEntries().get(1)) + .markInput()); + + widgets.add(Widgets.createSlot(new Rectangle(startPoint.x + 80, startPoint.y + 28, 8, 9)) + .entries(display.getOutputEntries().get(1)) + .markInput()); + + widgets.add(Widgets.createLabel(new Point(bounds.getCenterX(), startPoint.y), JeiReiHelpers.getEnergyTextComponent(display.getRecipe().getDuration(), BlockMechanicalDryingBasinConfig.consumptionRate)) + .color(0xFF808080) + .noShadow()); + widgets.add(Widgets.createLabel(new Point(bounds.getCenterX(), startPoint.y + 42), JeiReiHelpers.getDurationSecondsTextComponent(display.getRecipe().getDuration())) + .color(0xFF808080) + .noShadow()); + + return widgets; + } +} diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicaldryingbasin/ReiMechanicalDryingBasinRecipe.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicaldryingbasin/ReiMechanicalDryingBasinRecipe.java new file mode 100644 index 00000000..5c7a8b65 --- /dev/null +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicaldryingbasin/ReiMechanicalDryingBasinRecipe.java @@ -0,0 +1,50 @@ +package org.cyclops.integrateddynamicscompat.modcompat.rei.mechanicaldryingbasin; + +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import org.apache.commons.compress.utils.Lists; +import org.cyclops.integrateddynamics.core.recipe.type.RecipeMechanicalDryingBasin; + +import java.util.List; + +/** + * @author rubensworks + */ +public class ReiMechanicalDryingBasinRecipe implements Display { + + private final RecipeMechanicalDryingBasin recipe; + private final List inputs; + private final List outputs; + + public ReiMechanicalDryingBasinRecipe(RecipeMechanicalDryingBasin recipe) { + this.recipe = recipe; + this.inputs = Lists.newArrayList(); + this.outputs = Lists.newArrayList(); + + this.inputs.add(EntryIngredients.ofIngredient(recipe.getInputIngredient())); + this.inputs.add(EntryIngredients.of(recipe.getInputFluid().getFluid(), recipe.getInputFluid().getAmount())); + this.outputs.add(EntryIngredients.of(recipe.getOutputItemFirst())); + this.outputs.add(EntryIngredients.of(recipe.getOutputFluid().getFluid(), recipe.getOutputFluid().getAmount())); + } + + public RecipeMechanicalDryingBasin getRecipe() { + return recipe; + } + + @Override + public List getInputEntries() { + return this.inputs; + } + + @Override + public List getOutputEntries() { + return this.outputs; + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return ReiMechanicalDryingBasinCategory.ID; + } +} diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicalsqueezer/ReiMechanicalSqueezerCategory.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicalsqueezer/ReiMechanicalSqueezerCategory.java new file mode 100644 index 00000000..628ce202 --- /dev/null +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicalsqueezer/ReiMechanicalSqueezerCategory.java @@ -0,0 +1,106 @@ +package org.cyclops.integrateddynamicscompat.modcompat.rei.mechanicalsqueezer; + +import com.google.common.collect.Lists; +import me.shedaniel.math.Dimension; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.Renderer; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.client.registry.display.DisplayCategory; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.api.common.util.EntryStacks; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import org.cyclops.cyclopscore.helper.RenderHelpers; +import org.cyclops.integrateddynamics.Reference; +import org.cyclops.integrateddynamics.RegistryEntries; +import org.cyclops.integrateddynamics.block.BlockMechanicalSqueezerConfig; +import org.cyclops.integrateddynamics.core.recipe.type.RecipeMechanicalSqueezer; +import org.cyclops.integrateddynamicscompat.modcompat.common.JeiReiHelpers; + +import java.util.List; + +/** + * @author rubensworks + */ +public class ReiMechanicalSqueezerCategory implements DisplayCategory { + + public static final CategoryIdentifier ID = CategoryIdentifier + .of(new ResourceLocation(Reference.MOD_ID, "mechanical_squeezer")); + + private final Renderer icon; + + public ReiMechanicalSqueezerCategory() { + this.icon = EntryStacks.of(RegistryEntries.BLOCK_MECHANICAL_SQUEEZER); + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return ID; + } + + @Override + public Component getTitle() { + return Component.translatable(RegistryEntries.BLOCK_MECHANICAL_SQUEEZER.getDescriptionId()); + } + + @Override + public Renderer getIcon() { + return this.icon; + } + + @Override + public List setupDisplay(ReiMechanicalSqueezerRecipe display, Rectangle bounds) { + RecipeMechanicalSqueezer recipe = display.getRecipe(); + Point startPoint = new Point(bounds.getCenterX() - 116/2, bounds.getCenterY() - 53/2); + List widgets = Lists.newArrayList(); + + widgets.add(Widgets.createRecipeBase(bounds)); + widgets.add(Widgets.createDrawableWidget((graphics, poseStack, mouseX, mouseY, delta) -> { + ResourceLocation texture = new ResourceLocation(org.cyclops.integrateddynamicscompat.Reference.MOD_ID, "textures/gui/mechanical_squeezer_gui_jei.png"); + RenderHelpers.bindTexture(texture); + + // Background + graphics.blit(poseStack, startPoint.x, startPoint.y, 0, 0, 116, 53); + + // Progress bar + int height = Mth.ceil(System.currentTimeMillis() / 250d % 11d); + graphics.blit(poseStack, startPoint.x + 45, startPoint.y + 21, 116, 0, 4, height); + })); + + widgets.add(Widgets.createSlot(new Point(startPoint.x + 2, startPoint.y + 18)) + .entries(display.getInputEntries().get(0)) + .markInput()); + + int offset = 0; + for (int i = 0; i < recipe.getOutputItems().size(); i++) { + RecipeMechanicalSqueezer.IngredientChance outputItem = recipe.getOutputItems().get(i); + Point point = new Point(startPoint.x + 76 + (i % 2 > 0 ? 22 : 0), startPoint.y + 8 + offset + (i > 1 ? 22 : 0)); + widgets.add(Widgets.createSlot(point.clone()) + .entries(EntryIngredients.of(outputItem.getIngredientFirst())) + .markOutput()); + point.translate(8, 8); + widgets.add(Widgets.createTooltip( + new Rectangle(point, new Dimension(8, 8)), + Component.literal("Chance: " + (outputItem.getChance() * 100.0F) + "%").withStyle(ChatFormatting.GRAY) + )); + } + + widgets.add(Widgets.createSlot(new Point(startPoint.x + 98, startPoint.y + 30)) + .entries(EntryIngredients.of(recipe.getOutputFluid().getFluid(), recipe.getOutputFluid().getAmount())) + .markInput()); + + widgets.add(Widgets.createLabel(new Point(bounds.getCenterX(), startPoint.y), JeiReiHelpers.getEnergyTextComponent(display.getRecipe().getDuration(), BlockMechanicalSqueezerConfig.consumptionRate)) + .color(0xFF808080) + .noShadow()); + widgets.add(Widgets.createLabel(new Point(bounds.getCenterX(), startPoint.y + 42), JeiReiHelpers.getDurationSecondsTextComponent(display.getRecipe().getDuration())) + .color(0xFF808080) + .noShadow()); + + return widgets; + } +} diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicalsqueezer/ReiMechanicalSqueezerRecipe.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicalsqueezer/ReiMechanicalSqueezerRecipe.java new file mode 100644 index 00000000..974894f0 --- /dev/null +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/mechanicalsqueezer/ReiMechanicalSqueezerRecipe.java @@ -0,0 +1,51 @@ +package org.cyclops.integrateddynamicscompat.modcompat.rei.mechanicalsqueezer; + +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import org.apache.commons.compress.utils.Lists; +import org.cyclops.integrateddynamics.core.recipe.type.RecipeMechanicalSqueezer; + +import java.util.List; + +/** + * @author rubensworks + */ +public class ReiMechanicalSqueezerRecipe implements Display { + + private final RecipeMechanicalSqueezer recipe; + private final List inputs; + private final List outputs; + + public ReiMechanicalSqueezerRecipe(RecipeMechanicalSqueezer recipe) { + this.recipe = recipe; + this.inputs = Lists.newArrayList(); + this.outputs = Lists.newArrayList(); + + this.inputs.add(EntryIngredients.ofIngredient(recipe.getInputIngredient())); + for (RecipeMechanicalSqueezer.IngredientChance outputItem : recipe.getOutputItems()) { + this.outputs.add(EntryIngredients.of(outputItem.getIngredientFirst())); + } + this.outputs.add(EntryIngredients.of(recipe.getOutputFluid().getFluid(), recipe.getOutputFluid().getAmount())); + } + + public RecipeMechanicalSqueezer getRecipe() { + return recipe; + } + + @Override + public List getInputEntries() { + return this.inputs; + } + + @Override + public List getOutputEntries() { + return this.outputs; + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return ReiMechanicalSqueezerCategory.ID; + } +} diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/squeezer/ReiSqueezerCategory.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/squeezer/ReiSqueezerCategory.java new file mode 100644 index 00000000..5e61d637 --- /dev/null +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/squeezer/ReiSqueezerCategory.java @@ -0,0 +1,98 @@ +package org.cyclops.integrateddynamicscompat.modcompat.rei.squeezer; + +import com.google.common.collect.Lists; +import me.shedaniel.math.Dimension; +import me.shedaniel.math.Point; +import me.shedaniel.math.Rectangle; +import me.shedaniel.rei.api.client.gui.Renderer; +import me.shedaniel.rei.api.client.gui.widgets.Widget; +import me.shedaniel.rei.api.client.gui.widgets.Widgets; +import me.shedaniel.rei.api.client.registry.display.DisplayCategory; +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import me.shedaniel.rei.api.common.util.EntryStacks; +import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import org.cyclops.cyclopscore.helper.RenderHelpers; +import org.cyclops.integrateddynamics.Reference; +import org.cyclops.integrateddynamics.RegistryEntries; +import org.cyclops.integrateddynamics.core.recipe.type.RecipeSqueezer; + +import java.util.List; + +/** + * @author rubensworks + */ +public class ReiSqueezerCategory implements DisplayCategory { + + public static final CategoryIdentifier ID = CategoryIdentifier + .of(new ResourceLocation(Reference.MOD_ID, "squeezer")); + + private final Renderer icon; + + public ReiSqueezerCategory() { + this.icon = EntryStacks.of(RegistryEntries.BLOCK_SQUEEZER); + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return ID; + } + + @Override + public Component getTitle() { + return Component.translatable(RegistryEntries.BLOCK_SQUEEZER.getDescriptionId()); + } + + @Override + public Renderer getIcon() { + return this.icon; + } + + @Override + public List setupDisplay(ReiSqueezerRecipe display, Rectangle bounds) { + RecipeSqueezer recipe = display.getRecipe(); + Point startPoint = new Point(bounds.getCenterX() - 116/2, bounds.getCenterY() - 53/2); + List widgets = Lists.newArrayList(); + + widgets.add(Widgets.createRecipeBase(bounds)); + widgets.add(Widgets.createDrawableWidget((graphics, poseStack, mouseX, mouseY, delta) -> { + ResourceLocation texture = new ResourceLocation(org.cyclops.integrateddynamicscompat.Reference.MOD_ID, "textures/gui/squeezer_gui_jei.png"); + RenderHelpers.bindTexture(texture); + + // Background + graphics.blit(poseStack, startPoint.x, startPoint.y, 0, 0, 116, 53); + + // Progress bar + int height = Mth.ceil(Minecraft.getInstance().level.getGameTime() / 4d % 7d); + graphics.blit(poseStack, startPoint.x + 41, startPoint.y + 18 + height * 2, 41, 32, 13, 2); + })); + + widgets.add(Widgets.createSlot(new Point(startPoint.x + 2, startPoint.y + 18)) + .entries(display.getInputEntries().get(0)) + .markInput()); + + int offset = 0; + for (int i = 0; i < recipe.getOutputItems().size(); i++) { + RecipeSqueezer.IngredientChance outputItem = recipe.getOutputItems().get(i); + Point point = new Point(startPoint.x + 76 + (i % 2 > 0 ? 22 : 0), startPoint.y + 8 + offset + (i > 1 ? 22 : 0)); + widgets.add(Widgets.createSlot(point.clone()) + .entries(EntryIngredients.of(outputItem.getIngredientFirst())) + .markOutput()); + point.translate(8, 8); + widgets.add(Widgets.createTooltip( + new Rectangle(point, new Dimension(8, 8)), + Component.literal("Chance: " + (outputItem.getChance() * 100.0F) + "%").withStyle(ChatFormatting.GRAY) + )); + } + + widgets.add(Widgets.createSlot(new Point(startPoint.x + 98, startPoint.y + 30)) + .entries(EntryIngredients.of(recipe.getOutputFluid().getFluid(), recipe.getOutputFluid().getAmount())) + .markInput()); + + return widgets; + } +} diff --git a/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/squeezer/ReiSqueezerRecipe.java b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/squeezer/ReiSqueezerRecipe.java new file mode 100644 index 00000000..b90a46a0 --- /dev/null +++ b/src/main/java/org/cyclops/integrateddynamicscompat/modcompat/rei/squeezer/ReiSqueezerRecipe.java @@ -0,0 +1,51 @@ +package org.cyclops.integrateddynamicscompat.modcompat.rei.squeezer; + +import me.shedaniel.rei.api.common.category.CategoryIdentifier; +import me.shedaniel.rei.api.common.display.Display; +import me.shedaniel.rei.api.common.entry.EntryIngredient; +import me.shedaniel.rei.api.common.util.EntryIngredients; +import org.apache.commons.compress.utils.Lists; +import org.cyclops.integrateddynamics.core.recipe.type.RecipeSqueezer; + +import java.util.List; + +/** + * @author rubensworks + */ +public class ReiSqueezerRecipe implements Display { + + private final RecipeSqueezer recipe; + private final List inputs; + private final List outputs; + + public ReiSqueezerRecipe(RecipeSqueezer recipe) { + this.recipe = recipe; + this.inputs = Lists.newArrayList(); + this.outputs = Lists.newArrayList(); + + this.inputs.add(EntryIngredients.ofIngredient(recipe.getInputIngredient())); + for (RecipeSqueezer.IngredientChance outputItem : recipe.getOutputItems()) { + this.outputs.add(EntryIngredients.of(outputItem.getIngredientFirst())); + } + this.outputs.add(EntryIngredients.of(recipe.getOutputFluid().getFluid(), recipe.getOutputFluid().getAmount())); + } + + public RecipeSqueezer getRecipe() { + return recipe; + } + + @Override + public List getInputEntries() { + return this.inputs; + } + + @Override + public List getOutputEntries() { + return this.outputs; + } + + @Override + public CategoryIdentifier getCategoryIdentifier() { + return ReiSqueezerCategory.ID; + } +} diff --git a/src/main/resources/assets/integrateddynamicscompat/lang/en_us.json b/src/main/resources/assets/integrateddynamicscompat/lang/en_us.json index 4d305cb6..790dd9f9 100644 --- a/src/main/resources/assets/integrateddynamicscompat/lang/en_us.json +++ b/src/main/resources/assets/integrateddynamicscompat/lang/en_us.json @@ -27,6 +27,7 @@ "_comment": "# ----- JEI ----- ##", "error.jei.integrateddynamics.recipetransfer.recipe.toobig.desc": "Too big for the Logic Programmer recipe pattern.", + "gui.integrateddynamics.jei.category.time.seconds": "%ss", "_comment": "# ----- Charset ----- ##",