From eba71cac444991cc36ef77fbcd752c8002affdd9 Mon Sep 17 00:00:00 2001 From: Sven <5113257+mainrs@users.noreply.github.com> Date: Fri, 27 Dec 2024 10:00:00 +0000 Subject: [PATCH] feat: inventory check inspects large fluid containers (#18) Co-authored-by: Caedis Co-authored-by: Martin Robertz --- dependencies.gradle | 4 ++ .../jecalculation/data/label/ILabel.java | 53 +++++++++++++++---- .../data/label/labels/LFluidStack.java | 17 +++++- .../jecalculation/gui/guis/GuiCraft.java | 6 +++ .../jecalculation/utils/ItemStackHelper.java | 19 +++++++ 5 files changed, 87 insertions(+), 12 deletions(-) diff --git a/dependencies.gradle b/dependencies.gradle index 075e506c4..cf7cdecb1 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -22,4 +22,8 @@ dependencies { // runtime("curse.maven:cofh-core-69162:2388751") testCompile 'org.junit.jupiter:junit-jupiter-api:5.2.0' + + // Required to load in GTNH mods inside the dev environment for testing. Useful for checking item stack label + // generation. + runtimeOnlyNonPublishable("com.github.GTNewHorizons:GT5-Unofficial:5.09.48.133:dev") } diff --git a/src/main/java/me/towdium/jecalculation/data/label/ILabel.java b/src/main/java/me/towdium/jecalculation/data/label/ILabel.java index 7e4550936..1ba91f21b 100644 --- a/src/main/java/me/towdium/jecalculation/data/label/ILabel.java +++ b/src/main/java/me/towdium/jecalculation/data/label/ILabel.java @@ -1,5 +1,7 @@ package me.towdium.jecalculation.data.label; +import static me.towdium.jecalculation.utils.ItemStackHelper.isGregTechLargeFluidContainer; + import java.util.ArrayList; import java.util.EnumMap; import java.util.HashMap; @@ -23,6 +25,7 @@ import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.util.GTUtility; import me.towdium.jecalculation.JustEnoughCalculation; import me.towdium.jecalculation.data.label.labels.LFluidStack; import me.towdium.jecalculation.data.label.labels.LItemStack; @@ -194,7 +197,7 @@ public void register(String identifier, Function deseria * @param nbt NBT to deserialize * @return the recovered label * A typical NBT structure of an {@link ILabel} is as follows: - * + * *
          * {@code
          * {
@@ -258,18 +261,48 @@ public enum Priority {
             handlers.put(Priority.FALLBACK, new ArrayList<>());
         }
 
-        public static ILabel from(@Nullable Object o) {
-            if (o == null) return ILabel.EMPTY;
-            else if (o instanceof ItemStack) return new LItemStack((ItemStack) o);
-            else if (o instanceof FluidStack) return new LFluidStack((FluidStack) o);
-            else if (o instanceof EnchantmentData) {
+        /**
+         * Converts an {@code ItemStack} to its corresponding {@link ILabel} implementation.
+         *
+         * @param item The {@code ItemStack} to convert.
+         * @return A {@link LItemStack} if the passed argument is an item stack, a {@link LFluidStack} if the past
+         *         item is a fluid stack or an item stack containing a fluid. If the item is neither, returns an
+         *         instance of {@link LPlaceholder}. If the argument is {@code null}, returns an instance of
+         *         {@link ILabel.LEmpty}.
+         */
+        public static ILabel from(@Nullable Object item) {
+            if (item == null) {
+                return ILabel.EMPTY;
+            }
+
+            if (item instanceof ItemStack) {
+                // We require special handling of item stacks that contain fluids. For those, we check if they are any
+                // variant of the large fluid cell. If that is the case, we return a fluid stack instead of an item
+                // stack label. `getFluidForFilledItem` returns `null` if the cell is empty. For those cases, we still
+                // return an item stack label.
+                ItemStack itemStack = (ItemStack) item;
+                if (isGregTechLargeFluidContainer(itemStack)) {
+                    FluidStack fluidStack = GTUtility.getFluidForFilledItem(itemStack, true);
+                    if (fluidStack != null) {
+                        return new LFluidStack(fluidStack);
+                    }
+                }
+
+                return new LItemStack((ItemStack) item);
+            }
+
+            if (item instanceof FluidStack) {
+                return new LFluidStack((FluidStack) item);
+            }
+
+            if (item instanceof EnchantmentData) {
                 ItemStack itemStack = new ItemStack(Items.enchanted_book);
-                new ItemEnchantedBook().addEnchantment(itemStack, (EnchantmentData) o);
+                new ItemEnchantedBook().addEnchantment(itemStack, (EnchantmentData) item);
                 return new LItemStack(itemStack);
-            } else {
-                JustEnoughCalculation.logger.warn("Unrecognized ingredient type: " + o.getClass());
-                return LPlaceholder.Converter.from(o);
             }
+
+            JustEnoughCalculation.logger.warn("Unrecognized ingredient type: {}", item.getClass());
+            return LPlaceholder.Converter.from(item);
         }
 
         public void register(ConverterFunction handler, Priority priority) {
diff --git a/src/main/java/me/towdium/jecalculation/data/label/labels/LFluidStack.java b/src/main/java/me/towdium/jecalculation/data/label/labels/LFluidStack.java
index 185e92dd0..d21d13383 100644
--- a/src/main/java/me/towdium/jecalculation/data/label/labels/LFluidStack.java
+++ b/src/main/java/me/towdium/jecalculation/data/label/labels/LFluidStack.java
@@ -20,8 +20,7 @@
 import me.towdium.jecalculation.utils.Utilities;
 
 /**
- * Author: towdium
- * Date: 17-9-27.
+ * A label that represents some quantity of a fluid.
  */
 @ParametersAreNonnullByDefault
 public class LFluidStack extends ILabel.Impl {
@@ -30,10 +29,24 @@ public class LFluidStack extends ILabel.Impl {
     public static final String KEY_FLUID = "fluid";
     public static final String KEY_NBT = "nbt";
 
+    /**
+     * The fluid the label represents.
+     */
     Fluid fluid;
+
+    /**
+     * The fluids optional NBT tag.
+     */
     NBTTagCompound nbt;
+
+    /**
+     * An instance of {@link FluidStack} that represents the fluid inside inventories.
+     */
     FluidStack temp;
 
+    /**
+     * Returns the fluid (item) stack representation.
+     */
     @Override
     public FluidStack getRepresentation() {
         return temp;
diff --git a/src/main/java/me/towdium/jecalculation/gui/guis/GuiCraft.java b/src/main/java/me/towdium/jecalculation/gui/guis/GuiCraft.java
index 4e6582b87..fd9fc5b10 100644
--- a/src/main/java/me/towdium/jecalculation/gui/guis/GuiCraft.java
+++ b/src/main/java/me/towdium/jecalculation/gui/guis/GuiCraft.java
@@ -222,14 +222,20 @@ void refreshCalculator() {
         refreshResult();
     }
 
+    /*
+     * Gets all items in the player's inventory. Additionally, checks a list of fluid containers to see if the player
+     * carries and fluids for crafting tasks with them.
+     */
     List getInventory() {
         InventoryPlayer inv = Utilities.getPlayer().inventory;
         ArrayList labels = new ArrayList<>();
+
         Consumer add = i -> Arrays.stream(i)
             .filter(j -> !ItemStackHelper.isEmpty(j))
             .forEach(j -> labels.add(ILabel.Converter.from(j)));
         add.accept(inv.armorInventory);
         add.accept(inv.mainInventory);
+
         return labels;
     }
 
diff --git a/src/main/java/me/towdium/jecalculation/utils/ItemStackHelper.java b/src/main/java/me/towdium/jecalculation/utils/ItemStackHelper.java
index 9b8945b90..132959f99 100644
--- a/src/main/java/me/towdium/jecalculation/utils/ItemStackHelper.java
+++ b/src/main/java/me/towdium/jecalculation/utils/ItemStackHelper.java
@@ -8,7 +8,26 @@ public class ItemStackHelper {
     public static final Item EMPTY_ITEM = null;
     public static final ItemStack EMPTY_ITEM_STACK = new ItemStack((Item) null);
 
+    private static final String GREGTECH_LARGE_FLUID_CELL_ID = "gt.metaitem.01";
+
     public static boolean isEmpty(ItemStack stack) {
         return stack == null || stack == EMPTY_ITEM_STACK || stack.getItem() == EMPTY_ITEM;
     }
+
+    /**
+     * Checks if the given ItemStack is a GregTech large fluid container. This method checks for all variants of the
+     * item.
+     *
+     * @param itemStack The ItemStack to check.
+     * @return True if the ItemStack is a GregTech large fluid container, false otherwise.
+     */
+    public static boolean isGregTechLargeFluidContainer(ItemStack itemStack) {
+        Item item = itemStack.getItem();
+        if (item == null) {
+            return false;
+        }
+
+        return item.getUnlocalizedName()
+            .equals(GREGTECH_LARGE_FLUID_CELL_ID);
+    }
 }