From 4c3cf3ba764e9cd802771e5a0a3aecb88c705535 Mon Sep 17 00:00:00 2001
From: maggi373 <40539743+maggi373@users.noreply.github.com>
Date: Fri, 17 May 2024 18:57:34 +0200
Subject: [PATCH 1/4] Revert "Revert "New factory sort algorithm for MekCE.""

---
 .../common/tile/TileEntityFactory.java        | 376 +++++++++++++++---
 1 file changed, 329 insertions(+), 47 deletions(-)

diff --git a/src/main/java/mekanism/common/tile/TileEntityFactory.java b/src/main/java/mekanism/common/tile/TileEntityFactory.java
index 46cbf48e25c..b4ce35412aa 100644
--- a/src/main/java/mekanism/common/tile/TileEntityFactory.java
+++ b/src/main/java/mekanism/common/tile/TileEntityFactory.java
@@ -1,7 +1,10 @@
 package mekanism.common.tile;
 
 import io.netty.buffer.ByteBuf;
+
+import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 import java.util.Objects;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -46,7 +49,9 @@
 import mekanism.common.recipe.machines.DoubleMachineRecipe;
 import mekanism.common.recipe.machines.MachineRecipe;
 import mekanism.common.recipe.machines.MetallurgicInfuserRecipe;
+import mekanism.common.recipe.outputs.ChanceOutput;
 import mekanism.common.recipe.outputs.ItemStackOutput;
+import mekanism.common.recipe.outputs.PressurizedOutput;
 import mekanism.common.tier.BaseTier;
 import mekanism.common.tier.FactoryTier;
 import mekanism.common.tile.component.TileComponentConfig;
@@ -67,15 +72,16 @@
 import net.minecraft.nbt.NBTTagCompound;
 import net.minecraft.util.EnumFacing;
 import net.minecraft.util.NonNullList;
+import net.minecraft.util.Tuple;
 import net.minecraftforge.common.capabilities.Capability;
 import net.minecraftforge.fml.common.FMLCommonHandler;
-import net.minecraftforge.items.ItemHandlerHelper;
 
 public class TileEntityFactory extends TileEntityMachine implements IComputerIntegration, ISideConfiguration, IGasHandler, ISpecialConfigData, ITierUpgradeable,
       ISustainedData, IComparatorSupport {
 
     private static final String[] methods = new String[]{"getEnergy", "getProgress", "facing", "canOperate", "getMaxEnergy", "getEnergyNeeded"};
     private final MachineRecipe[] cachedRecipe;
+    private final FactoryInvSorter inventorySorter = new FactoryInvSorter(this);
     /**
      * This Factory's tier.
      */
@@ -235,7 +241,7 @@ public void onUpdate() {
             ChargeUtils.discharge(1, this);
 
             handleSecondaryFuel();
-            sortInventory();
+            inventorySorter.sort();
             ItemStack machineSwapItem = inventory.get(2);
             if (!machineSwapItem.isEmpty() && machineSwapItem.getItem() instanceof ItemBlockMachine && inventory.get(3).isEmpty()) {
 
@@ -349,51 +355,6 @@ public boolean sideIsConsumer(EnumFacing side) {
         return configComponent.hasSideForData(TransmissionType.ENERGY, facing, 1, side);
     }
 
-    public void sortInventory() {
-        if (sorting) {
-            int[] inputSlots;
-            if (tier == FactoryTier.BASIC) {
-                inputSlots = new int[]{5, 6, 7};
-            } else if (tier == FactoryTier.ADVANCED) {
-                inputSlots = new int[]{5, 6, 7, 8, 9};
-            } else if (tier == FactoryTier.ELITE) {
-                inputSlots = new int[]{5, 6, 7, 8, 9, 10, 11};
-            } else {
-                //If something went wrong finding the tier don't sort it
-                return;
-            }
-            for (int i = 0; i < inputSlots.length; i++) {
-                int slotID = inputSlots[i];
-                ItemStack stack = inventory.get(slotID);
-                int count = stack.getCount();
-                ItemStack output = inventory.get(tier.processes + slotID);
-                for (int j = i + 1; j < inputSlots.length; j++) {
-                    int checkSlotID = inputSlots[j];
-                    ItemStack checkStack = inventory.get(checkSlotID);
-                    if (Math.abs(count - checkStack.getCount()) < 2 ||
-                        !InventoryUtils.areItemsStackable(stack, checkStack)) {
-                        continue;
-                    }
-                    //Output/Input will not match
-                    // Only check if the input spot is empty otherwise assume it works
-                    if (stack.isEmpty() && !inputProducesOutput(checkSlotID, checkStack, output, true) ||
-                        checkStack.isEmpty() && !inputProducesOutput(slotID, stack, inventory.get(tier.processes + checkSlotID), true)) {
-                        continue;
-                    }
-
-                    //Balance the two slots
-                    int total = count + checkStack.getCount();
-                    ItemStack newStack = stack.isEmpty() ? checkStack : stack;
-                    inventory.set(slotID, StackUtils.size(newStack, (total + 1) / 2));
-                    inventory.set(checkSlotID, StackUtils.size(newStack, total / 2));
-
-                    markDirty();
-                    return;
-                }
-            }
-        }
-    }
-
     /**
      * Checks if the cached recipe (or recipe for current factory if the cache is out of date) can produce a specific output.
      *
@@ -1000,4 +961,325 @@ public void readSustainedData(ItemStack itemStack) {
     public int getRedstoneLevel() {
         return Container.calcRedstoneFromInventory(this);
     }
+
+    public MachineRecipe<?, ?, ?> getSlotRecipe(int slotID, ItemStack fallbackInput, ItemStack output) {
+        int process = getOperation(slotID);
+        //cached recipe may be invalid
+        MachineRecipe<?, ?, ?> cached = cachedRecipe[process];
+        ItemStack extra = inventory.get(4);
+        if (cached == null) {
+            cached = recipeType.getAnyRecipe(fallbackInput, extra, gasTank.getGasType(), infuseStored);
+            if (cached == null) { // We have not enough input probably
+                cached = recipeType.getAnyRecipe(StackUtils.size(fallbackInput, fallbackInput.getMaxStackSize()), extra, gasTank.getGasType(), infuseStored);
+            }
+        } else {
+            ItemStack recipeInput = ItemStack.EMPTY;
+            boolean secondaryMatch = true;
+            if (cached.recipeInput instanceof ItemStackInput) {
+                recipeInput = ((ItemStackInput) cached.recipeInput).ingredient;
+            } else if (cached.recipeInput instanceof AdvancedMachineInput) {
+                AdvancedMachineInput advancedInput = (AdvancedMachineInput) cached.recipeInput;
+                recipeInput = advancedInput.itemStack;
+                secondaryMatch = gasTank.getGasType() == null || advancedInput.gasType == gasTank.getGasType();
+            } else if (cached.recipeInput instanceof DoubleMachineInput) {
+                DoubleMachineInput doubleMachineInput = (DoubleMachineInput) cached.recipeInput;
+                recipeInput = doubleMachineInput.itemStack;
+                secondaryMatch = extra.isEmpty() || ItemStack.areItemsEqual(doubleMachineInput.extraStack, extra);
+            } else if (cached.recipeInput instanceof InfusionInput) {
+                InfusionInput infusionInput = (InfusionInput) cached.recipeInput;
+                recipeInput = infusionInput.inputStack;
+                secondaryMatch = infuseStored.getAmount() == 0 || infuseStored.getType() == infusionInput.infuse.getType();
+            }
+            //If there is no cached item input or it doesn't match our fallback
+            // then it is an out of date cache so we compare against the new one
+            // and update the cache while we are at it
+            if (recipeInput.isEmpty() || !secondaryMatch || !ItemStack.areItemsEqual(recipeInput, fallbackInput)) {
+                cached = recipeType.getAnyRecipe(fallbackInput, extra, gasTank.getGasType(), infuseStored);
+            }
+        }
+
+        if (cached != null) {
+            ItemStack recipeOutput = ItemStack.EMPTY;
+            if (cached.recipeOutput instanceof ItemStackOutput) {
+                recipeOutput = ((ItemStackOutput) cached.recipeOutput).output;
+            } else if (cached.recipeOutput instanceof ChanceOutput) {
+                recipeOutput = ((ChanceOutput) cached.recipeOutput).primaryOutput;
+            } if (cached.recipeOutput instanceof PressurizedOutput) {
+                recipeOutput = ((PressurizedOutput) cached.recipeOutput).getItemOutput();
+            }
+            if (!recipeOutput.isEmpty()) {
+                InventoryUtils.areItemsStackable(recipeOutput, output);
+            }
+        }
+        return cached;
+    }
+
+    public static ItemStack getRecipeInput(MachineRecipe<?, ?, ?> recipe) {
+        if (recipe.recipeInput instanceof ItemStackInput) {
+            return ((ItemStackInput) recipe.recipeInput).ingredient;
+        } else if (recipe.recipeInput instanceof AdvancedMachineInput) {
+            AdvancedMachineInput advancedInput = (AdvancedMachineInput) recipe.recipeInput;
+            return advancedInput.itemStack;
+        } else if (recipe.recipeInput instanceof DoubleMachineInput) {
+            DoubleMachineInput doubleMachineInput = (DoubleMachineInput) recipe.recipeInput;
+            return doubleMachineInput.itemStack;
+        } else if (recipe.recipeInput instanceof InfusionInput) {
+            InfusionInput infusionInput = (InfusionInput) recipe.recipeInput;
+            return infusionInput.inputStack;
+        } else {
+            return ItemStack.EMPTY;
+        }
+    }
+
+    private static int[] getSlotsWithTier(FactoryTier tier) {
+        switch (tier) {
+            case BASIC:
+                return new int[]{5, 6, 7};
+            case ADVANCED:
+                return new int[]{5, 6, 7, 8, 9};
+            case ELITE:
+                return new int[]{5, 6, 7, 8, 9, 10, 11};
+            default:
+                return null;
+        }
+    }
+
+    public static ItemStack copyStackWithSize(ItemStack stack, int amount) {
+        if (stack.isEmpty() || amount <= 0) return ItemStack.EMPTY;
+        ItemStack s = stack.copy();
+        s.setCount(amount);
+        return s;
+    }
+
+    public static boolean matchStacks(@Nonnull ItemStack stack, @Nonnull ItemStack other) {
+        if (!ItemStack.areItemsEqual(stack, other)) return false;
+        return ItemStack.areItemStackTagsEqual(stack, other);
+    }
+
+    /**
+     * <p>Efficient, intelligent factory sequencing.</p>
+     * <p><strong>Non-thread safe。</strong></p>
+     * <p>In fact, it still has a lot of room for optimization, limited by the structure of the code, these features are sufficient.</p>
+     */
+    public static class FactoryInvSorter {
+        private final TileEntityFactory factory;
+        // Reusable List
+        private final List<Tuple<MachineRecipe<?, ?, ?>, ItemStack>> vaildRecipeItemStackList = new ArrayList<>();
+        // Reusable List
+        private final List<ItemStack> invaildRecipeItemStackList = new ArrayList<>();
+        // Reusable List
+        private final List<ItemStack> sorted = new ArrayList<>();
+
+        public FactoryInvSorter(TileEntityFactory factory) {
+            this.factory = factory;
+        }
+
+        /**
+         * <p>Add an ItemStack to the item list. </p
+         *
+         * @param willBeAdded The item that will be added to the list, or merged if the item already exists in the list and has not reached its maximum stack value.
+         * @param stackList The list of items.
+         */
+        private static void addItemStackToList(ItemStack willBeAdded, List<ItemStack> stackList) {
+            boolean isAdded = false;
+            for (ItemStack stack : stackList) {
+                int maxStackSize = stack.getMaxStackSize();
+                int invStackCount = willBeAdded.getCount();
+
+                if (!matchStacks(stack, willBeAdded)) {
+                    continue;
+                }
+                if (stack.getCount() >= maxStackSize) {
+                    continue;
+                }
+                if (stack.getCount() + invStackCount > maxStackSize) {
+                    int added = maxStackSize - stack.getCount();
+                    stack.setCount(maxStackSize);
+                    willBeAdded.setCount(invStackCount - added);
+                    continue;
+                }
+                stack.setCount(stack.getCount() + invStackCount);
+                isAdded = true;
+            }
+            if (!isAdded) {
+                stackList.add(willBeAdded);
+            }
+        }
+
+        /**
+         * <p>Add an ItemStack to the item list. </p
+         *
+         * @param willBeAdded The item that will be added to the list, or merged if the item already exists in the list and has not reached the maximum stack value.
+         * @param tupleList The list of items.
+         * @return Returns true if the addition was successful, or false if the list is full.
+         */
+        private static boolean addItemStackToTupleList(ItemStack willBeAdded, List<Tuple<MachineRecipe<?, ?, ?>, ItemStack>> tupleList) {
+            for (Tuple<MachineRecipe<?, ?, ?>, ItemStack> collected : tupleList) {
+                ItemStack stack = collected.getSecond();
+                int maxStackSize = stack.getMaxStackSize();
+                int invStackCount = willBeAdded.getCount();
+
+                if (!matchStacks(stack, willBeAdded)) {
+                    continue;
+                }
+                if (stack.getCount() >= maxStackSize) {
+                    continue;
+                }
+                if (stack.getCount() + invStackCount > maxStackSize) {
+                    int added = maxStackSize - stack.getCount();
+                    stack.setCount(maxStackSize);
+                    willBeAdded.setCount(invStackCount - added);
+                    continue;
+                }
+                stack.setCount(stack.getCount() + invStackCount);
+                return true;
+            }
+
+            return false;
+        }
+
+        /**
+         * <h2>Sorting Process Introduction</h2>
+         * <ol>
+         *     <li>First detects if there is at least one item in the factory, and if there is no item, ends the process early.</li>
+         *     <li>When the above condition is met, start sorting the contents into two lists (see {@link FactoryInvSorter#collectInvToList(int[] slotIds)} for the workflow.</li>
+         *     <li>After sorting, execute {@link FactoryInvSorter#doSort(int)} to sort the results further and output the results to {@link FactoryInvSorter#sorted}.</li>
+         *     <li>Finally, execute {@link FactoryInvSorter#applyResult(List sorted, int[] slotIds)} to apply the result to the machine inventory.</li>
+         * </ol>
+         */
+        public void sort() {
+            if (!factory.sorting || factory.getWorld().getWorldTime() % 20 != 0) {
+                return;
+            }
+            int[] slotIds = getSlotsWithTier(factory.tier);
+            if (slotIds == null || !hasItem(slotIds)) {
+                return;
+            }
+
+            vaildRecipeItemStackList.clear();
+            invaildRecipeItemStackList.clear();
+            sorted.clear();
+
+            collectInvToList(slotIds);
+
+            if (vaildRecipeItemStackList.size() + invaildRecipeItemStackList.size() >= slotIds.length) {
+                //The collection size is bigger than equals slotIds size, end sort.
+                return;
+            }
+
+            doSort(slotIds.length - (vaildRecipeItemStackList.size() + invaildRecipeItemStackList.size()));
+            applyResult(sorted, slotIds);
+        }
+
+        /**
+         * Check if at least one item exists in the mechanical item bar.
+         *
+         * @param slotIds The slot to check.
+         * @return Returns true if at least one item is present, false if neither is present.
+         */
+        private boolean hasItem(int[] slotIds) {
+            for (int slotId : slotIds) {
+                if (factory.inventory.get(slotId) != ItemStack.EMPTY) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Apply items from the specified item list to the mechanical item bar, which <strong>must</strong> be larger or equal to the list size.
+         *
+         * @param sorted  Sorted item list
+         * @param slotIds slotIdArray
+         */
+        private void applyResult(List<ItemStack> sorted, int[] slotIds) {
+            if (sorted.isEmpty()) {
+                return;
+            }
+
+            int index = 0;
+            for (int slotId : slotIds) {
+                factory.inventory.set(slotId, ItemStack.EMPTY);
+                if (index >= sorted.size()) {
+                    continue;
+                }
+                factory.inventory.set(slotId, sorted.get(index));
+                index++;
+            }
+            sorted.clear();
+            factory.markDirty();
+        }
+
+        /**
+         * <p>Sort the sorted results to return a list of items available for use by {@link FactoryInvSorter#applyResult(List itemStackList, int[] slotIds)}.</p>
+         * <h2>Additional Features:</h2>
+         * <ul>
+         *     <li>Automatically calculates the product of the corresponding item and limits the number of divisions to the minimum number of recipes.</li>
+         *     <li>Maximize the application of each item slot while implementing the features above.</li>
+         *     <li>Minimize the number of slots occupied by invalid items and merge these invalid items where allowed.</li>
+         * </ul>
+         *
+         * @param emptySlotAmount Available empty slots.
+         */
+        private void doSort(int emptySlotAmount) {
+            int availableEmptySlotAmount = emptySlotAmount;
+            for (Tuple<MachineRecipe<?, ?, ?>, ItemStack> recipeAndInput : vaildRecipeItemStackList) {
+                MachineRecipe<?, ?, ?> recipe = recipeAndInput.getFirst();
+                ItemStack invStack = recipeAndInput.getSecond();
+                ItemStack recipeInput = TileEntityFactory.getRecipeInput(recipe);
+
+                int invCount = invStack.getCount();
+                int minCount = recipeInput.getCount();
+                if (invCount <= minCount) {
+                    sorted.add(invStack);
+                    continue;
+                }
+
+                int splitCount = Math.min(availableEmptySlotAmount + 1, invCount / minCount);
+                int countAfterSplit = invCount / splitCount;
+                int extra = invCount % splitCount;
+
+                sorted.add(copyStackWithSize(invStack, countAfterSplit + extra));
+
+                while (splitCount > 1) {
+                    sorted.add(copyStackWithSize(invStack, countAfterSplit));
+                    availableEmptySlotAmount--;
+                    splitCount--;
+                }
+            }
+            sorted.addAll(invaildRecipeItemStackList);
+        }
+
+        /**
+         * <p>Iterate through the contents of the mechanical item column with the incoming slot array and sort it into two item lists.</p>
+         * <h2>Feature:</h2>
+         * <ul>
+         *     <li>Automatically determines if an item is ready to run a recipe and adds it to the list {@link FactoryInvSorter#vaildRecipeItemStackList}.</li>
+         *     <li>Automatically determines items that cannot perform a recipe or are invalid and adds them to the list {@link FactoryInvSorter#invaildRecipeItemStackList}.</li>
+         * </ul>
+         *
+         * @param slotIds slotIDArray
+         */
+        private void collectInvToList(int[] slotIds) {
+            for (int slotId : slotIds) {
+                ItemStack invTmp = factory.inventory.get(slotId);
+                if (invTmp == ItemStack.EMPTY) {
+                    continue;
+                }
+                ItemStack invStack = invTmp.copy();
+
+                if (addItemStackToTupleList(invStack, vaildRecipeItemStackList)) {
+                    continue;
+                }
+
+                ItemStack outStack = factory.inventory.get(slotId + factory.tier.processes);
+                MachineRecipe<?, ?, ?> recipe = factory.getSlotRecipe(slotId, invStack, outStack);
+                if (recipe != null) {
+                    vaildRecipeItemStackList.add(new Tuple<>(recipe, invStack));
+                } else {
+                    addItemStackToList(invStack, invaildRecipeItemStackList);
+                }
+            }
+        }
+    }
 }
\ No newline at end of file

From 68be3bc05b30ce84dee8f6abb144ffc5f45b5f99 Mon Sep 17 00:00:00 2001
From: maggi373 <40539743+maggi373@users.noreply.github.com>
Date: Fri, 17 May 2024 19:09:54 +0200
Subject: [PATCH 2/4] adds configurable new sorting algorithm

---
 .../mekanism/common/config/MEKCEConfig.java   |  3 ++
 .../common/tile/TileEntityFactory.java        | 52 ++++++++++++++++++-
 2 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/src/main/java/mekanism/common/config/MEKCEConfig.java b/src/main/java/mekanism/common/config/MEKCEConfig.java
index 8b38a12991b..50a81c4238f 100644
--- a/src/main/java/mekanism/common/config/MEKCEConfig.java
+++ b/src/main/java/mekanism/common/config/MEKCEConfig.java
@@ -27,6 +27,9 @@ public class MEKCEConfig extends BaseConfig {
     public final BooleanOption EnableSiliconCompat = new BooleanOption(this, "mekce", "EnableSiliconCompat", true,
             "When a mod that adds silicon (galacticraft, enderio, projectred and ae2) is detected, recipe for control circuit is changed from using iron to silicon in the metalurgic infuser");
 
+    public final BooleanOption EnableNewSortAlgorithm = new BooleanOption(this, "mekce", "EnableNewSortAlgorithm", true,
+            "Enables the new sorting algorithm on factories, you might need to replace the placed machine for the new code to work correctly, option is here to resolve any compat issues a modpack might have");
+
     //public final BooleanOption enableBoPProgression = new BooleanOption(this, "mekce", "enableBoPProgression", true,
     //        "when true and biome's o plenty is installed atomic alloy is made by using ender instead of obsidian");
 
diff --git a/src/main/java/mekanism/common/tile/TileEntityFactory.java b/src/main/java/mekanism/common/tile/TileEntityFactory.java
index b4ce35412aa..4c562f8376f 100644
--- a/src/main/java/mekanism/common/tile/TileEntityFactory.java
+++ b/src/main/java/mekanism/common/tile/TileEntityFactory.java
@@ -35,6 +35,7 @@
 import mekanism.common.base.ITierUpgradeable;
 import mekanism.common.block.states.BlockStateMachine.MachineType;
 import mekanism.common.capabilities.Capabilities;
+import mekanism.common.config.MekanismConfig;
 import mekanism.common.integration.computer.IComputerIntegration;
 import mekanism.common.item.ItemBlockMachine;
 import mekanism.common.recipe.GasConversionHandler;
@@ -241,7 +242,11 @@ public void onUpdate() {
             ChargeUtils.discharge(1, this);
 
             handleSecondaryFuel();
-            inventorySorter.sort();
+            if (MekanismConfig.current().mekce.EnableNewSortAlgorithm.val()) {
+                inventorySorter.sort();
+            } else {
+                sortInventory();
+            }
             ItemStack machineSwapItem = inventory.get(2);
             if (!machineSwapItem.isEmpty() && machineSwapItem.getItem() instanceof ItemBlockMachine && inventory.get(3).isEmpty()) {
 
@@ -355,6 +360,51 @@ public boolean sideIsConsumer(EnumFacing side) {
         return configComponent.hasSideForData(TransmissionType.ENERGY, facing, 1, side);
     }
 
+    public void sortInventory() {
+        if (sorting) {
+            int[] inputSlots;
+            if (tier == FactoryTier.BASIC) {
+                inputSlots = new int[]{5, 6, 7};
+            } else if (tier == FactoryTier.ADVANCED) {
+                inputSlots = new int[]{5, 6, 7, 8, 9};
+            } else if (tier == FactoryTier.ELITE) {
+                inputSlots = new int[]{5, 6, 7, 8, 9, 10, 11};
+            } else {
+                //If something went wrong finding the tier don't sort it
+                return;
+            }
+            for (int i = 0; i < inputSlots.length; i++) {
+                int slotID = inputSlots[i];
+                ItemStack stack = inventory.get(slotID);
+                int count = stack.getCount();
+                ItemStack output = inventory.get(tier.processes + slotID);
+                for (int j = i + 1; j < inputSlots.length; j++) {
+                    int checkSlotID = inputSlots[j];
+                    ItemStack checkStack = inventory.get(checkSlotID);
+                    if (Math.abs(count - checkStack.getCount()) < 2 ||
+                            !InventoryUtils.areItemsStackable(stack, checkStack)) {
+                        continue;
+                    }
+                    //Output/Input will not match
+                    // Only check if the input spot is empty otherwise assume it works
+                    if (stack.isEmpty() && !inputProducesOutput(checkSlotID, checkStack, output, true) ||
+                            checkStack.isEmpty() && !inputProducesOutput(slotID, stack, inventory.get(tier.processes + checkSlotID), true)) {
+                        continue;
+                    }
+
+                    //Balance the two slots
+                    int total = count + checkStack.getCount();
+                    ItemStack newStack = stack.isEmpty() ? checkStack : stack;
+                    inventory.set(slotID, StackUtils.size(newStack, (total + 1) / 2));
+                    inventory.set(checkSlotID, StackUtils.size(newStack, total / 2));
+
+                    markDirty();
+                    return;
+                }
+            }
+        }
+    }
+
     /**
      * Checks if the cached recipe (or recipe for current factory if the cache is out of date) can produce a specific output.
      *

From a73fbac0d48f5aa6e51aa47ea0646a4bbc952c5b Mon Sep 17 00:00:00 2001
From: maggi373 <40539743+maggi373@users.noreply.github.com>
Date: Fri, 17 May 2024 19:20:06 +0200
Subject: [PATCH 3/4] use boolean

probably not smart to check config every tick lel
---
 src/main/java/mekanism/common/tile/TileEntityFactory.java | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/java/mekanism/common/tile/TileEntityFactory.java b/src/main/java/mekanism/common/tile/TileEntityFactory.java
index 4c562f8376f..5d8e55fc3b1 100644
--- a/src/main/java/mekanism/common/tile/TileEntityFactory.java
+++ b/src/main/java/mekanism/common/tile/TileEntityFactory.java
@@ -124,6 +124,7 @@ public class TileEntityFactory extends TileEntityMachine implements IComputerInt
     public boolean sorting;
 
     public boolean upgraded;
+    public boolean NewSortAlgo = MekanismConfig.current().mekce.EnableNewSortAlgorithm.val();
 
     public double lastUsage;
 
@@ -242,7 +243,7 @@ public void onUpdate() {
             ChargeUtils.discharge(1, this);
 
             handleSecondaryFuel();
-            if (MekanismConfig.current().mekce.EnableNewSortAlgorithm.val()) {
+            if (NewSortAlgo) {
                 inventorySorter.sort();
             } else {
                 sortInventory();

From 92d666f82eddb4c8c2a08185c1457f21f57adaa0 Mon Sep 17 00:00:00 2001
From: maggi373 <40539743+maggi373@users.noreply.github.com>
Date: Fri, 17 May 2024 19:22:29 +0200
Subject: [PATCH 4/4] bump version

---
 gradle.properties | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gradle.properties b/gradle.properties
index 422fe346277..766fe44b6b9 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,7 +1,7 @@
 minecraft_version=1.12.2
 mappings_version=stable_39
 forge_version=14.23.5.2847
-mod_version=9.12.9
+mod_version=9.12.10
 
 mcmp_version=2.5.3
 jei_version=4.15.0.289