diff options
author | Martin Robertz <dream-master@gmx.net> | 2020-12-31 11:59:53 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-31 11:59:53 +0100 |
commit | 116009659e461ac81f451406a5041a9b55f80a6f (patch) | |
tree | 87e512bd270ce13251fe96f3663755045d2295cc /src/main | |
parent | c8adb93578e701d1443376ce103ce62a50aaecb0 (diff) | |
parent | 939441f7b24e5f6abb0b5534dfea715b4be6e5ed (diff) | |
download | GT5-Unofficial-116009659e461ac81f451406a5041a9b55f80a6f.tar.gz GT5-Unofficial-116009659e461ac81f451406a5041a9b55f80a6f.tar.bz2 GT5-Unofficial-116009659e461ac81f451406a5041a9b55f80a6f.zip |
Merge pull request #389 from GTNewHorizons/dissassembler2
NBT Dissassebly Data removal
Diffstat (limited to 'src/main')
8 files changed, 663 insertions, 116 deletions
diff --git a/src/main/java/gregtech/GT_Mod.java b/src/main/java/gregtech/GT_Mod.java index b0ac434c61..fe44141324 100644 --- a/src/main/java/gregtech/GT_Mod.java +++ b/src/main/java/gregtech/GT_Mod.java @@ -32,6 +32,8 @@ import gregtech.api.enums.SubTag; import gregtech.api.enums.Textures; import gregtech.api.interfaces.internal.IGT_Mod; import gregtech.api.objects.ItemData; +import gregtech.api.objects.ReverseShapedRecipe; +import gregtech.api.objects.ReverseShapelessRecipe; import gregtech.api.objects.XSTR; import gregtech.api.threads.GT_Runnable_MachineBlockUpdate; import gregtech.api.util.GT_Assemblyline_Server; @@ -1077,6 +1079,9 @@ public class GT_Mod implements IGT_Mod { achievements = new GT_Achievements(); + ReverseShapedRecipe.runReverseRecipes(); + ReverseShapelessRecipe.runReverseRecipes(); + GT_Recipe.GTppRecipeHelper = true; GT_Log.out.println("GT_Mod: Loading finished, deallocating temporary Init Variables."); GregTech_API.sBeforeGTPreload = null; diff --git a/src/main/java/gregtech/api/objects/ReverseShapedRecipe.java b/src/main/java/gregtech/api/objects/ReverseShapedRecipe.java new file mode 100644 index 0000000000..cb9e7d4d83 --- /dev/null +++ b/src/main/java/gregtech/api/objects/ReverseShapedRecipe.java @@ -0,0 +1,43 @@ +package gregtech.api.objects; + +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_Utility; +import gregtech.common.tileentities.machines.basic.GT_MetaTileEntity_Disassembler; +import net.minecraft.item.ItemStack; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.Optional; +import java.util.Queue; + +import static gregtech.api.util.GT_Recipe.GT_Recipe_Map.sDisassemblerRecipes; + +public class ReverseShapedRecipe { + private static Queue<ReverseShapedRecipe> reverseRecipes = new LinkedList<>(); + private ItemStack aResult; + private Object[] aRecipe; + + public static Queue<ReverseShapedRecipe> getReverseRecipes() { + return reverseRecipes; + } + + public ReverseShapedRecipe(ItemStack output, Object[] aRecipe) { + this.aResult = output; + this.aRecipe = aRecipe; + reverseRecipes.add(this); + } + + public static void runReverseRecipes() { + for (ReverseShapedRecipe x : reverseRecipes) { + Optional<GT_Recipe> recipeOptional = GT_Utility.reverseShapedRecipe(x.aResult, x.aRecipe); + if (!recipeOptional.isPresent()) + continue; + GT_Recipe recipe = recipeOptional.get(); + ItemStack[] replacement = new ItemStack[recipe.mOutputs.length]; + GT_MetaTileEntity_Disassembler.handleRecipeTransformation(recipe.mOutputs, replacement, Collections.singleton(recipe.mOutputs)); + + recipe.mOutputs = replacement; + sDisassemblerRecipes.add(recipe); + } + } +} diff --git a/src/main/java/gregtech/api/objects/ReverseShapelessRecipe.java b/src/main/java/gregtech/api/objects/ReverseShapelessRecipe.java new file mode 100644 index 0000000000..1c5e27d246 --- /dev/null +++ b/src/main/java/gregtech/api/objects/ReverseShapelessRecipe.java @@ -0,0 +1,43 @@ +package gregtech.api.objects; + +import gregtech.api.util.GT_Recipe; +import gregtech.api.util.GT_Utility; +import gregtech.common.tileentities.machines.basic.GT_MetaTileEntity_Disassembler; +import net.minecraft.item.ItemStack; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.Optional; +import java.util.Queue; + +import static gregtech.api.util.GT_Recipe.GT_Recipe_Map.sDisassemblerRecipes; + +public class ReverseShapelessRecipe { + private static Queue<ReverseShapelessRecipe> reverseRecipes = new LinkedList<>(); + private ItemStack aResult; + private Object[] aRecipe; + + public static Queue<ReverseShapelessRecipe> getReverseRecipes() { + return reverseRecipes; + } + + public ReverseShapelessRecipe(ItemStack output, Object[] aRecipe) { + this.aResult = output; + this.aRecipe = aRecipe; + reverseRecipes.add(this); + } + + public static void runReverseRecipes() { + for (ReverseShapelessRecipe x : reverseRecipes) { + Optional<GT_Recipe> recipeOptional = GT_Utility.reverseShapelessRecipe(x.aResult, x.aRecipe); + if (!recipeOptional.isPresent()) + continue; + GT_Recipe recipe = recipeOptional.get(); + ItemStack[] replacement = new ItemStack[recipe.mOutputs.length]; + GT_MetaTileEntity_Disassembler.handleRecipeTransformation(recipe.mOutputs, replacement, Collections.singleton(recipe.mOutputs)); + + recipe.mOutputs = replacement; + sDisassemblerRecipes.add(recipe); + } + } +} diff --git a/src/main/java/gregtech/api/util/GT_Recipe.java b/src/main/java/gregtech/api/util/GT_Recipe.java index 537d92b365..9756a8199a 100644 --- a/src/main/java/gregtech/api/util/GT_Recipe.java +++ b/src/main/java/gregtech/api/util/GT_Recipe.java @@ -561,7 +561,7 @@ public class GT_Recipe implements Comparable<GT_Recipe> { public static final GT_Recipe_Map sRecyclerRecipes = new GT_Recipe_Map_Recycler(new HashSet<>(0), "ic.recipe.recycler", "Recycler", "ic2.recycler", RES_PATH_GUI + "basicmachines/Recycler", 1, 1, 1, 0, 1, E, 1, E, true, false); public static final GT_Recipe_Map sFurnaceRecipes = new GT_Recipe_Map_Furnace(new HashSet<>(0), "mc.recipe.furnace", "Furnace", "smelting", RES_PATH_GUI + "basicmachines/E_Furnace", 1, 1, 1, 0, 1, E, 1, E, true, false); public static final GT_Recipe_Map sMicrowaveRecipes = new GT_Recipe_Map_Microwave(new HashSet<>(0), "gt.recipe.microwave", "Microwave", "smelting", RES_PATH_GUI + "basicmachines/E_Furnace", 1, 1, 1, 0, 1, E, 1, E, true, false); - + public static final GT_Recipe_Map sDisassemblerRecipes = new GT_Recipe_Map(new HashSet<>(250), "gt.recipe.disassembler", "Disassembler", null, RES_PATH_GUI + "basicmachines/Disassembler", 1, 9, 1, 0, 1, E, 1, E, true, false); public static final GT_Recipe_Map sScannerFakeRecipes = new GT_Recipe_Map(new HashSet<>(300), "gt.recipe.scanner", "Scanner", null, RES_PATH_GUI + "basicmachines/Scanner", 1, 1, 1, 0, 1, E, 1, E, true, true); public static final GT_Recipe_Map sRockBreakerFakeRecipes = new GT_Recipe_Map(new HashSet<>(200), "gt.recipe.rockbreaker", "Rock Breaker", null, RES_PATH_GUI + "basicmachines/RockBreaker", 1, 1, 0, 0, 1, E, 1, E, true, true); public static final GT_Recipe_Map sByProductList = new GT_Recipe_Map(new HashSet<>(1000), "gt.recipe.byproductlist", "Ore Byproduct List", null, RES_PATH_GUI + "basicmachines/Default", 1, 6, 1, 0, 1, E, 1, E, true, true); diff --git a/src/main/java/gregtech/api/util/GT_Shaped_Recipe.java b/src/main/java/gregtech/api/util/GT_Shaped_Recipe.java index e51c490519..f00fc7758e 100644 --- a/src/main/java/gregtech/api/util/GT_Shaped_Recipe.java +++ b/src/main/java/gregtech/api/util/GT_Shaped_Recipe.java @@ -1,7 +1,7 @@ package gregtech.api.util; import gregtech.api.interfaces.internal.IGT_CraftingRecipe; -import gregtech.api.items.GT_MetaGenerated_Tool; +import gregtech.api.objects.ReverseShapedRecipe; import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.inventory.InventoryCrafting; @@ -11,7 +11,7 @@ import net.minecraft.world.World; import net.minecraftforge.oredict.ShapedOreRecipe; public class GT_Shaped_Recipe extends ShapedOreRecipe implements IGT_CraftingRecipe { - public final boolean mDismantleable, mRemovableByGT, mKeepingNBT; + public final boolean mRemovableByGT, mKeepingNBT; private final Enchantment[] mEnchantmentsAdded; private final int[] mEnchantmentLevelsAdded; @@ -21,7 +21,9 @@ public class GT_Shaped_Recipe extends ShapedOreRecipe implements IGT_CraftingRec mEnchantmentLevelsAdded = aEnchantmentLevelsAdded; mRemovableByGT = aRemovableByGT; mKeepingNBT = aKeepingNBT; - mDismantleable = aDismantleAble; + if (aDismantleAble) { + new ReverseShapedRecipe(aResult, aRecipe); + } } @Override @@ -65,23 +67,6 @@ public class GT_Shaped_Recipe extends ShapedOreRecipe implements IGT_CraftingRec if (tCharge > 0) GT_ModHandler.chargeElectricItem(rStack, tCharge, Integer.MAX_VALUE, true, false); } - // Saving Ingredients inside the Item. - if (mDismantleable) { - NBTTagCompound rNBT = rStack.getTagCompound(), tNBT = new NBTTagCompound(); - if (rNBT == null) rNBT = new NBTTagCompound(); - for (int i = 0; i < 9; i++) { - ItemStack tStack = aGrid.getStackInSlot(i); - if (tStack != null && GT_Utility.getContainerItem(tStack, true) == null && !(tStack.getItem() instanceof GT_MetaGenerated_Tool)) { - tStack = GT_Utility.copyAmount(1, tStack); - if(GT_Utility.isStackValid(tStack)){ - GT_ModHandler.dischargeElectricItem(tStack, Integer.MAX_VALUE, Integer.MAX_VALUE, true, false, true); - tNBT.setTag("Ingredient." + i, tStack.writeToNBT(new NBTTagCompound()));} - } - } - rNBT.setTag("GT.CraftingComponents", tNBT); - rStack.setTagCompound(rNBT); - } - // Add Enchantments for (int i = 0; i < mEnchantmentsAdded.length; i++) GT_Utility.ItemNBT.addEnchantment(rStack, mEnchantmentsAdded[i], EnchantmentHelper.getEnchantmentLevel(mEnchantmentsAdded[i].effectId, rStack) + mEnchantmentLevelsAdded[i]); diff --git a/src/main/java/gregtech/api/util/GT_Shapeless_Recipe.java b/src/main/java/gregtech/api/util/GT_Shapeless_Recipe.java index 937ba0a837..fce135dfe6 100644 --- a/src/main/java/gregtech/api/util/GT_Shapeless_Recipe.java +++ b/src/main/java/gregtech/api/util/GT_Shapeless_Recipe.java @@ -1,7 +1,7 @@ package gregtech.api.util; import gregtech.api.interfaces.internal.IGT_CraftingRecipe; -import gregtech.api.items.GT_MetaGenerated_Tool; +import gregtech.api.objects.ReverseShapelessRecipe; import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.inventory.InventoryCrafting; @@ -11,7 +11,7 @@ import net.minecraft.world.World; import net.minecraftforge.oredict.ShapelessOreRecipe; public class GT_Shapeless_Recipe extends ShapelessOreRecipe implements IGT_CraftingRecipe { - public final boolean mDismantleable, mRemovableByGT, mKeepingNBT; + public final boolean /*mDismantleable,*/ mRemovableByGT, mKeepingNBT; private final Enchantment[] mEnchantmentsAdded; private final int[] mEnchantmentLevelsAdded; @@ -21,7 +21,9 @@ public class GT_Shapeless_Recipe extends ShapelessOreRecipe implements IGT_Craft mEnchantmentLevelsAdded = aEnchantmentLevelsAdded; mRemovableByGT = aRemovableByGT; mKeepingNBT = aKeepingNBT; - mDismantleable = aDismantleAble; + if (aDismantleAble){ + new ReverseShapelessRecipe(aResult, aRecipe); + } } @Override @@ -66,20 +68,20 @@ public class GT_Shapeless_Recipe extends ShapelessOreRecipe implements IGT_Craft } // Saving Ingredients inside the Item. - if (mDismantleable) { - NBTTagCompound rNBT = rStack.getTagCompound(), tNBT = new NBTTagCompound(); - if (rNBT == null) rNBT = new NBTTagCompound(); - for (int i = 0; i < 9; i++) { - ItemStack tStack = aGrid.getStackInSlot(i); - if (tStack != null && GT_Utility.getContainerItem(tStack, true) == null && !(tStack.getItem() instanceof GT_MetaGenerated_Tool)) { - tStack = GT_Utility.copyAmount(1, tStack); - GT_ModHandler.dischargeElectricItem(tStack, Integer.MAX_VALUE, Integer.MAX_VALUE, true, false, true); - tNBT.setTag("Ingredient." + i, tStack.writeToNBT(new NBTTagCompound())); - } - } - rNBT.setTag("GT.CraftingComponents", tNBT); - rStack.setTagCompound(rNBT); - } +// if (mDismantleable) { +// NBTTagCompound rNBT = rStack.getTagCompound(), tNBT = new NBTTagCompound(); +// if (rNBT == null) rNBT = new NBTTagCompound(); +// for (int i = 0; i < 9; i++) { +// ItemStack tStack = aGrid.getStackInSlot(i); +// if (tStack != null && GT_Utility.getContainerItem(tStack, true) == null && !(tStack.getItem() instanceof GT_MetaGenerated_Tool)) { +// tStack = GT_Utility.copyAmount(1, tStack); +// GT_ModHandler.dischargeElectricItem(tStack, Integer.MAX_VALUE, Integer.MAX_VALUE, true, false, true); +// tNBT.setTag("Ingredient." + i, tStack.writeToNBT(new NBTTagCompound())); +// } +// } +// rNBT.setTag("GT.CraftingComponents", tNBT); +// rStack.setTagCompound(rNBT); +// } // Add Enchantments for (int i = 0; i < mEnchantmentsAdded.length; i++) diff --git a/src/main/java/gregtech/api/util/GT_Utility.java b/src/main/java/gregtech/api/util/GT_Utility.java index 3530fa17c2..adc0f95881 100644 --- a/src/main/java/gregtech/api/util/GT_Utility.java +++ b/src/main/java/gregtech/api/util/GT_Utility.java @@ -14,6 +14,7 @@ import gregtech.api.interfaces.ITexture; import gregtech.api.interfaces.tileentity.*; import gregtech.api.items.GT_EnergyArmor_Item; import gregtech.api.items.GT_Generic_Item; +import gregtech.api.items.GT_MetaGenerated_Tool; import gregtech.api.net.GT_Packet_Sound; import gregtech.api.objects.GT_CopiedBlockTexture; import gregtech.api.objects.GT_ItemStack; @@ -1022,7 +1023,7 @@ public class GT_Utility { return copyMetaData(Items.feather.getDamage(aStack) + 1, aStack); return null; } - + public static synchronized boolean removeIC2BottleRecipe(ItemStack aContainer, ItemStack aInput, Map<ic2.api.recipe.ICannerBottleRecipeManager.Input, RecipeOutput> aRecipeList, ItemStack aOutput){ if ((isStackInvalid(aInput) && isStackInvalid(aOutput) && isStackInvalid(aContainer)) || aRecipeList == null) return false; boolean rReturn = false; @@ -1742,7 +1743,7 @@ public class GT_Utility { if(aDimensionID<=1 && aDimensionID>=-1 && !GregTech_API.sDimensionalList.contains(aDimensionID)) return true; return !GregTech_API.sDimensionalList.contains(aDimensionID) && DimensionManager.isDimensionRegistered(aDimensionID); } - + //public static boolean isRealDimension(int aDimensionID) { // try { // if (DimensionManager.getProvider(aDimensionID).getClass().getName().contains("com.xcompwiz.mystcraft")) @@ -1756,7 +1757,7 @@ public class GT_Utility { // } catch (Throwable e) {/*Do nothing*/} // return GregTech_API.sDimensionalList.contains(aDimensionID); //} - + public static boolean moveEntityToDimensionAtCoords(Entity entity, int aDimension, double aX, double aY, double aZ) { //Credit goes to BrandonCore Author :!: @@ -2040,7 +2041,7 @@ public class GT_Utility { if (D1) e.printStackTrace(GT_Log.err); } } - + if (aPlayer.capabilities.isCreativeMode) { FluidStack tFluid = undergroundOilReadInformation(aWorld.getChunkFromBlockCoords(aX,aZ));//-# to only read if (tFluid!=null) @@ -2355,7 +2356,7 @@ public class GT_Utility { setBookTitle(aStack, "Raw Prospection Data"); NBTTagCompound tNBT = GT_Utility.ItemNBT.getNBT(aStack); - + tNBT.setByte("prospection_tier", aTier); tNBT.setString("prospection_pos", "Dim: " + aDim + "\nX: " + aX + " Y: " + aY + " Z: " + aZ); @@ -2369,27 +2370,27 @@ public class GT_Utility { String[] aStats = aStr.split(","); tOilsTransformed.add(aStats[0] + ": " + aStats[1] + "L " + aStats[2]); } - + tNBT.setString("prospection_oils", joinListToString(tOilsTransformed)); String tOilsPosStr = "X: " + Math.floorDiv(aX, 16*8)*16*8 + " Z: " + Math.floorDiv(aZ, 16*8)*16*8 + "\n"; int xOff = aX - Math.floorDiv(aX, 16*8)*16*8; xOff = xOff/16; int xOffRemain = 7 - xOff; - + int zOff = aZ - Math.floorDiv(aZ, 16*8)*16*8; zOff = zOff/16; int zOffRemain = 7 - zOff; - + for( ; zOff > 0; zOff-- ) { tOilsPosStr = tOilsPosStr.concat("--------\n"); } for( ; xOff > 0; xOff-- ) { tOilsPosStr = tOilsPosStr.concat("-"); } - + tOilsPosStr = tOilsPosStr.concat("P"); - + for( ; xOffRemain > 0; xOffRemain-- ) { tOilsPosStr = tOilsPosStr.concat("-"); } @@ -2444,11 +2445,11 @@ public class GT_Utility { + "Location is center of orevein\n\n" + "Check NEI to confirm orevein type"; tNBTList.appendTag(new NBTTagString(tPageText)); - + if (tOres != null) fillBookWithList(tNBTList, "Ores Found %s\n\n", "\n", 7, tOres); - + if (tOils != null) fillBookWithList(tNBTList, "Oils%s\n\n", "\n", 9, tOils); @@ -2466,7 +2467,7 @@ public class GT_Utility { tOilsPosStr + "\n" + "P - Prospector in 8x8 field"; tNBTList.appendTag(new NBTTagString(tPageText)); - + tNBT.setString("author", tPos.replace("\n"," ")); tNBT.setTag("pages", tNBTList); setNBT(aStack, tNBT); @@ -2606,11 +2607,11 @@ public class GT_Utility { } public static boolean isPartOfMaterials(ItemStack aStack, Materials aMaterials){ - return GT_OreDictUnificator.getAssociation(aStack) != null ? GT_OreDictUnificator.getAssociation(aStack).mMaterial.mMaterial.equals(aMaterials) : false; + return GT_OreDictUnificator.getAssociation(aStack) != null && GT_OreDictUnificator.getAssociation(aStack).mMaterial.mMaterial.equals(aMaterials); } public static boolean isPartOfOrePrefix(ItemStack aStack, OrePrefixes aPrefix){ - return GT_OreDictUnificator.getAssociation(aStack) != null ? GT_OreDictUnificator.getAssociation(aStack).mPrefix.equals(aPrefix) : false; + return GT_OreDictUnificator.getAssociation(aStack) != null && GT_OreDictUnificator.getAssociation(aStack).mPrefix.equals(aPrefix); } public static boolean isOre(ItemStack aStack) { for (int id: OreDictionary.getOreIDs(aStack)) { @@ -2620,4 +2621,152 @@ public class GT_Utility { return false; } + public static Optional<GT_Recipe> reverseShapelessRecipe(ItemStack output, Object... aRecipe) { + if (output == null) { + return Optional.empty(); + } + + List<ItemStack> inputs = new ArrayList<>(); + + for (Object o : aRecipe) { + if (o instanceof ItemStack) { + ItemStack toAdd = ((ItemStack) o).copy(); + inputs.add(toAdd); + } else if (o instanceof String) { + ItemStack stack = GT_OreDictUnificator.get(o, 1); + if (stack == null) { + Optional<ItemStack> oStack = OreDictionary.getOres((String) o) + .stream() + .findAny(); + if (oStack.isPresent()) { + ItemStack copy = oStack.get().copy(); + inputs.add(copy); + } + } else { + ItemStack copy = stack.copy(); + inputs.add(copy); + } + } else if (o instanceof Item) + inputs.add(new ItemStack((Item) o)); + else if (o instanceof Block) + inputs.add(new ItemStack((Block) o)); + else + throw new IllegalStateException("A Recipe contains an invalid input! Output: " + output); + } + + inputs.removeIf(x -> x.getItem() instanceof GT_MetaGenerated_Tool); + + return Optional.of( + new GT_Recipe( + false, + new ItemStack[]{output}, + inputs.toArray(new ItemStack[0]), + null, null, + null, null, + 300, 30, 0 + ) + ); + } + + + public static Optional<GT_Recipe> reverseShapedRecipe(ItemStack output, Object... aRecipe) { + if (output == null) { +// System.out.println("Null Recipe detected!"); + return Optional.empty(); + } +// System.out.println("Registering Reverse Recipe for: " + GT_LanguageManager.getTranslation(GT_LanguageManager.getTranslateableItemStackName(output) + "|" + output.getUnlocalizedName())); +// for (Object o : aRecipe) { +// String toPrint; +// if (o instanceof String) { +// toPrint = (String) o; +// toPrint += " String"; +// } else if (o instanceof ItemStack) { +// toPrint = GT_LanguageManager.getTranslation(GT_LanguageManager.getTranslateableItemStackName((ItemStack) o)); +// toPrint += " ItemStack"; +// } else if (o instanceof List) { +// toPrint = String.join(", ", ((List<String>) o)); +// toPrint += " List<String>"; +// } else if (o instanceof Item) { +// toPrint = GT_LanguageManager.getTranslation(GT_LanguageManager.getTranslateableItemStackName(new ItemStack((Item) o))); +// toPrint += " Item"; +// } else if (o instanceof Block) { +// toPrint = GT_LanguageManager.getTranslation(GT_LanguageManager.getTranslateableItemStackName(new ItemStack((Block) o))); +// toPrint += " Block"; +// } else if (o != null) { +// toPrint = o.toString(); +// toPrint += " Other"; +// } else { +// toPrint = "NULL"; +// } +// System.out.println(toPrint); +// } + Map<Object, Integer> recipeAsMap = new HashMap<>(); + Map<Character, Object> ingridients = new HashMap<>(); + Map<Character, Integer> amounts = new HashMap<>(); + boolean startFound = false; + for (int i = 0, aRecipeLength = aRecipe.length; i < aRecipeLength; i++) { + Object o = aRecipe[i]; + if (!startFound) { + if (o instanceof String) { + for (Character c : ((String) o).toCharArray()) + amounts.merge(c, 1, (a, b) -> ++a); + } else if (o instanceof Character) + startFound = true; + } else if (!(o instanceof Character)) + ingridients.put((Character) aRecipe[i - 1], o); + } + for (Map.Entry<Character, Object> characterObjectEntry : ingridients.entrySet()) { + for (Map.Entry<Character, Integer> characterIntegerEntry : amounts.entrySet()) { + if (characterObjectEntry.getKey() != characterIntegerEntry.getKey()) + continue; + recipeAsMap.put(characterObjectEntry.getValue(), characterIntegerEntry.getValue()); + } + } + List<ItemStack> inputs = new ArrayList<>(); + + for (Map.Entry<Object, Integer> o : recipeAsMap.entrySet()) { + if (o.getKey() instanceof ItemStack) { + ItemStack toAdd = ((ItemStack) o.getKey()).copy(); + toAdd.stackSize = o.getValue(); + inputs.add(toAdd); + } else if (o.getKey() instanceof String) { +// System.out.println("Found OreDictEntry: "+o.getKey()); + ItemStack stack = GT_OreDictUnificator.get(o.getKey(), o.getValue()); + if (stack == null) { + Optional<ItemStack> oStack = OreDictionary.getOres((String) o.getKey()) + .stream() + .findAny(); + if (oStack.isPresent()) { + ItemStack copy = oStack.get().copy(); + copy.stackSize = o.getValue(); + inputs.add(copy); + } +// else +// System.out.println("OreDict Entry "+o.getKey()+" couldn't be found!"); + } else { + ItemStack copy = stack.copy(); + copy.stackSize = o.getValue(); + inputs.add(copy); + } + } else if (o.getKey() instanceof Item) + inputs.add(new ItemStack((Item) o.getKey(), o.getValue())); + else if (o.getKey() instanceof Block) + inputs.add(new ItemStack((Block) o.getKey(), o.getValue())); + else + throw new IllegalStateException("A Recipe contains an invalid input! Output: " + output); + } + + inputs.removeIf(x -> x.getItem() instanceof GT_MetaGenerated_Tool); + + return Optional.of( + new GT_Recipe( + false, + new ItemStack[]{output}, + inputs.toArray(new ItemStack[0]), + null, null, + null, null, + 300, 30, 0 + ) + ); + } } diff --git a/src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Disassembler.java b/src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Disassembler.java index ce1812a9cf..92ed054b05 100644 --- a/src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Disassembler.java +++ b/src/main/java/gregtech/common/tileentities/machines/basic/GT_MetaTileEntity_Disassembler.java @@ -1,15 +1,34 @@ package gregtech.common.tileentities.machines.basic; -import gregtech.api.enums.GT_Values; +import com.google.common.collect.ArrayListMultimap; +import gregtech.api.GregTech_API; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; import gregtech.api.enums.Textures; import gregtech.api.interfaces.ITexture; +import gregtech.api.interfaces.metatileentity.IMetaTileEntity; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.items.GT_MetaGenerated_Tool; import gregtech.api.metatileentity.MetaTileEntity; import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_BasicMachine; +import gregtech.api.metatileentity.implementations.GT_MetaTileEntity_TieredMachineBlock; +import gregtech.api.objects.GT_ItemStack; import gregtech.api.objects.GT_RenderedTexture; +import gregtech.api.objects.ItemData; +import gregtech.api.util.GT_OreDictUnificator; +import gregtech.api.util.GT_Recipe; import gregtech.api.util.GT_Utility; +import net.minecraft.init.Blocks; +import net.minecraft.init.Items; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.oredict.OreDictionary; + +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; +import java.util.stream.IntStream; public class GT_MetaTileEntity_Disassembler extends GT_MetaTileEntity_BasicMachine { @@ -29,79 +48,380 @@ public class GT_MetaTileEntity_Disassembler return new GT_MetaTileEntity_Disassembler(this.mName, this.mTier, this.mDescriptionArray, this.mTextures, this.mGUIName, this.mNEIName); } + private static final ItemStack[][] alwaysReplace = new ItemStack[][]{ + { + //ItemStack to look for + new ItemStack(Blocks.trapped_chest, 1, OreDictionary.WILDCARD_VALUE) + }, + { + //ItemStack to replace + new ItemStack(Blocks.chest) + } + }; + + private static final Object[][] OreDictionaryOverride = new Object[][]{ + { + //String to look for + "plankWood", + "stoneCobble", + "gemDiamond", + "logWood", + "stickWood", + "treeSapling" + }, + { + //ItemStack to replace + new ItemStack(Blocks.planks), + new ItemStack(Blocks.cobblestone), + new ItemStack(Items.diamond), + new ItemStack(Blocks.log), + new ItemStack(Items.stick), + new ItemStack(Blocks.sapling) + } + }; + + public static ArrayListMultimap<GT_ItemStack, ItemStack> getOutputHardOverrides() { + return outputHardOverrides; + } + + private static final ArrayListMultimap<GT_ItemStack, ItemStack> outputHardOverrides; + + static { + outputHardOverrides = ArrayListMultimap.create(); + outputHardOverrides.put(new GT_ItemStack(new ItemStack(Blocks.torch,6)), new ItemStack(Items.stick)); + } + public int checkRecipe() { - //if ((getInputAt(0) != null) && (isOutputEmpty())) { - // if(GT_Utility.areStacksEqual(getInputAt(0), new ItemStack(Items.egg))){ - // getInputAt(0).stackSize -= 1; - // this.mEUt = (16 * (1 << this.mTier - 1) * (1 << this.mTier - 1)); - // this.mMaxProgresstime = 2400; - // this.mMaxProgresstime = this.mMaxProgresstime >> (mTier); - //if (getBaseMetaTileEntity().getRandomNumber(100) < (this.mTier+1)) { - // this.mOutputItems[0] = ItemList.Circuit_Chip_Stemcell.get(1, new Object[0]); - //} - //return 2; - //} - NBTTagCompound tNBT = getInputAt(0).getTagCompound(); - if (tNBT != null) { - tNBT = tNBT.getCompoundTag("GT.CraftingComponents"); - if (tNBT != null) { - boolean isAnyOutput=false; - calculateOverclockedNessDisassembler(16); - this.mMaxProgresstime = 80; - //In case recipe is too OP for that machine - if (mEUt == Integer.MAX_VALUE - 1)//&& mMaxProgresstime==Integer.MAX_VALUE-1 - return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; - for (int i = 0; i < this.mOutputItems.length; i++) { - if (getBaseMetaTileEntity().getRandomNumber(100) < 50 + 10 * this.mTier) { - this.mOutputItems[i] = GT_Utility.loadItem(tNBT, "Ingredient." + i); - if (this.mOutputItems[i] != null) { - this.mMaxProgresstime *= 1.7F; - isAnyOutput=true; - } - } - } - if(!isAnyOutput) - return DID_NOT_FIND_RECIPE; - for(int i=mTier-5;i>0;i--){ - this.mMaxProgresstime>>=1; - if(this.mMaxProgresstime==0) - this.mEUt = this.mEUt>>1; - } - if(this.mEUt==0) - mEUt = 1; - if(this.mMaxProgresstime==0) - this.mMaxProgresstime = 1; - getInputAt(0).stackSize -= 1; - return FOUND_AND_SUCCESSFULLY_USED_RECIPE; - } + ItemStack is = getInputAt(0); + if (GT_Utility.isStackInvalid(is)) + return DID_NOT_FIND_RECIPE; + if (is.getItem() instanceof GT_MetaGenerated_Tool) + return DID_NOT_FIND_RECIPE; + ItemStack comp = new ItemStack(GregTech_API.sBlockMachines); + if (is.getItem() == comp.getItem()) { + IMetaTileEntity iMetaTileEntity = GregTech_API.METATILEENTITIES[is.getItemDamage()]; + if (iMetaTileEntity instanceof GT_MetaTileEntity_TieredMachineBlock && + ((GT_MetaTileEntity_TieredMachineBlock) iMetaTileEntity).mTier > this.mTier) + return FOUND_RECIPE_BUT_DID_NOT_MEET_REQUIREMENTS; + } + Set<GT_ItemStack> stacks = outputHardOverrides.keySet(); + for (GT_ItemStack stack : stacks) { + ItemStack in = is.copy(); + in.stackSize = 1; + if (stack.isStackEqual(in) && stack.mStackSize <= is.stackSize) { + return setOutputsAndTime(outputHardOverrides.get(stack).toArray(new ItemStack[0]), stack.mStackSize) + ? FOUND_AND_SUCCESSFULLY_USED_RECIPE + : DID_NOT_FIND_RECIPE; } + } + return process() + ? FOUND_AND_SUCCESSFULLY_USED_RECIPE + : DID_NOT_FIND_RECIPE; + } + + private boolean process(){ + + GT_Recipe gt_recipe = GT_Recipe.GT_Recipe_Map.sDisassemblerRecipes.findRecipe(this.getBaseMetaTileEntity(), true, this.mEUt, null, this.getAllInputs()); + if (gt_recipe != null) { + gt_recipe.isRecipeInputEqual(true, null, this.getRealInventory()); + return setOutputsAndTime(gt_recipe.mOutputs, gt_recipe.mInputs[0].stackSize); + } + + Collection<DissassembleReference> recipes = this.findRecipeFromMachine(); + if (recipes.isEmpty()) + return false; - return DID_NOT_FIND_RECIPE; + DissassembleReference recipe = ensureDowncasting(recipes); + + for (int i = 0; i < recipe.inputs.length; i++) + if (GT_Utility.isStackInvalid(recipe.inputs[i]) || recipe.inputs[i].stackSize < 1) + recipe.inputs[i] = null; + + recipe.inputs = GT_Utility.getArrayListWithoutNulls(recipe.inputs).toArray(new ItemStack[0]); + + return setOutputsAndTime(recipe.inputs, recipe.stackSize); } - private void calculateOverclockedNessDisassembler(int aEUt) { - if(mTier==0){ - mEUt=aEUt>>2; - }else{ - //Long EUt calculation - long xEUt=aEUt; - //Isnt too low EUt check? - long tempEUt = xEUt<GT_Values.V[1] ? GT_Values.V[1] : xEUt; + private boolean setOutputsAndTime(ItemStack[] inputs, int stackSize){ + if (this.getInputAt(0).stackSize >= stackSize) + this.getInputAt(0).stackSize -= stackSize; + else + return false; + + System.arraycopy(inputs, 0, this.mOutputItems, 0, inputs.length); + this.calculateOverclockedNess(30,600); + + return true; + } + + private static DissassembleReference ensureDowncasting(Collection<DissassembleReference> recipes) { + ItemStack[] inputs = recipes.stream() + .findFirst() + .orElseThrow(NullPointerException::new) + .inputs; + + ItemStack[] output = new ItemStack[inputs.length]; + List<GT_Recipe> recipesColl = null; + if (recipes.size() > 1) + recipesColl = recipes.stream() + .skip(1) + .map(x -> x.recipe) + .collect(Collectors.toList()); + + handleRecipeTransformation(inputs, output, recipesColl); - while (tempEUt <= GT_Values.V[mTier -1] * (long)mAmperage) { - tempEUt<<=2;//this actually controls overclocking - xEUt<<=2;//this is effect of overclocking + return new DissassembleReference(recipes.stream().mapToInt(x -> x.stackSize).min().orElseThrow(NumberFormatException::new), output, null); + } + + private static void handleRecipeTransformation(ItemStack[] inputs, ItemStack[] output, List<GT_Recipe> recipesColl) { + for (int i = 0, inputsLength = inputs.length; i < inputsLength; i++) { + Set<ItemStack[]> inputsStacks = null; + if (recipesColl != null) + inputsStacks = recipesColl.stream() + .map(x -> x.mInputs) + .collect(Collectors.toSet()); + ItemStack input = inputs[i]; + ItemData data = GT_OreDictUnificator.getItemData(input); + if (data == null || data.mMaterial == null || data.mMaterial.mMaterial == null || data.mPrefix == null) { + output[i] = input; + continue; } - if(xEUt>Integer.MAX_VALUE-1){ - mEUt = Integer.MAX_VALUE-1; - }else{ - mEUt = (int)xEUt; + handleReplacement(inputsStacks, data, output, input, i); + } + addOthersAndHandleAlwaysReplace(inputs, output); + } + + /** + * Public Interface for ReverseRecipes, do not call inside of this class. + * @param inputs + * @param output + * @param inputsStacks + */ + public static void handleRecipeTransformation(ItemStack[] inputs, ItemStack[] output, Set<ItemStack[]> inputsStacks) { + for (int i = 0, inputsLength = inputs.length; i < inputsLength; i++) { + ItemStack input = inputs[i]; + ItemData data = GT_OreDictUnificator.getItemData(input); + if (data == null || data.mMaterial == null || data.mMaterial.mMaterial == null || data.mPrefix == null) { + output[i] = input; + continue; } + handleReplacement(inputsStacks, data, output, input, i); } + addOthersAndHandleAlwaysReplace(inputs, output); + } + + private static void addOthersAndHandleAlwaysReplace(ItemStack[] inputs, ItemStack[] output){ + for (int i = 0; i < inputs.length; i++) { + //Adds rest of Items + if (output[i] == null) + output[i] = inputs[i]; + + //Math.min the recipe output if Items are the same + if (GT_Utility.areStacksEqual(output[i], inputs[i])) + output[i].stackSize = Math.min(output[i].stackSize, inputs[i].stackSize); + + //Handles replacement Overrides + ItemStack[] itemStacks = GT_MetaTileEntity_Disassembler.alwaysReplace[0]; + for (int j = 0; j < itemStacks.length; j++) { + ItemStack x = itemStacks[j]; + if (GT_Utility.areStacksEqual(x, output[i], true)) { + output[i] = GT_MetaTileEntity_Disassembler.alwaysReplace[1][j]; + break; + } + } + + //Unification + output[i] = handleUnification(output[i]); + } + } + + private static ItemStack handleUnification(ItemStack stack) { + for (int oreID : OreDictionary.getOreIDs(stack)) { + for (int i = 0; i < OreDictionaryOverride[0].length; i++) + if (OreDictionary.getOreName(oreID).equals(OreDictionaryOverride[0][i])){ + ItemStack ret = ((ItemStack) OreDictionaryOverride[1][i]).copy(); + ret.stackSize = stack.stackSize; + return ret; + } + } + return GT_OreDictUnificator.get(stack); + } + + private static void handleReplacement(Set<ItemStack[]> inputsStacks, ItemData data, ItemStack[] output, ItemStack input, int i){ + AtomicReference<Materials> toRpl = new AtomicReference<>(); + Materials first = data.mMaterial.mMaterial; + if (inputsStacks != null) { + handleInputStacks(inputsStacks, toRpl, data, first, i); + } + if (toRpl.get() == null) { + //Remove Magnetic and Annealed Modifiers + handleBetterMaterialsVersions(data, toRpl); + } + if (toRpl.get() != null) { + output[i] = GT_OreDictUnificator.get(data.mPrefix, toRpl.get(), input.stackSize); + return; + } + if (data.mPrefix == OrePrefixes.circuit) { + handleCircuits(first, output, input, i); + } + } + + private static void handleInputStacks(Set<ItemStack[]> inputsStacks, AtomicReference<Materials> toRpl, ItemData data, Materials first, int i){ + final int finalIndex = i; + inputsStacks.forEach(stackArray -> { + ItemData dataAgainst = GT_OreDictUnificator.getItemData(stackArray[finalIndex]); + if ( + dataAgainst == null || + dataAgainst.mMaterial == null || + dataAgainst.mMaterial.mMaterial == null || + dataAgainst.mPrefix == null || + dataAgainst.mPrefix != data.mPrefix + ) { + return; + } + handleDifferentMaterialsOnRecipes(first, dataAgainst.mMaterial.mMaterial, toRpl); + handleAnyMaterials(first,toRpl); + }); + } + + private static void handleAnyMaterials(Materials first, AtomicReference<Materials> toRpl){ + if (first.mOreReRegistrations.stream().anyMatch(y -> y.equals(Materials.AnyIron))) + toRpl.set(Materials.Iron); + else if (first.mOreReRegistrations.stream().anyMatch(y -> y.equals(Materials.AnyCopper))) + toRpl.set(Materials.Copper); + else if (first.mOreReRegistrations.stream().anyMatch(y -> y.equals(Materials.AnyRubber))) + toRpl.set(Materials.Rubber); + else if (first.mOreReRegistrations.stream().anyMatch(y -> y.equals(Materials.AnyBronze))) + toRpl.set(Materials.Bronze); + else if (first.mOreReRegistrations.stream().anyMatch(y -> y.equals(Materials.AnySyntheticRubber))) + toRpl.set(Materials.Rubber); + } + + private static void handleDifferentMaterialsOnRecipes(Materials first, Materials second, AtomicReference<Materials> toRpl){ + if (!first.equals(second)) + if (first.equals(Materials.Aluminium) && second.equals(Materials.Iron)) + toRpl.set(second); + else if (first.equals(Materials.Steel) && second.equals(Materials.Iron)) + toRpl.set(second); + else if (first.equals(Materials.WroughtIron) && second.equals(Materials.Iron)) + toRpl.set(second); + else if (first.equals(Materials.Aluminium) && second.equals(Materials.WroughtIron)) + toRpl.set(Materials.Iron); + else if (first.equals(Materials.Aluminium) && second.equals(Materials.Steel)) + toRpl.set(second); + else if (first.equals(Materials.Polytetrafluoroethylene) && second.equals(Materials.Plastic)) + toRpl.set(second); + else if (first.equals(Materials.Polybenzimidazole) && second.equals(Materials.Plastic)) + toRpl.set(second); + else if (first.equals(Materials.Polystyrene) && second.equals(Materials.Plastic)) + toRpl.set(second); + else if (first.equals(Materials.Silicone) && second.equals(Materials.Plastic)) + toRpl.set(second); + else if (first.equals(Materials.NetherQuartz) || first.equals(Materials.CertusQuartz) && second.equals(Materials.Quartzite)) + toRpl.set(second); + else if (first.equals(Materials.Plastic) && second.equals(Materials.Wood)) + toRpl.set(second); + else if (first.equals(Materials.Diamond) && second.equals(Materials.Glass)) + toRpl.set(second); + } + + private static void handleBetterMaterialsVersions(ItemData data, AtomicReference<Materials> toRpl){ + if (Materials.SteelMagnetic.equals(data.mMaterial.mMaterial)) { + toRpl.set(Materials.Steel); + } else if (Materials.IronMagnetic.equals(data.mMaterial.mMaterial)) { + toRpl.set(Materials.Iron); + } else if (Materials.NeodymiumMagnetic.equals(data.mMaterial.mMaterial)) { + toRpl.set(Materials.Neodymium); + } else if (Materials.SamariumMagnetic.equals(data.mMaterial.mMaterial)) { + toRpl.set(Materials.Samarium); + } else if (Materials.AnnealedCopper.equals(data.mMaterial.mMaterial)) { + toRpl.set(Materials.Copper); + } + } + + @SuppressWarnings("deprecation") + private static void handleCircuits(Materials first, ItemStack[] output, ItemStack input, int i){ + if (first.equals(Materials.Primitive)) + output[i] = ItemList.NandChip.get(input.stackSize); + else if (first.equals(Materials.Basic)) + output[i] = ItemList.Circuit_Microprocessor.get(input.stackSize); + else if (first.equals(Materials.Good)) + output[i] = ItemList.Circuit_Good.get(input.stackSize); + else if (first.equals(Materials.Advanced)) + output[i] = ItemList.Circuit_Advanced.get(input.stackSize); + else if (first.equals(Materials.Data)) + output[i] = ItemList.Circuit_Data.get(input.stackSize); + else if (first.equals(Materials.Master)) + output[i] = ItemList.Circuit_Master.get(input.stackSize); + else if (first.equals(Materials.Ultimate)) + output[i] = ItemList.Circuit_Quantummainframe.get(input.stackSize); + else if (first.equals(Materials.Superconductor)) + output[i] = ItemList.Circuit_Crystalmainframe.get(input.stackSize); + else if (first.equals(Materials.Infinite)) + output[i] = ItemList.Circuit_Wetwaremainframe.get(input.stackSize); + else if (first.equals(Materials.Bio)) + output[i] = ItemList.Circuit_Biomainframe.get(input.stackSize); + } + + static class DissassembleReference { + final int stackSize; + ItemStack[] inputs; + final GT_Recipe recipe; + + public DissassembleReference(int stackSize, ItemStack[] inputs, GT_Recipe recipe) { + this.stackSize = stackSize; + this.inputs = inputs; + this.recipe = recipe; + } + } + + private Collection<DissassembleReference> findRecipeFromMachine() { + ItemStack is = getInputAt(0); + if (GT_Utility.isStackInvalid(is)) + return Collections.emptySet(); + + AtomicInteger stacksize = new AtomicInteger(); + //Check Recipe Maps for creation of Item + List<DissassembleReference> possibleRecipes = GT_Recipe.GT_Recipe_Map.sAssemblerRecipes.mRecipeList.stream() + .filter(x -> Arrays.stream(x.mOutputs) + .anyMatch(y -> + { + ItemStack out = is.copy(); + out.stackSize = y.stackSize; + boolean isDone = GT_Utility.areStacksEqual(y, out, true) && y.stackSize <= is.stackSize; + if (isDone) + stacksize.set(y.stackSize); + return isDone; + }) + ) + .map(x -> new DissassembleReference(stacksize.get(), x.mInputs, x)) + .collect(Collectors.toList()); + + //Is there only one way to create it? + if (possibleRecipes.size() == 1) + return possibleRecipes; + + //There are Multiple Ways -> Get recipe with cheapest inputs + //More Inputs should mean cheaper Materials + return possibleRecipes + .stream() + .sorted(Comparator.comparingDouble(x -> + { + double fluidInputValueRaw = Arrays.stream(x.recipe.mFluidInputs).flatMapToInt(f -> IntStream.of(f.amount)).sum(); + fluidInputValueRaw = fluidInputValueRaw > 0 ? fluidInputValueRaw : 144D; + double inputValue = Arrays.stream(x.inputs).flatMapToInt(f -> IntStream.of(f.stackSize)).sum() + + (fluidInputValueRaw / 144D); + double fluidOutputValueRaw = Arrays.stream(x.recipe.mFluidOutputs).flatMapToInt(f -> IntStream.of(f.amount)).sum(); + fluidOutputValueRaw = fluidOutputValueRaw > 0 ? fluidOutputValueRaw : 144D; + double outputValue = Arrays.stream(x.recipe.mOutputs).flatMapToInt(f -> IntStream.of(f.stackSize)).sum() + + (fluidOutputValueRaw / 144D); + return inputValue / outputValue; + } + )).collect(Collectors.toList()); } public boolean allowPutStack(IGregTechTileEntity aBaseMetaTileEntity, int aIndex, byte aSide, ItemStack aStack) { return //(aIndex == 4 && GT_Utility.areStacksEqual(aStack, new ItemStack(Items.egg))) || (super.allowPutStack(aBaseMetaTileEntity, aIndex, aSide, aStack)) && (aStack.getTagCompound() != null) && (aStack.getTagCompound().getCompoundTag("GT.CraftingComponents") != null); } -} +}
\ No newline at end of file |