aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/gtPlusPlus/core/util/recipe/GTRecipeUtils.java
blob: 980068ed97ef9fe1d74435bfc6cdf6df32981de6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package gtPlusPlus.core.util.recipe;

import static gtPlusPlus.core.slots.SlotIntegratedCircuit.isRegularProgrammableCircuit;

import java.util.ArrayList;
import java.util.List;

import net.minecraft.item.ItemStack;

import org.apache.commons.lang3.ArrayUtils;

import gnu.trove.map.hash.TCustomHashMap;
import gnu.trove.set.hash.TCustomHashSet;
import gregtech.api.util.GTRecipe;
import gtPlusPlus.api.objects.Logger;

public class GTRecipeUtils {

    public static List<GTRecipe> removeDuplicates(List<GTRecipe> inputRecipes, String recipeMapName) {
        TCustomHashSet<GTRecipe> recipesHashSet = new TCustomHashSet<>(RecipeHashStrat.RecipeHashingStrategy);
        ArrayList<GTRecipe> recipeOutput = new ArrayList<>();
        TCustomHashMap<GTRecipe, ItemStack> circuitMap = new TCustomHashMap<>(RecipeHashStrat.RecipeHashingStrategy);
        int removedRecipeCount = 0;

        for (GTRecipe recipeInput : inputRecipes) {
            ItemStack savedCircuit = null;
            // create a new input ItemStack array that does not contain programmable circuits if they were in the recipe
            ArrayList<ItemStack> itemInputsWithoutProgrammableCircuit = new ArrayList<>();
            // iterate over the recipe input items and add them all to a new array without any programmable circuits
            for (ItemStack itemStack : recipeInput.mInputs) {
                if (itemStack == null) {
                    continue;
                }
                if (isRegularProgrammableCircuit(itemStack) == -1) {
                    itemInputsWithoutProgrammableCircuit.add(itemStack);
                } else {
                    savedCircuit = itemStack;
                }
            }
            GTRecipe newRecipe = new GTRecipe(
                false,
                itemInputsWithoutProgrammableCircuit.toArray(new ItemStack[0]),
                recipeInput.mOutputs,
                recipeInput.mSpecialItems,
                recipeInput.mChances,
                recipeInput.mFluidInputs,
                recipeInput.mFluidOutputs,
                recipeInput.mDuration,
                recipeInput.mEUt,
                recipeInput.mSpecialValue);
            if (!recipesHashSet.contains(newRecipe)) {
                // if the recipes customHashSet does not contain the new recipe then add it
                recipesHashSet.add(newRecipe);
            } else {
                removedRecipeCount++;
            }
            if (savedCircuit != null) {
                // if the current recipe has a circuit and the recipe (without circuits) is already in the
                // circuit map then check make sure the circuit map saves the recipe with the smallest circuit
                // damage value. This is to prevent a case where recipe load order would affect which duplicate
                // recipes with multiple circuit values gets removed.
                if (circuitMap.containsKey(newRecipe)) {
                    if (circuitMap.get(newRecipe)
                        .getItemDamage() > savedCircuit.getItemDamage()) {
                        circuitMap.put(newRecipe, savedCircuit);
                    }
                } else {
                    // If the circuit map does not have the recipe in it yet then add it
                    circuitMap.put(newRecipe, savedCircuit);
                }
            }
        }
        // iterate over all recipes without duplicates and add them to the output. If the recipe had a programmable
        // circuit in it then add it back with its damage value coming from the circuit map.
        for (GTRecipe filteredRecipe : recipesHashSet) {
            // check to see if the recipe is in the circuit map
            if (circuitMap.contains(filteredRecipe)) {
                // add the circuit back
                // update the item input array with the new input from
                // ItemInputsWithoutProgrammableCircuit + circuit map circuit
                filteredRecipe.mInputs = ArrayUtils.add(filteredRecipe.mInputs, circuitMap.get(filteredRecipe));
            }
            // if the recipe was not in the circuit map then just add it the output as no updates to the item input
            // needs to be made
            recipeOutput.add(filteredRecipe);
        }
        // print results to log
        Logger.INFO(
            "Recipe Array duplication removal process completed for '" + recipeMapName
                + "': '"
                + removedRecipeCount
                + "' removed.");
        return recipeOutput;
    }
}