diff options
4 files changed, 142 insertions, 29 deletions
diff --git a/src/functionalTest/java/gregtech/test/GTParallelHelperTest.java b/src/functionalTest/java/gregtech/test/GTParallelHelperTest.java index 517e41b8ba..67abe8a5bd 100644 --- a/src/functionalTest/java/gregtech/test/GTParallelHelperTest.java +++ b/src/functionalTest/java/gregtech/test/GTParallelHelperTest.java @@ -91,7 +91,7 @@ public class GTParallelHelperTest { .setMachine(machine, false, false) .setItemInputs(inputItems) .setMaxParallel(10) - .setAvailableEUt(100) + .setAvailableEUt(10) .setConsumption(false) .setOutputCalculation(true) .setChanceMultiplier(10) diff --git a/src/functionalTest/java/gregtech/test/GTRecipeTest.java b/src/functionalTest/java/gregtech/test/GTRecipeTest.java index cf9245dbec..c54fb0a7c8 100644 --- a/src/functionalTest/java/gregtech/test/GTRecipeTest.java +++ b/src/functionalTest/java/gregtech/test/GTRecipeTest.java @@ -19,6 +19,9 @@ import static net.minecraft.init.Blocks.iron_ore; import static net.minecraft.init.Blocks.lapis_block; import static net.minecraft.init.Blocks.log; import static net.minecraft.init.Blocks.planks; +import static net.minecraft.init.Blocks.stone; +import static net.minecraft.init.Blocks.stone_slab; +import static net.minecraft.init.Items.glass_bottle; import static net.minecraft.init.Items.iron_ingot; import static net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -32,6 +35,7 @@ import net.minecraft.nbt.NBTTagCompound; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import gregtech.api.enums.ItemList; import gregtech.api.recipe.RecipeMap; import gregtech.api.recipe.RecipeMapBuilder; import gregtech.api.util.GT_Recipe; @@ -75,6 +79,36 @@ class GTRecipeTest { .duration(0) .eut(0) .addTo(recipeMap); + + RA.stdBuilder() + .itemInputs(new ItemStack(stone_slab, 64), new ItemStack(stone_slab, 64)) + .itemOutputs(new ItemStack(stone, 2)) + .duration(0) + .eut(0) + .addTo(recipeMap); + + ItemStack dataStick = ItemList.Tool_DataStick.get(0); + NBTTagCompound dataStickTag = new NBTTagCompound(); + dataStickTag.setInteger("integer", 123456); + dataStick.setTagCompound(dataStickTag); + RA.stdBuilder() + .itemInputs(dataStick) + .itemOutputs(new ItemStack(chest, 1)) + .duration(0) + .eut(0) + .addTo(recipeMap); + + ItemStack glass = new ItemStack(glass_bottle, 2); + NBTTagCompound glassTag = new NBTTagCompound(); + glassTag.setInteger("integer", 123456); + glass.setTagCompound(glassTag); + RA.stdBuilder() + .itemInputs(glass) + .itemOutputs(new ItemStack(chest, 1)) + .duration(0) + .eut(0) + .nbtSensitive() + .addTo(recipeMap); } @Test @@ -82,7 +116,7 @@ class GTRecipeTest { assertEquals( recipeMap.getAllRecipes() .size(), - 4); + 7); } @Test @@ -91,6 +125,11 @@ class GTRecipeTest { .items(new ItemStack(lapis_block, 1), get(circuit, Advanced, 1)) .find(); assertNotNull(recipe); + + GT_Recipe stoneRecipe = recipeMap.findRecipeQuery() + .items(new ItemStack(stone_slab, 128)) + .find(); + assertNotNull(stoneRecipe); } @Test @@ -126,6 +165,26 @@ class GTRecipeTest { .items(lapisBlock, get(circuit, Advanced, 1)) .find(); assertNotNull(recipe); + + // For NBT sensitive recipes + ItemStack glass = new ItemStack(glass_bottle, 2); + NBTTagCompound glassTag = new NBTTagCompound(); + glassTag.setInteger("integer", 123456); + glass.setTagCompound(glassTag); + GT_Recipe nbtSensitiveRecipe = recipeMap.findRecipeQuery() + .items(glass) + .find(); + assertNotNull(nbtSensitiveRecipe); + + // For items that need to check NBT, e.g. data sticks + ItemStack dataStick = ItemList.Tool_DataStick.get(0); + NBTTagCompound dataStickTag = new NBTTagCompound(); + dataStickTag.setInteger("integer", 123456); + dataStick.setTagCompound(dataStickTag); + GT_Recipe checkNBTRecipe = recipeMap.findRecipeQuery() + .items(dataStick) + .find(); + assertNotNull(checkNBTRecipe); } @Test @@ -134,6 +193,11 @@ class GTRecipeTest { .items(new ItemStack(log, 1, 0), new ItemStack(planks, 1, 0)) .find(); assertNull(recipe); + + GT_Recipe stoneRecipe = recipeMap.findRecipeQuery() + .items(new ItemStack(stone_slab, 127)) + .find(); + assertNull(stoneRecipe); } @Test @@ -147,6 +211,21 @@ class GTRecipeTest { } @Test + void rejectWithoutCorrectNBT() { + // For NBT sensitive recipes + GT_Recipe nbtSensitiveRecipe = recipeMap.findRecipeQuery() + .items(new ItemStack(glass_bottle, 2)) + .find(); + assertNull(nbtSensitiveRecipe); + + // For items that need to check NBT, e.g. data sticks + GT_Recipe checkNBTRecipe = recipeMap.findRecipeQuery() + .items(ItemList.Tool_DataStick.get(0)) + .find(); + assertNull(checkNBTRecipe); + } + + @Test void findOredicted() { // https://github.com/GTNewHorizons/GT5-Unofficial/pull/2373 assertTrue( diff --git a/src/main/java/gregtech/api/util/GT_Recipe.java b/src/main/java/gregtech/api/util/GT_Recipe.java index b06c7f9e64..ddb0708716 100644 --- a/src/main/java/gregtech/api/util/GT_Recipe.java +++ b/src/main/java/gregtech/api/util/GT_Recipe.java @@ -36,6 +36,8 @@ import gregtech.api.recipe.metadata.IRecipeMetadataStorage; import gregtech.api.util.extensions.ArrayExt; import gregtech.api.util.item.ItemHolder; import ic2.core.Ic2Items; +import it.unimi.dsi.fastutil.objects.Object2LongArrayMap; +import it.unimi.dsi.fastutil.objects.Object2LongMap; import it.unimi.dsi.fastutil.objects.Reference2LongArrayMap; import it.unimi.dsi.fastutil.objects.Reference2LongMap; @@ -492,8 +494,8 @@ public class GT_Recipe implements Comparable<GT_Recipe> { // because of early exit condition above. if (mFluidInputs.length > 0 /* && aFluidInputs != null */) { // Create map for fluid -> stored amount - Reference2LongMap<Fluid> fluidMap = new Reference2LongArrayMap<>(4); - Reference2LongMap<Fluid> fluidCost = new Reference2LongArrayMap<>(4); + Reference2LongMap<Fluid> fluidMap = new Reference2LongArrayMap<>(2); + Reference2LongMap<Fluid> fluidCost = new Reference2LongArrayMap<>(2); for (FluidStack fluidStack : aFluidInputs) { if (fluidStack == null) continue; fluidMap.mergeLong(fluidStack.getFluid(), fluidStack.amount, Long::sum); @@ -516,46 +518,72 @@ public class GT_Recipe implements Comparable<GT_Recipe> { } } - double remainingCost; - long providedAmount; - if (aInputs != null) { - nextRecipeItemCost: for (ItemStack recipeItemCost : mInputs) { + if (mInputs.length > 0) { + double remainingCost; + long providedAmount; + Object2LongMap<GT_Utility.ItemId> itemCostMap = new Object2LongArrayMap<>(2); + + for (ItemStack itemStack : mInputs) { + if (itemStack == null) continue; + if (shouldCheckNBT(itemStack)) { + GT_Utility.ItemId itemId = GT_Utility.ItemId.createNoCopy(itemStack); + itemCostMap.mergeLong(itemId, itemStack.stackSize, Long::sum); + continue; + } + ItemStack unifiedItem = GT_OreDictUnificator.get_nocopy(true, itemStack); + if (unifiedItem != null) { + GT_Utility.ItemId unifiedId; + if (isNBTSensitive) unifiedId = GT_Utility.ItemId.createNoCopy(unifiedItem); + else unifiedId = GT_Utility.ItemId.createWithoutNBT(unifiedItem); + itemCostMap.mergeLong(unifiedId, itemStack.stackSize, Long::sum); + } + } - ItemStack unifiedItemCost = GT_OreDictUnificator.get_nocopy(true, recipeItemCost); + ItemStack unifiedItemCost; + nextRecipeItemCost: for (Map.Entry<GT_Utility.ItemId, Long> costEntry : itemCostMap.entrySet()) { + unifiedItemCost = costEntry.getKey() + .getItemStack(); if (unifiedItemCost != null) { - remainingCost = recipeItemCost.stackSize * currentParallel; + remainingCost = costEntry.getValue() * currentParallel; providedAmount = 0; for (ItemStack providedItem : aInputs) { - if (isNBTSensitive && !GT_Utility.areStacksEqual(providedItem, unifiedItemCost, false)) { - continue; - } else if (!isNBTSensitive - && !GT_OreDictUnificator.isInputStackEqual(providedItem, unifiedItemCost)) { - continue; - } - - if (GTppRecipeHelper) { // Please see JavaDoc on GTppRecipeHelper for why this is here. - if (GT_Utility.areStacksEqual(providedItem, Ic2Items.FluidCell.copy(), true) - || GT_Utility.areStacksEqual(providedItem, ItemList.Tool_DataStick.get(1L), true) - || GT_Utility.areStacksEqual(providedItem, ItemList.Tool_DataOrb.get(1L), true)) { - if (!GT_Utility.areStacksEqual(providedItem, recipeItemCost, false)) continue; - } - } + if (!areInputStackAndRecipeCostMatched(providedItem, unifiedItemCost)) continue; // for non-consumed input - if (recipeItemCost.stackSize == 0) continue nextRecipeItemCost; + if (costEntry.getValue() == 0) continue nextRecipeItemCost; providedAmount += providedItem.stackSize; if (providedAmount >= remainingCost) continue nextRecipeItemCost; } if (providedAmount == 0) return 0; - currentParallel = Math.min(currentParallel, (double) providedAmount / recipeItemCost.stackSize); + currentParallel = Math.min(currentParallel, (double) providedAmount / costEntry.getValue()); } } } return currentParallel; } + private boolean areInputStackAndRecipeCostMatched(ItemStack providedItem, ItemStack unifiedItemCost) { + if (isNBTSensitive || shouldCheckNBT(providedItem)) { + return GT_Utility.areStacksEqual(providedItem, unifiedItemCost, false); + } else { + return GT_OreDictUnificator.isInputStackEqual(providedItem, unifiedItemCost); + } + } + + /** + * Please see JavaDoc on {@link #GTppRecipeHelper} for why this is here. + */ + private boolean shouldCheckNBT(ItemStack item) { + if (GTppRecipeHelper) { + return GT_Utility.areStacksEqual(item, Ic2Items.FluidCell.copy(), true) + || GT_Utility.areStacksEqual(item, ItemList.Tool_DataStick.get(1L), true) + || GT_Utility.areStacksEqual(item, ItemList.Tool_DataOrb.get(1L), true); + } + return false; + } + public boolean isRecipePossible(@Nullable ItemInventoryLogic itemInput, @Nullable FluidInventoryLogic fluidInput) { return getAmountOfRecipesDone(itemInput, fluidInput, 1, true) > 0; } diff --git a/src/main/java/gregtech/api/util/GT_Utility.java b/src/main/java/gregtech/api/util/GT_Utility.java index 4f2d13dd04..467e52a1db 100644 --- a/src/main/java/gregtech/api/util/GT_Utility.java +++ b/src/main/java/gregtech/api/util/GT_Utility.java @@ -4883,7 +4883,7 @@ public class GT_Utility { nbt = (NBTTagCompound) nbt.copy(); } - return new AutoValue_GT_Utility_ItemId(itemStack.getItem(), itemStack.getItemDamage(), nbt); + return new AutoValue_GT_Utility_ItemId(itemStack.getItem(), Items.feather.getDamage(itemStack), nbt); } /** @@ -4907,7 +4907,7 @@ public class GT_Utility { * This method stores NBT as null. */ public static ItemId createWithoutNBT(ItemStack itemStack) { - return new AutoValue_GT_Utility_ItemId(itemStack.getItem(), itemStack.getItemDamage(), null); + return new AutoValue_GT_Utility_ItemId(itemStack.getItem(), Items.feather.getDamage(itemStack), null); } /** @@ -4916,7 +4916,7 @@ public class GT_Utility { public static ItemId createNoCopy(ItemStack itemStack) { return new AutoValue_GT_Utility_ItemId( itemStack.getItem(), - itemStack.getItemDamage(), + Items.feather.getDamage(itemStack), itemStack.getTagCompound()); } @@ -4941,6 +4941,12 @@ public class GT_Utility { if (nbt() != null) tag.setTag("tag", nbt()); return tag; } + + public ItemStack getItemStack() { + ItemStack itemStack = new ItemStack(item(), 1, metaData()); + itemStack.setTagCompound(nbt()); + return itemStack; + } } public static int getPlasmaFuelValueInEUPerLiterFromMaterial(Materials material) { |