From 88d341976c420cd1daf11e342a834d6413bd6889 Mon Sep 17 00:00:00 2001 From: Tech22 Date: Wed, 30 Jun 2021 04:15:30 -0400 Subject: [PATCH 1/3] start work on recipe division for distilleries --- .../java/gregtech/api/recipes/RecipeMaps.java | 2 +- .../UniversalDistillationRecipeBuilder.java | 15 +- .../java/gregtech/api/util/GTUtility.java | 190 +++++++++++++++++- .../recipe/chemistry/DistillationRecipes.java | 6 +- 4 files changed, 204 insertions(+), 9 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/RecipeMaps.java b/src/main/java/gregtech/api/recipes/RecipeMaps.java index 4e22e10ce2a..a618dd043f3 100644 --- a/src/main/java/gregtech/api/recipes/RecipeMaps.java +++ b/src/main/java/gregtech/api/recipes/RecipeMaps.java @@ -269,7 +269,7 @@ public class RecipeMaps { */ @ZenProperty - public static final RecipeMap DISTILLERY_RECIPES = new RecipeMap<>("distillery", 1, 1, 0, 0, 1, 1, 1, 1, new IntCircuitRecipeBuilder()) + public static final RecipeMap DISTILLERY_RECIPES = new RecipeMap<>("distillery", 1, 1, 0, 1, 1, 1, 1, 1, new IntCircuitRecipeBuilder()) .setProgressBar(GuiTextures.PROGRESS_BAR_ARROW_MULTIPLE, MoveType.HORIZONTAL); /** diff --git a/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java index 0e4ea2dfaa3..f19e23bc4d6 100644 --- a/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java @@ -4,6 +4,7 @@ import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; +import gregtech.api.util.GTUtility; import gregtech.api.util.ValidationResult; import net.minecraftforge.fluids.FluidStack; @@ -28,12 +29,20 @@ public UniversalDistillationRecipeBuilder copy() { @Override public void buildAndRegister() { IntCircuitRecipeBuilder builder = RecipeMaps.DISTILLERY_RECIPES.recipeBuilder() - .fluidInputs(this.fluidInputs.toArray(new FluidStack[0])) - .duration(this.duration * 2) .EUt(this.EUt / 4); + //todo do this on a per-output basis + int ratio = GTUtility.getRatioForDistillation(this.fluidInputs, this.fluidOutputs, this.outputs); + for (int i = 0; i < fluidOutputs.size(); i++) { - builder.copy().circuitMeta(i).fluidOutputs(this.fluidOutputs.get(i)).buildAndRegister(); + builder.copy() + .circuitMeta(i + 1) + .fluidInputs(new FluidStack(this.fluidInputs.get(0), this.fluidInputs.get(0).amount / ratio)) //todo fluid inputs must not be reduced to smaller than 25mB + .fluidOutputs(new FluidStack(this.fluidOutputs.get(i), this.fluidOutputs.get(i).amount / ratio)) + .duration(this.EUt > 16 ? (int) (this.duration * 2.8f / ratio) : this.duration * 2 / ratio) + //todo figure out how to do outputs without creating broken recipes + .outputs(this.outputs) + .buildAndRegister(); } super.buildAndRegister(); diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index a9463a7c3fb..dd9bee26321 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -9,11 +9,16 @@ import gregtech.api.gui.ModularUI; import gregtech.api.gui.impl.ModularUIContainer; import gregtech.api.items.IToolItem; +import gregtech.api.items.metaitem.MetaItem; +import gregtech.api.items.metaitem.stats.IItemBehaviour; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.common.ConfigHolder; +import gregtech.common.items.behaviors.CoverPlaceBehavior; +import gregtech.common.items.behaviors.CrowbarBehaviour; import net.minecraft.block.Block; import net.minecraft.block.BlockRedstoneWire; +import net.minecraft.block.material.Material; import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; @@ -33,8 +38,7 @@ import net.minecraft.potion.PotionEffect; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.*; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.*; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.common.BiomeDictionary; @@ -716,4 +720,186 @@ public static Comparator createItemStackComparator() { public static int getRandomIntXSTR(int bound) { return random.nextInt(bound); } + + public static RayTraceResult getBlockLookingAt(EntityPlayer player) { + Vec3d pos2 = player.getPositionVector().add(0, player.getEyeHeight(), 0); + RayTraceResult result = player.world.rayTraceBlocks(pos2, pos2.add(player.getLookVec().scale(12)), false, true, true); + if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) + return result; + return null; + } + + public static RayTraceResult getBlockLookingAt(EntityPlayer player, BlockPos exclude) { + Vec3d pos2 = player.getPositionVector().add(0, player.getEyeHeight(), 0); + RayTraceResult result = rayTraceBlocks(pos2, pos2.add(player.getLookVec().scale(12)), false, true, true, player.world, exclude); + if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) + return result; + return null; + } + + public static RayTraceResult rayTraceBlocks(Vec3d vec31, Vec3d vec32, boolean stopOnLiquid, boolean ignoreBlockWithoutBoundingBox, boolean returnLastUncollidableBlock, World world, BlockPos ignore) { + if (!Double.isNaN(vec31.x) && !Double.isNaN(vec31.y) && !Double.isNaN(vec31.z)) { + if (!Double.isNaN(vec32.x) && !Double.isNaN(vec32.y) && !Double.isNaN(vec32.z)) { + int i = MathHelper.floor(vec32.x); + int j = MathHelper.floor(vec32.y); + int k = MathHelper.floor(vec32.z); + int l = MathHelper.floor(vec31.x); + int i1 = MathHelper.floor(vec31.y); + int j1 = MathHelper.floor(vec31.z); + BlockPos blockpos = new BlockPos(l, i1, j1); + IBlockState iblockstate = world.getBlockState(blockpos); + Block block = iblockstate.getBlock(); + + if ((!ignoreBlockWithoutBoundingBox || iblockstate.getCollisionBoundingBox(world, blockpos) != Block.NULL_AABB) && block.canCollideCheck(iblockstate, stopOnLiquid) && !arePosEqual(ignore, blockpos)) + return iblockstate.collisionRayTrace(world, blockpos, vec31, vec32); + + RayTraceResult raytraceresult2 = null; + int k1 = 200; + + while (k1-- >= 0) { + if (Double.isNaN(vec31.x) || Double.isNaN(vec31.y) || Double.isNaN(vec31.z)) + return null; + + if (l == i && i1 == j && j1 == k) + return returnLastUncollidableBlock ? raytraceresult2 : null; + + boolean flag2 = true; + boolean flag = true; + boolean flag1 = true; + double d0 = 999.0D; + double d1 = 999.0D; + double d2 = 999.0D; + + if (i > l) + d0 = (double)l + 1.0D; + else if (i < l) + d0 = (double)l + 0.0D; + else + flag2 = false; + + if (j > i1) + d1 = (double)i1 + 1.0D; + else if (j < i1) + d1 = (double)i1 + 0.0D; + else + flag = false; + + if (k > j1) + d2 = (double)j1 + 1.0D; + else if (k < j1) + d2 = (double)j1 + 0.0D; + else + flag1 = false; + + double d3 = 999.0D; + double d4 = 999.0D; + double d5 = 999.0D; + double d6 = vec32.x - vec31.x; + double d7 = vec32.y - vec31.y; + double d8 = vec32.z - vec31.z; + + if (flag2) + d3 = (d0 - vec31.x) / d6; + + if (flag) + d4 = (d1 - vec31.y) / d7; + + if (flag1) + d5 = (d2 - vec31.z) / d8; + + if (d3 == -0.0D) + d3 = -1.0E-4D; + + if (d4 == -0.0D) + d4 = -1.0E-4D; + + if (d5 == -0.0D) + d5 = -1.0E-4D; + + EnumFacing enumfacing; + + if (d3 < d4 && d3 < d5) { + enumfacing = i > l ? EnumFacing.WEST : EnumFacing.EAST; + vec31 = new Vec3d(d0, vec31.y + d7 * d3, vec31.z + d8 * d3); + } else if (d4 < d5) { + enumfacing = j > i1 ? EnumFacing.DOWN : EnumFacing.UP; + vec31 = new Vec3d(vec31.x + d6 * d4, d1, vec31.z + d8 * d4); + } else { + enumfacing = k > j1 ? EnumFacing.NORTH : EnumFacing.SOUTH; + vec31 = new Vec3d(vec31.x + d6 * d5, vec31.y + d7 * d5, d2); + } + + l = MathHelper.floor(vec31.x) - (enumfacing == EnumFacing.EAST ? 1 : 0); + i1 = MathHelper.floor(vec31.y) - (enumfacing == EnumFacing.UP ? 1 : 0); + j1 = MathHelper.floor(vec31.z) - (enumfacing == EnumFacing.SOUTH ? 1 : 0); + blockpos = new BlockPos(l, i1, j1); + IBlockState iblockstate1 = world.getBlockState(blockpos); + Block block1 = iblockstate1.getBlock(); + + if (!ignoreBlockWithoutBoundingBox || iblockstate1.getMaterial() == Material.PORTAL || iblockstate1.getCollisionBoundingBox(world, blockpos) != Block.NULL_AABB && !arePosEqual(blockpos, ignore)) { + if (block1.canCollideCheck(iblockstate1, stopOnLiquid)) { + return iblockstate1.collisionRayTrace(world, blockpos, vec31, vec32); + } else { + raytraceresult2 = new RayTraceResult(RayTraceResult.Type.MISS, vec31, enumfacing, blockpos); + } + } + } + return returnLastUncollidableBlock ? raytraceresult2 : null; + } else return null; + } else return null; + } + + public static boolean arePosEqual(BlockPos pos1, BlockPos pos2) { + return pos1.getX() == pos2.getX() & pos1.getY() == pos2.getY() & pos1.getZ() == pos2.getZ(); + } + + public static boolean isCoverBehaviorItem(ItemStack itemStack) { + if (itemStack.getItem() instanceof MetaItem) { + MetaItem metaItem = (MetaItem) itemStack.getItem(); + MetaItem.MetaValueItem valueItem = metaItem.getItem(itemStack); + if (valueItem != null) { + List behaviourList = valueItem.getBehaviours(); + return behaviourList.stream().anyMatch(it -> + it instanceof CoverPlaceBehavior || it instanceof CrowbarBehaviour); + } + } + return false; + } + + public static int getRatioForDistillation(List fluidInputs, List fluidOutputs, List outputs) { + int[] divisors = new int[]{2, 5, 10}; + int ratio = -1; + + for (int divisor : divisors) { + + if (!(checkFluidStackDivisibility(fluidInputs, divisor))) + continue; + + if (!(checkFluidStackDivisibility(fluidOutputs, divisor))) + continue; + + if (!(checkItemStackDivisibility(outputs, divisor))) + continue; + + ratio = divisor; + } + + return Math.max(1, ratio); + } + + private static boolean checkFluidStackDivisibility(List fluidStacks, int divisor) { + for (FluidStack fluidStack : fluidStacks) { + if (fluidStack.amount % divisor != 0) + return false; + } + return true; + } + + private static boolean checkItemStackDivisibility(List itemStacks, int divisor) { + for (ItemStack itemStack : itemStacks) { + if (itemStack.getCount() % divisor != 0) + return false; + } + return true; + } } diff --git a/src/main/java/gregtech/loaders/recipe/chemistry/DistillationRecipes.java b/src/main/java/gregtech/loaders/recipe/chemistry/DistillationRecipes.java index 2b62cd92c90..df8c4fa2174 100644 --- a/src/main/java/gregtech/loaders/recipe/chemistry/DistillationRecipes.java +++ b/src/main/java/gregtech/loaders/recipe/chemistry/DistillationRecipes.java @@ -345,19 +345,19 @@ public static void init() { .duration(32).EUt(24).buildAndRegister(); DISTILLERY_RECIPES.recipeBuilder() - .circuitMeta(4) + .circuitMeta(5) .fluidInputs(OilLight.getFluid(300)) .fluidOutputs(Oil.getFluid(100)) .duration(16).EUt(24).buildAndRegister(); DISTILLERY_RECIPES.recipeBuilder() - .circuitMeta(4) + .circuitMeta(5) .fluidInputs(OilMedium.getFluid(200)) .fluidOutputs(Oil.getFluid(100)) .duration(16).EUt(24).buildAndRegister(); DISTILLERY_RECIPES.recipeBuilder() - .circuitMeta(4) + .circuitMeta(5) .fluidInputs(OilHeavy.getFluid(100)) .fluidOutputs(Oil.getFluid(100)) .duration(16).EUt(24).buildAndRegister(); From 8bccbc51a53145695ebdf0a2c138aa914dda4cdc Mon Sep 17 00:00:00 2001 From: Tech22 Date: Sat, 3 Jul 2021 18:57:26 -0400 Subject: [PATCH 2/3] finish distillery logic --- .../UniversalDistillationRecipeBuilder.java | 82 +++++++++++++++---- .../java/gregtech/api/util/GTUtility.java | 37 --------- 2 files changed, 68 insertions(+), 51 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java index f19e23bc4d6..c91fa9508f8 100644 --- a/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java @@ -4,8 +4,8 @@ import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; -import gregtech.api.util.GTUtility; import gregtech.api.util.ValidationResult; +import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; public class UniversalDistillationRecipeBuilder extends RecipeBuilder { @@ -28,21 +28,46 @@ public UniversalDistillationRecipeBuilder copy() { @Override public void buildAndRegister() { - IntCircuitRecipeBuilder builder = RecipeMaps.DISTILLERY_RECIPES.recipeBuilder() - .EUt(this.EUt / 4); + for (int i = 0; i < fluidOutputs.size(); i++) { + IntCircuitRecipeBuilder builder = RecipeMaps.DISTILLERY_RECIPES.recipeBuilder().copy().EUt(this.EUt / 4).circuitMeta(i + 1); - //todo do this on a per-output basis - int ratio = GTUtility.getRatioForDistillation(this.fluidInputs, this.fluidOutputs, this.outputs); + int ratio = getRatioForDistillery(this.fluidInputs.get(0), this.fluidOutputs.get(i), this.outputs.size() > 0 ? this.outputs.get(0) : null); - for (int i = 0; i < fluidOutputs.size(); i++) { - builder.copy() - .circuitMeta(i + 1) - .fluidInputs(new FluidStack(this.fluidInputs.get(0), this.fluidInputs.get(0).amount / ratio)) //todo fluid inputs must not be reduced to smaller than 25mB - .fluidOutputs(new FluidStack(this.fluidOutputs.get(i), this.fluidOutputs.get(i).amount / ratio)) - .duration(this.EUt > 16 ? (int) (this.duration * 2.8f / ratio) : this.duration * 2 / ratio) - //todo figure out how to do outputs without creating broken recipes - .outputs(this.outputs) - .buildAndRegister(); + int recipeDuration = this.EUt > 16 ? (int) (this.duration * 2.8f) : this.duration * 2; + + boolean shouldDivide = ratio != 1; + + boolean fluidsDivisible = isFluidStackDivisibleForDistillery(this.fluidInputs.get(0), ratio) && + isFluidStackDivisibleForDistillery(this.fluidOutputs.get(i), ratio); + + FluidStack dividedInputFluid = new FluidStack(this.fluidInputs.get(0), Math.max(1, this.fluidInputs.get(0).amount / ratio)); + FluidStack dividedOutputFluid = new FluidStack(this.fluidOutputs.get(i), Math.max(1, this.fluidOutputs.get(i).amount / ratio)); + + if (shouldDivide && fluidsDivisible) + builder.fluidInputs(dividedInputFluid) + .fluidOutputs(dividedOutputFluid) + .duration(recipeDuration / ratio); + + else if (!shouldDivide) { + builder.fluidInputs(this.fluidInputs.get(0)) + .fluidOutputs(this.fluidOutputs.get(i)) + .outputs(this.outputs) + .duration(recipeDuration) + .buildAndRegister(); + continue; + } + + if (this.outputs.size() > 0) { + boolean itemsDivisible = isItemStackDivisibleForDistillery(this.outputs.get(0), ratio) && fluidsDivisible; + + if (fluidsDivisible && itemsDivisible) { + ItemStack stack = this.outputs.get(0).copy(); + stack.setCount(stack.getCount() / ratio); + + builder.outputs(stack); + } + } + builder.buildAndRegister(); } super.buildAndRegister(); @@ -53,4 +78,33 @@ public ValidationResult build() { new Recipe(inputs, outputs, chancedOutputs, fluidInputs, fluidOutputs, duration, EUt, hidden)); } + private int getRatioForDistillery(FluidStack fluidInput, FluidStack fluidOutput, ItemStack output) { + int[] divisors = new int[]{2, 5, 10}; + int ratio = -1; + + for (int divisor : divisors) { + + if (!(isFluidStackDivisibleForDistillery(fluidInput, divisor))) + continue; + + if (!(isFluidStackDivisibleForDistillery(fluidOutput, divisor))) + continue; + + if (output != null && !(isItemStackDivisibleForDistillery(output, divisor))) + continue; + + ratio = divisor; + } + + return Math.max(1, ratio); + } + + private boolean isFluidStackDivisibleForDistillery(FluidStack fluidStack, int divisor) { + return fluidStack.amount % divisor == 0 && fluidStack.amount / divisor > 25 && fluidStack.amount % divisor != fluidStack.amount && fluidStack.amount / divisor != 0; + } + + private boolean isItemStackDivisibleForDistillery(ItemStack itemStack, int divisor) { + return itemStack.getCount() % divisor == 0 && itemStack.getCount() % divisor != itemStack.getCount() && itemStack.getCount() / divisor != 0; + } + } diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index dd9bee26321..cfd3c0be4ba 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -865,41 +865,4 @@ public static boolean isCoverBehaviorItem(ItemStack itemStack) { } return false; } - - public static int getRatioForDistillation(List fluidInputs, List fluidOutputs, List outputs) { - int[] divisors = new int[]{2, 5, 10}; - int ratio = -1; - - for (int divisor : divisors) { - - if (!(checkFluidStackDivisibility(fluidInputs, divisor))) - continue; - - if (!(checkFluidStackDivisibility(fluidOutputs, divisor))) - continue; - - if (!(checkItemStackDivisibility(outputs, divisor))) - continue; - - ratio = divisor; - } - - return Math.max(1, ratio); - } - - private static boolean checkFluidStackDivisibility(List fluidStacks, int divisor) { - for (FluidStack fluidStack : fluidStacks) { - if (fluidStack.amount % divisor != 0) - return false; - } - return true; - } - - private static boolean checkItemStackDivisibility(List itemStacks, int divisor) { - for (ItemStack itemStack : itemStacks) { - if (itemStack.getCount() % divisor != 0) - return false; - } - return true; - } } From 7ba78ba12b75ebabaf18dfc2b863f3da81c8eaf7 Mon Sep 17 00:00:00 2001 From: Tech22 Date: Sat, 3 Jul 2021 19:26:02 -0400 Subject: [PATCH 3/3] Make division logic in GTUtility --- .../UniversalDistillationRecipeBuilder.java | 13 +++----- .../java/gregtech/api/util/GTUtility.java | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java b/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java index c91fa9508f8..124421e720c 100644 --- a/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java +++ b/src/main/java/gregtech/api/recipes/builders/UniversalDistillationRecipeBuilder.java @@ -4,6 +4,7 @@ import gregtech.api.recipes.RecipeBuilder; import gregtech.api.recipes.RecipeMap; import gregtech.api.recipes.RecipeMaps; +import gregtech.api.util.GTUtility; import gregtech.api.util.ValidationResult; import net.minecraft.item.ItemStack; import net.minecraftforge.fluids.FluidStack; @@ -58,7 +59,7 @@ else if (!shouldDivide) { } if (this.outputs.size() > 0) { - boolean itemsDivisible = isItemStackDivisibleForDistillery(this.outputs.get(0), ratio) && fluidsDivisible; + boolean itemsDivisible = GTUtility.isItemStackCountDivisible(this.outputs.get(0), ratio) && fluidsDivisible; if (fluidsDivisible && itemsDivisible) { ItemStack stack = this.outputs.get(0).copy(); @@ -79,7 +80,7 @@ public ValidationResult build() { } private int getRatioForDistillery(FluidStack fluidInput, FluidStack fluidOutput, ItemStack output) { - int[] divisors = new int[]{2, 5, 10}; + int[] divisors = new int[]{2, 5, 10, 25, 50}; int ratio = -1; for (int divisor : divisors) { @@ -90,7 +91,7 @@ private int getRatioForDistillery(FluidStack fluidInput, FluidStack fluidOutput, if (!(isFluidStackDivisibleForDistillery(fluidOutput, divisor))) continue; - if (output != null && !(isItemStackDivisibleForDistillery(output, divisor))) + if (output != null && !(GTUtility.isItemStackCountDivisible(output, divisor))) continue; ratio = divisor; @@ -100,11 +101,7 @@ private int getRatioForDistillery(FluidStack fluidInput, FluidStack fluidOutput, } private boolean isFluidStackDivisibleForDistillery(FluidStack fluidStack, int divisor) { - return fluidStack.amount % divisor == 0 && fluidStack.amount / divisor > 25 && fluidStack.amount % divisor != fluidStack.amount && fluidStack.amount / divisor != 0; - } - - private boolean isItemStackDivisibleForDistillery(ItemStack itemStack, int divisor) { - return itemStack.getCount() % divisor == 0 && itemStack.getCount() % divisor != itemStack.getCount() && itemStack.getCount() / divisor != 0; + return GTUtility.isFluidStackAmountDivisible(fluidStack, divisor) && fluidStack.amount / divisor >= 25; } } diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index cfd3c0be4ba..9c8e42fef22 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -865,4 +865,36 @@ public static boolean isCoverBehaviorItem(ItemStack itemStack) { } return false; } + + public static int getDecompositionReductionRatio(FluidStack fluidInput, FluidStack fluidOutput, ItemStack input, ItemStack output) { + int[] divisors = new int[]{2, 5, 10, 25, 50}; + int ratio = -1; + + for (int divisor : divisors) { + + if (!(isFluidStackAmountDivisible(fluidInput, divisor))) + continue; + + if (!(isFluidStackAmountDivisible(fluidOutput, divisor))) + continue; + + if (input != null && !(GTUtility.isItemStackCountDivisible(input, divisor))) + continue; + + if (output != null && !(GTUtility.isItemStackCountDivisible(output, divisor))) + continue; + + ratio = divisor; + } + + return Math.max(1, ratio); + } + + public static boolean isFluidStackAmountDivisible(FluidStack fluidStack, int divisor) { + return fluidStack.amount % divisor == 0 && fluidStack.amount % divisor != fluidStack.amount && fluidStack.amount / divisor != 0; + } + + public static boolean isItemStackCountDivisible(ItemStack itemStack, int divisor) { + return itemStack.getCount() % divisor == 0 && itemStack.getCount() % divisor != itemStack.getCount() && itemStack.getCount() / divisor != 0; + } }