From 3b6bc659ee5a38644ce0c3e55dbc3363e3a7100e Mon Sep 17 00:00:00 2001 From: Jason Mitchell Date: Sat, 2 Jan 2021 20:50:56 -0800 Subject: 1) Remove mAddGTRecipesToIC2Machines (stolen from @Glease) 2) Batch (most) recipe map removals and additions (significant speedup) 3) Modernize old java constructs --> java8 (in the files touched) --- src/main/java/gregtech/GT_Mod.java | 106 +- src/main/java/gregtech/api/util/GT_ModHandler.java | 335 ++++-- .../gregtech/api/util/GT_OreDictUnificator.java | 28 +- src/main/java/gregtech/api/util/GT_Utility.java | 256 ++-- src/main/java/gregtech/common/GT_Proxy.java | 91 +- .../loaders/oreprocessing/ProcessingArrows.java | 32 +- .../loaders/oreprocessing/ProcessingBeans.java | 2 +- .../loaders/oreprocessing/ProcessingBlock.java | 17 +- .../loaders/oreprocessing/ProcessingBolt.java | 2 +- .../loaders/oreprocessing/ProcessingCell.java | 31 +- .../loaders/oreprocessing/ProcessingCircuit.java | 14 +- .../oreprocessing/ProcessingCompressed.java | 2 +- .../loaders/oreprocessing/ProcessingCrafting.java | 96 +- .../loaders/oreprocessing/ProcessingCrate.java | 24 +- .../loaders/oreprocessing/ProcessingCrop.java | 64 +- .../oreprocessing/ProcessingCrushedOre.java | 10 +- .../oreprocessing/ProcessingCrystallized.java | 4 +- .../loaders/oreprocessing/ProcessingDirty.java | 20 +- .../loaders/oreprocessing/ProcessingDust.java | 97 +- .../loaders/oreprocessing/ProcessingDye.java | 10 +- .../loaders/oreprocessing/ProcessingFineWire.java | 6 +- .../loaders/oreprocessing/ProcessingFood.java | 19 +- .../loaders/oreprocessing/ProcessingGear.java | 12 +- .../loaders/oreprocessing/ProcessingGem.java | 2 +- .../loaders/oreprocessing/ProcessingIngot.java | 2 +- .../loaders/oreprocessing/ProcessingItem.java | 23 +- .../loaders/oreprocessing/ProcessingLens.java | 2 +- .../loaders/oreprocessing/ProcessingLog.java | 85 +- .../loaders/oreprocessing/ProcessingNugget.java | 10 +- .../loaders/oreprocessing/ProcessingOre.java | 28 +- .../loaders/oreprocessing/ProcessingOrePoor.java | 6 +- .../oreprocessing/ProcessingOreSmelting.java | 4 +- .../loaders/oreprocessing/ProcessingPipe.java | 20 +- .../loaders/oreprocessing/ProcessingPlank.java | 46 +- .../loaders/oreprocessing/ProcessingPlate.java | 83 +- .../loaders/oreprocessing/ProcessingPure.java | 4 +- .../loaders/oreprocessing/ProcessingRotor.java | 6 +- .../loaders/oreprocessing/ProcessingRound.java | 6 +- .../loaders/oreprocessing/ProcessingSand.java | 4 +- .../loaders/oreprocessing/ProcessingSaplings.java | 6 +- .../loaders/oreprocessing/ProcessingScrew.java | 4 +- .../loaders/oreprocessing/ProcessingShaping.java | 108 +- .../loaders/oreprocessing/ProcessingSlab.java | 2 +- .../loaders/oreprocessing/ProcessingStick.java | 14 +- .../loaders/oreprocessing/ProcessingStickLong.java | 12 +- .../loaders/oreprocessing/ProcessingStone.java | 50 +- .../oreprocessing/ProcessingStoneCobble.java | 8 +- .../oreprocessing/ProcessingStoneVarious.java | 4 +- .../loaders/oreprocessing/ProcessingToolHead.java | 98 +- .../loaders/oreprocessing/ProcessingToolOther.java | 6 +- .../oreprocessing/ProcessingTransforming.java | 22 +- .../loaders/oreprocessing/ProcessingWax.java | 2 +- .../loaders/oreprocessing/ProcessingWire.java | 38 +- .../loaders/postload/GT_CraftingRecipeLoader.java | 1228 +++++++++----------- 54 files changed, 1606 insertions(+), 1605 deletions(-) (limited to 'src/main/java') diff --git a/src/main/java/gregtech/GT_Mod.java b/src/main/java/gregtech/GT_Mod.java index 1844fb77c5..62148430b5 100644 --- a/src/main/java/gregtech/GT_Mod.java +++ b/src/main/java/gregtech/GT_Mod.java @@ -1,5 +1,6 @@ package gregtech; +import com.google.common.base.Stopwatch; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.LoadController; import cpw.mods.fml.common.Loader; @@ -424,7 +425,6 @@ public class GT_Mod implements IGT_Mod { gregtechproxy.mPollutionVegetationLimit = tMainConfig.get("Pollution", "VegetationLimit", 1000000).getInt(1000000); gregtechproxy.mPollutionSourRainLimit = tMainConfig.get("Pollution", "SourRainLimit", 2000000).getInt(2000000); gregtechproxy.mExplosionItemDrop = tMainConfig.get("general", "ExplosionItemDrops", false).getBoolean(false); - gregtechproxy.mAddGTRecipesToIC2Machines = tMainConfig.get("general", "AddGTRecipesToIC2Machines", true).getBoolean(true); gregtechproxy.mUndergroundOil.getConfig(tMainConfig, "undergroundfluid"); gregtechproxy.mEnableCleanroom = tMainConfig.get("general", "EnableCleanroom", true).getBoolean(true); gregtechproxy.mLowGravProcessing = Loader.isModLoaded(GT_Values.MOD_ID_GC_CORE) && tMainConfig.get("general", "LowGravProcessing", true).getBoolean(true); @@ -815,10 +815,10 @@ public class GT_Mod implements IGT_Mod { if (!GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.storageblockcrafting, "tile.glowstone", false)) { GT_ModHandler.removeRecipe(new ItemStack(Items.glowstone_dust, 1), new ItemStack(Items.glowstone_dust, 1), null, new ItemStack(Items.glowstone_dust, 1), new ItemStack(Items.glowstone_dust, 1)); } - GT_ModHandler.removeRecipe(new ItemStack(Blocks.wooden_slab, 1, 0), new ItemStack(Blocks.wooden_slab, 1, 1), new ItemStack(Blocks.wooden_slab, 1, 2)); - GT_ModHandler.addCraftingRecipe(new ItemStack(Blocks.wooden_slab, 6, 0), GT_ModHandler.RecipeBits.NOT_REMOVABLE, new Object[]{"WWW", 'W', new ItemStack(Blocks.planks, 1, 0)}); + GT_ModHandler.removeRecipeDelayed(new ItemStack(Blocks.wooden_slab, 1, 0), new ItemStack(Blocks.wooden_slab, 1, 1), new ItemStack(Blocks.wooden_slab, 1, 2)); + GT_ModHandler.addCraftingRecipe(new ItemStack(Blocks.wooden_slab, 6, 0), GT_ModHandler.RecipeBits.NOT_REMOVABLE | GT_ModHandler.RecipeBits.BUFFERED, new Object[]{"WWW", 'W', new ItemStack(Blocks.planks, 1, 0)}); - //Save a copy of these list before activateOreDictHandler(), then loop over them. + // Save a copy of these list before activateOreDictHandler(), then loop over them. Map aMaceratorRecipeList = GT_ModHandler.getMaceratorRecipeList(); Map aCompressorRecipeList = GT_ModHandler.getCompressorRecipeList(); Map aExtractorRecipeList = GT_ModHandler.getExtractorRecipeList(); @@ -827,14 +827,18 @@ public class GT_Mod implements IGT_Mod { GT_Log.out.println("GT_Mod: Activating OreDictionary Handler, this can take some time, as it scans the whole OreDictionary"); GT_FML_LOGGER.info("If your Log stops here, you were too impatient. Wait a bit more next time, before killing Minecraft with the Task Manager."); - long ms = System.currentTimeMillis(); + + Stopwatch stopwatch = Stopwatch.createStarted(); gregtechproxy.activateOreDictHandler(); - GT_FML_LOGGER.info("Congratulations, you have been waiting long enough (" + (System.currentTimeMillis() - ms) / 1000 + "s / " + (System.currentTimeMillis() - ms) + "ms). Have a Cake."); + GT_FML_LOGGER.info("Congratulations, you have been waiting long enough (" + stopwatch.stop() + "). Have a Cake."); GT_Log.out.println("GT_Mod: List of Lists of Tool Recipes: " + GT_ModHandler.sSingleNonBlockDamagableRecipeList_list.toString()); GT_Log.out.println("GT_Mod: Vanilla Recipe List -> Outputs null or stackSize <=0: " + GT_ModHandler.sVanillaRecipeList_warntOutput.toString()); GT_Log.out.println("GT_Mod: Single Non Block Damagable Recipe List -> Outputs null or stackSize <=0: " + GT_ModHandler.sSingleNonBlockDamagableRecipeList_warntOutput.toString()); - //GT_Log.out.println("GT_Mod: sRodMaterialList cycles: " + GT_RecipeRegistrator.sRodMaterialList_cycles); + Set replaceVanillaItemsSet = gregtechproxy.mUseGreatlyShrukenReplacementList ? Arrays.stream(Materials.values()).filter(GT_RecipeRegistrator::hasVanillaRecipes).collect(Collectors.toSet()) : new HashSet<>(Arrays.asList(Materials.values())); + + stopwatch.reset(); + stopwatch.start(); GT_FML_LOGGER.info("Replacing Vanilla Materials in recipes, please wait."); ProgressManager.ProgressBar progressBar = ProgressManager.push("Register materials", replaceVanillaItemsSet.size()); @@ -853,14 +857,20 @@ public class GT_Mod implements IGT_Mod { }); } ProgressManager.pop(progressBar); - GT_FML_LOGGER.info("Congratulations, you have been waiting long enough (" + (System.currentTimeMillis() - ms) / 1000 + "s / " + (System.currentTimeMillis() - ms) + "ms). Have a Cake."); + GT_FML_LOGGER.info("Congratulations, you have been waiting long enough (" + stopwatch.stop() + "). Have a Cake."); + + + stopwatch.reset(); + stopwatch.start(); //Add default IC2 recipe to GT GT_ModHandler.addIC2RecipesToGT(aMaceratorRecipeList, GT_Recipe.GT_Recipe_Map.sMaceratorRecipes, true, true, true); GT_ModHandler.addIC2RecipesToGT(aCompressorRecipeList, GT_Recipe.GT_Recipe_Map.sCompressorRecipes, true, true, true); GT_ModHandler.addIC2RecipesToGT(aExtractorRecipeList, GT_Recipe.GT_Recipe_Map.sExtractorRecipes, true, true, true); GT_ModHandler.addIC2RecipesToGT(aOreWashingRecipeList, GT_Recipe.GT_Recipe_Map.sOreWasherRecipes, false, true, true); GT_ModHandler.addIC2RecipesToGT(aThermalCentrifugeRecipeList, GT_Recipe.GT_Recipe_Map.sThermalCentrifugeRecipes, true, true, true); - + GT_FML_LOGGER.info("IC2 Removal (" + stopwatch.stop() + "). Have a Cake."); + + if (GT_Values.D1) { GT_ModHandler.sSingleNonBlockDamagableRecipeList.forEach(iRecipe -> GT_Log.out.println("=> " + iRecipe.getRecipeOutput().getDisplayName())); } @@ -888,61 +898,16 @@ public class GT_Mod implements IGT_Mod { } if (Loader.isModLoaded(MOD_ID_AE)) GT_MetaTileEntity_DigitalChestBase.registerAEIntegration(); - String tName = ""; - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "blastfurnace"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "blockcutter"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "inductionFurnace"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "generator"), false)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "windMill"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "waterMill"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "solarPanel"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "centrifuge"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "electrolyzer"), false)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "compressor"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "electroFurnace"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "extractor"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "macerator"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "recycler"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "metalformer"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "orewashingplant"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "massFabricator"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } - if (GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + (tName = "replicator"), true)) { - GT_ModHandler.removeRecipeByOutput(GT_ModHandler.getIC2Item(tName, 1L)); - } + + + Arrays.stream(new String[]{ + "blastfurnace", "blockcutter", "inductionFurnace", "generator", "windMill", "waterMill", "solarPanel", "centrifuge", "electrolyzer", "compressor", + "electroFurnace", "extractor", "macerator", "recycler", "metalformer", "orewashingplant", "massFabricator", "replicator", + }) + .filter(tName -> GregTech_API.sRecipeFile.get(ConfigCategories.Recipes.disabledrecipes, aTextIC2 + tName, true)) + .map(tName -> GT_ModHandler.getIC2Item(tName, 1L)).forEach(GT_ModHandler::removeRecipeByOutputDelayed); + + if (gregtechproxy.mNerfedVanillaTools) { GT_Log.out.println("GT_Mod: Nerfing Vanilla Tool Durability"); Items.wooden_sword.setMaxDamage(12); @@ -976,9 +941,20 @@ public class GT_Mod implements IGT_Mod { Items.diamond_hoe.setMaxDamage(768); } new GT_ExtremeDieselFuelLoader().run(); + + + /* + * Until this point most crafting recipe additions, and removals, have been buffered. + * Go through, execute the removals in bulk, and then any deferred additions. The bulk removals in particular significantly speed up the recipe list + * modifications. + */ + + stopwatch.reset(); + stopwatch.start(); GT_Log.out.println("GT_Mod: Adding buffered Recipes."); GT_ModHandler.stopBufferingCraftingRecipes(); - + GT_FML_LOGGER.info("Executed delayed Crafting Recipes (" + stopwatch.stop() + "). Have a Cake."); + GT_Log.out.println("GT_Mod: Saving Lang File."); GT_LanguageManager.sEnglishFile.save(); GregTech_API.sPostloadFinished = true; diff --git a/src/main/java/gregtech/api/util/GT_ModHandler.java b/src/main/java/gregtech/api/util/GT_ModHandler.java index bfa3f86e77..e8d311da39 100644 --- a/src/main/java/gregtech/api/util/GT_ModHandler.java +++ b/src/main/java/gregtech/api/util/GT_ModHandler.java @@ -54,11 +54,11 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; +import java.util.Set; import java.util.stream.Collectors; import static gregtech.api.enums.GT_Values.B; @@ -78,22 +78,28 @@ import static gregtech.api.enums.GT_Values.W; * Due to the many imports, this File can cause compile Problems if not all the APIs are installed */ public class GT_ModHandler { - public static final List sSingleNonBlockDamagableRecipeList = new ArrayList(1000); - private static final Map sIC2ItemMap = new HashMap(); - private static final List sAllRecipeList = /*Collections.synchronizedList(*/new ArrayList(5000)/*)*/, sBufferRecipeList = new ArrayList(1000); + public static final List sSingleNonBlockDamagableRecipeList = new ArrayList<>(1000); + private static final Map sIC2ItemMap = new HashMap<>(); + + private static final List sAllRecipeList = new ArrayList<>(5000), sBufferRecipeList = new ArrayList<>(1000); + private static final List delayedRemovalByOutput = new ArrayList<>(); + private static final List delayedRemovalByRecipe = new ArrayList<>(); + + public static volatile int VERSION = 509; - public static Collection sNativeRecipeClasses = new HashSet(), sSpecialRecipeClasses = new HashSet(); - public static GT_HashSet sNonReplaceableItems = new GT_HashSet(); + public static Collection sNativeRecipeClasses = new HashSet<>(), sSpecialRecipeClasses = new HashSet<>(); + public static GT_HashSet sNonReplaceableItems = new GT_HashSet<>(); public static Object sBoxableWrapper = GT_Utility.callConstructor("gregtechmod.api.util.GT_IBoxableWrapper", 0, null, false); - private static Map sExtractorRecipes = new /*Concurrent*/HashMap(); - private static Map sMaceratorRecipes = new /*Concurrent*/HashMap(); - private static Map sCompressorRecipes = new /*Concurrent*/HashMap(); - private static Map sOreWashingRecipes = new /*Concurrent*/HashMap(); - private static Map sThermalCentrifugeRecipes = new /*Concurrent*/HashMap(); - private static Map sMassfabRecipes = new /*Concurrent*/HashMap(); + private static final Map sExtractorRecipes = new HashMap<>(); + private static final Map sMaceratorRecipes = new HashMap<>(); + private static final Map sCompressorRecipes = new HashMap<>(); + private static final Map sOreWashingRecipes = new HashMap<>(); + private static final Map sThermalCentrifugeRecipes = new HashMap<>(); + private static final Map sMassfabRecipes = new HashMap<>(); + private static boolean sBufferCraftingRecipes = true; - public static List sSingleNonBlockDamagableRecipeList_list = new ArrayList(100); - private static boolean sSingleNonBlockDamagableRecipeList_create = true; + public static List sSingleNonBlockDamagableRecipeList_list = new ArrayList<>(100); + private static final boolean sSingleNonBlockDamagableRecipeList_create = true; private static final ItemStack sMt1 = new ItemStack(Blocks.dirt, 1, 0), sMt2 = new ItemStack(Blocks.dirt, 1, 0); private static final String s_H = "h", s_F = "f", s_I = "I", s_P = "P", s_R = "R"; private static final ItemStack[][] @@ -143,11 +149,11 @@ public class GT_ModHandler { {sMt1, sMt1, null, sMt2, null, sMt1, sMt2, null, null}, {null, sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2} }; - public static List sSingleNonBlockDamagableRecipeList_validsShapes1 = new ArrayList(44); + public static List sSingleNonBlockDamagableRecipeList_validsShapes1 = new ArrayList<>(44); public static boolean sSingleNonBlockDamagableRecipeList_validsShapes1_update = false; - public static List sSingleNonBlockDamagableRecipeList_warntOutput = new ArrayList(50); - public static List sVanillaRecipeList_warntOutput = new ArrayList(50); - public static final List sSingleNonBlockDamagableRecipeList_verified = new ArrayList(1000); + public static List sSingleNonBlockDamagableRecipeList_warntOutput = new ArrayList<>(50); + public static List sVanillaRecipeList_warntOutput = new ArrayList<>(50); + public static final List sSingleNonBlockDamagableRecipeList_verified = new ArrayList<>(1000); private static Cache sSmeltingRecipeCache = CacheBuilder.newBuilder().maximumSize(1000).build(); public static List sAnySteamFluidIDs = new ArrayList<>(); public static List sSuperHeatedSteamFluidIDs = new ArrayList<>(); @@ -542,10 +548,8 @@ public class GT_ModHandler { public static boolean addExtractionRecipe(ItemStack aInput, ItemStack aOutput) { aOutput = GT_OreDictUnificator.get(true, aOutput); if (aInput == null || aOutput == null) return false; - if (GT_Mod.gregtechproxy.mAddGTRecipesToIC2Machines) GT_Utility.removeSimpleIC2MachineRecipe(aInput, getExtractorRecipeList(), null); if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.extractor, aInput, true)) return false; RA.addExtractorRecipe(aInput, aOutput, 300, 2); - if (GT_Mod.gregtechproxy.mAddGTRecipesToIC2Machines) GT_Utility.addSimpleIC2MachineRecipe(aInput, getExtractorRecipeList(), null, aOutput); return true; } @@ -597,12 +601,8 @@ public class GT_ModHandler { aOutput1 = GT_OreDictUnificator.get(true, aOutput1); aOutput2 = GT_OreDictUnificator.get(true, aOutput2); if (GT_Utility.isStackInvalid(aInput) || GT_Utility.isStackInvalid(aOutput1)) return false; - if (GT_Mod.gregtechproxy.mAddGTRecipesToIC2Machines) GT_Utility.removeSimpleIC2MachineRecipe(aInput, getMaceratorRecipeList(), null); if (GT_Utility.getContainerItem(aInput, false) == null) { - if (GT_Mod.gregtechproxy.mAddGTRecipesToIC2Machines && GregTech_API.sRecipeFile.get(ConfigCategories.Machines.maceration, aInput, true)) { - GT_Utility.addSimpleIC2MachineRecipe(aInput, getMaceratorRecipeList(), null, aOutput1); - } addMagneticraftRecipe(aInput, aOutput1, aOutput2, aChance2, aOutput3, aChance3); addImmersiveEngineeringRecipe(aInput, aOutput1, aOutput2, aChance2, aOutput3, aChance3); RA.addPulveriserRecipe(aInput, new ItemStack[]{aOutput1, aOutput2, aOutput3}, new int[]{10000, aChance2 <= 0 ? 1000 : 100 * aChance2, aChance3 <= 0 ? 1000 : 100 * aChance3}, 400, 2); @@ -720,39 +720,34 @@ public class GT_ModHandler { */ public static void addIC2RecipesToGT(Map aIC2RecipeList, GT_Recipe.GT_Recipe_Map aGTRecipeMap, boolean aAddGTRecipe, boolean aRemoveIC2Recipe, boolean aExcludeGTIC2Items) { Map aRecipesToRemove = new HashMap<>(); - for (Iterator i$ = aIC2RecipeList.entrySet().iterator(); i$.hasNext(); ) { - Entry tRecipe = (Map.Entry) i$.next(); - if (((RecipeOutput) tRecipe.getValue()).items.size() > 0) { - for (ItemStack tStack : ((IRecipeInput) tRecipe.getKey()).getInputs()) { + for (Entry iRecipeInputRecipeOutputEntry : aIC2RecipeList.entrySet()) { + if ((iRecipeInputRecipeOutputEntry.getValue()).items.size() > 0) { + for (ItemStack tStack : (iRecipeInputRecipeOutputEntry.getKey()).getInputs()) { if (GT_Utility.isStackValid(tStack)) { if (aAddGTRecipe && (aGTRecipeMap.findRecipe(null, false, Long.MAX_VALUE, null, tStack) == null)) { - try{ - if (aExcludeGTIC2Items && ((tStack.getUnlocalizedName().contains("gt.metaitem.01") || tStack.getUnlocalizedName().contains("gt.blockores") || tStack.getUnlocalizedName().contains("ic2.itemCrushed") || tStack.getUnlocalizedName().contains("ic2.itemPurifiedCrushed")))) continue; - switch (aGTRecipeMap.mUnlocalizedName) { - case "gt.recipe.macerator": - aGTRecipeMap.addRecipe(true, new ItemStack[]{GT_Utility.copyAmount(((IRecipeInput) tRecipe.getKey()).getAmount(), tStack)}, (ItemStack[]) ((RecipeOutput) tRecipe.getValue()).items.toArray(), null, null, null, null, 300, 2, 0); - break; - case "gt.recipe.compressor": - aGTRecipeMap.addRecipe(true, new ItemStack[]{GT_Utility.copyAmount(((IRecipeInput) tRecipe.getKey()).getAmount(), tStack)}, (ItemStack[]) ((RecipeOutput) tRecipe.getValue()).items.toArray(), null, null, null, null, 300, 2, 0); - break; - case "gt.recipe.extractor": - aGTRecipeMap.addRecipe(true, new ItemStack[]{GT_Utility.copyAmount(((IRecipeInput) tRecipe.getKey()).getAmount(), tStack)}, (ItemStack[]) ((RecipeOutput) tRecipe.getValue()).items.toArray(), null, null, null, null, 300, 2, 0); - break; - case "gt.recipe.thermalcentrifuge": - aGTRecipeMap.addRecipe(true, new ItemStack[]{GT_Utility.copyAmount(((IRecipeInput) tRecipe.getKey()).getAmount(), tStack)}, (ItemStack[]) ((RecipeOutput) tRecipe.getValue()).items.toArray(), null, null, null, null, 500, 48, 0); - break; + try { + if (aExcludeGTIC2Items && ((tStack.getUnlocalizedName().contains("gt.metaitem.01") || tStack.getUnlocalizedName().contains("gt.blockores") || tStack.getUnlocalizedName().contains("ic2.itemCrushed") || tStack.getUnlocalizedName().contains("ic2.itemPurifiedCrushed")))) + continue; + switch (aGTRecipeMap.mUnlocalizedName) { + case "gt.recipe.macerator": + case "gt.recipe.extractor": + case "gt.recipe.compressor": + aGTRecipeMap.addRecipe(true, new ItemStack[]{GT_Utility.copyAmount((iRecipeInputRecipeOutputEntry.getKey()).getAmount(), tStack)}, (ItemStack[]) (iRecipeInputRecipeOutputEntry.getValue()).items.toArray(), null, null, null, null, 300, 2, 0); + break; + case "gt.recipe.thermalcentrifuge": + aGTRecipeMap.addRecipe(true, new ItemStack[]{GT_Utility.copyAmount((iRecipeInputRecipeOutputEntry.getKey()).getAmount(), tStack)}, (ItemStack[]) (iRecipeInputRecipeOutputEntry.getValue()).items.toArray(), null, null, null, null, 500, 48, 0); + break; + } + } catch (Exception e) { + System.err.println(e); } - }catch(Exception e){System.err.println(e);} - //GT_FML_LOGGER.info("#####Processed IC2 " + aGTRecipeMap.mUnlocalizedName + " Recipe: In(" + tStack.getUnlocalizedName() + ") - Out(" + ((RecipeOutput) tRecipe.getValue()).items.get(0).getUnlocalizedName() + ")"); } - if (aRemoveIC2Recipe) aRecipesToRemove.put(tStack, ((RecipeOutput) tRecipe.getValue()).items.get(0)); + if (aRemoveIC2Recipe) aRecipesToRemove.put(tStack, ((RecipeOutput) iRecipeInputRecipeOutputEntry.getValue()).items.get(0)); } } } } - for (Entry aEntry : aRecipesToRemove.entrySet()) { - GT_Utility.removeSimpleIC2MachineRecipe(aEntry.getKey(), aIC2RecipeList, aEntry.getValue()); - } + GT_Utility.bulkRemoveSimpleIC2MachineRecipe(aRecipesToRemove, aIC2RecipeList); } public static Map getExtractorRecipeList() { @@ -802,14 +797,8 @@ public class GT_ModHandler { */ public static boolean addThermalCentrifugeRecipe(ItemStack aInput, int aHeat, Object... aOutput) { if (aInput == null || aOutput == null || aOutput.length <= 0 || aOutput[0] == null) return false; - if (GT_Mod.gregtechproxy.mAddGTRecipesToIC2Machines) GT_Utility.removeSimpleIC2MachineRecipe(aInput, getThermalCentrifugeRecipeList(), null); if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.thermalcentrifuge, aInput, true)) return false; RA.addThermalCentrifugeRecipe(aInput, aOutput.length >= 1 ? (ItemStack)aOutput[0] : null, aOutput.length >= 2 ? (ItemStack)aOutput[1] : null, aOutput.length >= 3 ? (ItemStack)aOutput[2] : null, 500, 48); - if (GT_Mod.gregtechproxy.mAddGTRecipesToIC2Machines) { - NBTTagCompound tNBT = new NBTTagCompound(); - tNBT.setInteger("minHeat", aHeat); - GT_Utility.addSimpleIC2MachineRecipe(aInput, getThermalCentrifugeRecipeList(), tNBT, aOutput); - } return true; } @@ -818,15 +807,9 @@ public class GT_ModHandler { */ public static boolean addOreWasherRecipe(ItemStack aInput, int aWaterAmount, Object... aOutput) { if (aInput == null || aOutput == null || aOutput.length <= 0 || aOutput[0] == null) return false; - if (GT_Mod.gregtechproxy.mAddGTRecipesToIC2Machines) GT_Utility.removeSimpleIC2MachineRecipe(aInput, getOreWashingRecipeList(), null); if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.orewashing, aInput, true)) return false; RA.addOreWasherRecipe(aInput, (ItemStack)aOutput[0], (ItemStack)aOutput[1], (ItemStack)aOutput[2], GT_ModHandler.getWater(1000L), 500, 16); RA.addOreWasherRecipe(aInput, (ItemStack)aOutput[0], (ItemStack)aOutput[1], (ItemStack)aOutput[2], GT_ModHandler.getDistilledWater(200L), 300, 16); - if (GT_Mod.gregtechproxy.mAddGTRecipesToIC2Machines) { - NBTTagCompound tNBT = new NBTTagCompound(); - tNBT.setInteger("amount", aWaterAmount); - GT_Utility.addSimpleIC2MachineRecipe(aInput, getOreWashingRecipeList(), tNBT, aOutput); - } return true; } @@ -836,10 +819,8 @@ public class GT_ModHandler { public static boolean addCompressionRecipe(ItemStack aInput, ItemStack aOutput) { aOutput = GT_OreDictUnificator.get(true, aOutput); if (aInput == null || aOutput == null || GT_Utility.areStacksEqual(aInput, aOutput, true)) return false; - if (GT_Mod.gregtechproxy.mAddGTRecipesToIC2Machines) GT_Utility.removeSimpleIC2MachineRecipe(aInput, getCompressorRecipeList(), null); if (!GregTech_API.sRecipeFile.get(ConfigCategories.Machines.compression, aInput, true)) return false; RA.addCompressorRecipe(aInput, aOutput, 300, 2); - if (GT_Mod.gregtechproxy.mAddGTRecipesToIC2Machines) GT_Utility.addSimpleIC2MachineRecipe(aInput, getCompressorRecipeList(), null, aOutput); return true; } @@ -873,7 +854,13 @@ public class GT_ModHandler { public static void stopBufferingCraftingRecipes() { sBufferCraftingRecipes = false; - for (IRecipe tRecipe : sBufferRecipeList) {GameRegistry.addRecipe(tRecipe);} + + bulkRemoveRecipeByOutput(delayedRemovalByOutput); + bulkRemoveByRecipe(delayedRemovalByRecipe); + sBufferRecipeList.forEach(GameRegistry::addRecipe); + + delayedRemovalByOutput.clear(); + delayedRemovalByRecipe.clear(); sBufferRecipeList.clear(); } @@ -937,18 +924,54 @@ public class GT_ModHandler { * 'x' ToolDictNames.craftingToolWireCutter, */ public static boolean addCraftingRecipe(ItemStack aResult, long aBitMask, Object[] aRecipe) { - return addCraftingRecipe(aResult, new Enchantment[0], new int[0], (aBitMask & RecipeBits.MIRRORED) != 0, (aBitMask & RecipeBits.BUFFERED) != 0, (aBitMask & RecipeBits.KEEPNBT) != 0, (aBitMask & RecipeBits.DISMANTLEABLE) != 0, (aBitMask & RecipeBits.NOT_REMOVABLE) == 0, (aBitMask & RecipeBits.REVERSIBLE) != 0, (aBitMask & RecipeBits.DELETE_ALL_OTHER_RECIPES) != 0, (aBitMask & RecipeBits.DELETE_ALL_OTHER_RECIPES_IF_SAME_NBT) != 0, (aBitMask & RecipeBits.DELETE_ALL_OTHER_SHAPED_RECIPES) != 0, (aBitMask & RecipeBits.DELETE_ALL_OTHER_NATIVE_RECIPES) != 0, (aBitMask & RecipeBits.DO_NOT_CHECK_FOR_COLLISIONS) == 0, (aBitMask & RecipeBits.ONLY_ADD_IF_THERE_IS_ANOTHER_RECIPE_FOR_IT) != 0, (aBitMask & RecipeBits.ONLY_ADD_IF_RESULT_IS_NOT_NULL) != 0, aRecipe); + return addCraftingRecipe( + aResult, + new Enchantment[0], + new int[0], + (aBitMask & RecipeBits.MIRRORED) != 0, + (aBitMask & RecipeBits.BUFFERED) != 0, + (aBitMask & RecipeBits.KEEPNBT) != 0, + (aBitMask & RecipeBits.DISMANTLEABLE) != 0, + (aBitMask & RecipeBits.NOT_REMOVABLE) == 0, + (aBitMask & RecipeBits.REVERSIBLE) != 0, + (aBitMask & RecipeBits.DELETE_ALL_OTHER_RECIPES) != 0, + (aBitMask & RecipeBits.DELETE_ALL_OTHER_RECIPES_IF_SAME_NBT) != 0, + (aBitMask & RecipeBits.DELETE_ALL_OTHER_SHAPED_RECIPES) != 0, + (aBitMask & RecipeBits.DELETE_ALL_OTHER_NATIVE_RECIPES) != 0, + (aBitMask & RecipeBits.DO_NOT_CHECK_FOR_COLLISIONS) == 0, + (aBitMask & RecipeBits.ONLY_ADD_IF_THERE_IS_ANOTHER_RECIPE_FOR_IT) != 0, + (aBitMask & RecipeBits.ONLY_ADD_IF_RESULT_IS_NOT_NULL) != 0, + aRecipe); } /** * Internal realisation of the Crafting Recipe adding Process. */ - private static boolean addCraftingRecipe(ItemStack aResult, Enchantment[] aEnchantmentsAdded, int[] aEnchantmentLevelsAdded, boolean aMirrored, boolean aBuffered, boolean aKeepNBT, boolean aDismantleable, boolean aRemovable, boolean aReversible, boolean aRemoveAllOthersWithSameOutput, boolean aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT, boolean aRemoveAllOtherShapedsWithSameOutput, boolean aRemoveAllOtherNativeRecipes, boolean aCheckForCollisions, boolean aOnlyAddIfThereIsAnyRecipeOutputtingThis, boolean aOnlyAddIfResultIsNotNull, Object[] aRecipe) { + private static boolean addCraftingRecipe( + ItemStack aResult, + Enchantment[] aEnchantmentsAdded, + int[] aEnchantmentLevelsAdded, + boolean aMirrored, + boolean aBuffered, + boolean aKeepNBT, + boolean aDismantleable, + boolean aRemovable, + boolean aReversible, + boolean aRemoveAllOthersWithSameOutput, + boolean aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT, + boolean aRemoveAllOtherShapedsWithSameOutput, + boolean aRemoveAllOtherNativeRecipes, + boolean aCheckForCollisions, + boolean aOnlyAddIfThereIsAnyRecipeOutputtingThis, + boolean aOnlyAddIfResultIsNotNull, + Object[] aRecipe + ) { aResult = GT_OreDictUnificator.get(true, aResult); if (aOnlyAddIfResultIsNotNull && aResult == null) return false; if (aResult != null && Items.feather.getDamage(aResult) == W) Items.feather.setDamage(aResult, 0); if (aRecipe == null || aRecipe.length <= 0) return false; + boolean tDoWeCareIfThereWasARecipe = aOnlyAddIfThereIsAnyRecipeOutputtingThis; boolean tThereWasARecipe = false; for (byte i = 0; i < aRecipe.length; i++) { @@ -961,21 +984,21 @@ public class GT_ModHandler { } try { - String shape = E; + StringBuilder shape = new StringBuilder(E); int idx = 0; if (aRecipe[idx] instanceof Boolean) { throw new IllegalArgumentException(); } - ArrayList tRecipeList = new ArrayList(Arrays.asList(aRecipe)); + ArrayList tRecipeList = new ArrayList<>(Arrays.asList(aRecipe)); while (aRecipe[idx] instanceof String) { - String s = (String) aRecipe[idx++]; - shape += s; - while (s.length() < 3) s += " "; + StringBuilder s = new StringBuilder((String) aRecipe[idx++]); + shape.append(s); + while (s.length() < 3) s.append(" "); if (s.length() > 3) throw new IllegalArgumentException(); - for (char c : s.toCharArray()) { + for (char c : s.toString().toCharArray()) { switch (c) { case 'b': tRecipeList.add(c); @@ -1042,8 +1065,8 @@ public class GT_ModHandler { if (aRecipe[idx] instanceof Boolean) { idx++; } - /*ConcurrentHash*/Map tItemStackMap = new /*ConcurrentHash*/HashMap(); - /*ConcurrentHash*/Map tItemDataMap = new /*ConcurrentHash*/HashMap(); + Map tItemStackMap = new HashMap<>(); + Map tItemDataMap = new HashMap<>(); tItemStackMap.put(' ', null); boolean tRemoveRecipe = true; @@ -1063,16 +1086,22 @@ public class GT_ModHandler { tItemDataMap.put(chr, GT_OreDictUnificator.getItemData((ItemStack) in)); } else if (in instanceof ItemData) { String tString = in.toString(); - if (tString.equals("plankWood")) { - tItemDataMap.put(chr, new ItemData(Materials.Wood, M)); - } else if (tString.equals("stoneNetherrack")) { - tItemDataMap.put(chr, new ItemData(Materials.Netherrack, M)); - } else if (tString.equals("stoneObsidian")) { - tItemDataMap.put(chr, new ItemData(Materials.Obsidian, M)); - } else if (tString.equals("stoneEndstone")) { - tItemDataMap.put(chr, new ItemData(Materials.Endstone, M)); - } else { - tItemDataMap.put(chr, (ItemData) in); + switch (tString) { + case "plankWood": + tItemDataMap.put(chr, new ItemData(Materials.Wood, M)); + break; + case "stoneNetherrack": + tItemDataMap.put(chr, new ItemData(Materials.Netherrack, M)); + break; + case "stoneObsidian": + tItemDataMap.put(chr, new ItemData(Materials.Obsidian, M)); + break; + case "stoneEndstone": + tItemDataMap.put(chr, new ItemData(Materials.Endstone, M)); + break; + default: + tItemDataMap.put(chr, (ItemData) in); + break; } ItemStack tStack = GT_OreDictUnificator.getFirstOre(in, 1); if (tStack == null) tRemoveRecipe = false; @@ -1102,7 +1131,7 @@ public class GT_ModHandler { if (aReversible && aResult != null) { ItemData[] tData = new ItemData[9]; int x = -1; - for (char chr : shape.toCharArray()) tData[++x] = tItemDataMap.get(chr); + for (char chr : shape.toString().toCharArray()) tData[++x] = tItemDataMap.get(chr); if (GT_Utility.arrayContainsNonNull(tData)) GT_OreDictUnificator.addItemData(aResult, new ItemData(tData)); } @@ -1110,12 +1139,15 @@ public class GT_ModHandler { if (aCheckForCollisions && tRemoveRecipe) { ItemStack[] tRecipe = new ItemStack[9]; int x = -1; - for (char chr : shape.toCharArray()) { + for (char chr : shape.toString().toCharArray()) { tRecipe[++x] = tItemStackMap.get(chr); if (tRecipe[x] != null && Items.feather.getDamage(tRecipe[x]) == W) Items.feather.setDamage(tRecipe[x], 0); } - tThereWasARecipe = removeRecipe(tRecipe) != null || tThereWasARecipe; + if (tDoWeCareIfThereWasARecipe || !aBuffered) + tThereWasARecipe = removeRecipe(tRecipe) != null || tThereWasARecipe; + else + removeRecipeDelayed(tRecipe); } } catch (Throwable e) { e.printStackTrace(GT_Log.err); @@ -1123,10 +1155,14 @@ public class GT_ModHandler { if (aResult == null || aResult.stackSize <= 0) return false; - if (aRemoveAllOthersWithSameOutput || aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT || aRemoveAllOtherShapedsWithSameOutput || aRemoveAllOtherNativeRecipes) - tThereWasARecipe = removeRecipeByOutput(aResult, !aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT, aRemoveAllOtherShapedsWithSameOutput, aRemoveAllOtherNativeRecipes) || tThereWasARecipe; - - if (aOnlyAddIfThereIsAnyRecipeOutputtingThis && !tThereWasARecipe) { + if (aRemoveAllOthersWithSameOutput || aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT || aRemoveAllOtherShapedsWithSameOutput || aRemoveAllOtherNativeRecipes) { + if(tDoWeCareIfThereWasARecipe || !aBuffered) + tThereWasARecipe = removeRecipeByOutput(aResult, !aRemoveAllOthersWithSameOutputIfTheyHaveSameNBT, aRemoveAllOtherShapedsWithSameOutput, aRemoveAllOtherNativeRecipes) || tThereWasARecipe; + else + removeRecipeByOutputDelayed(aResult); + } + + if (aOnlyAddIfThereIsAnyRecipeOutputtingThis && !tDoWeCareIfThereWasARecipe && !tThereWasARecipe) { ArrayList tList = (ArrayList) CraftingManager.getInstance().getRecipeList(); int tList_sS=tList.size(); for (int i = 0; i < tList_sS && !tThereWasARecipe; i++) { @@ -1203,14 +1239,13 @@ public class GT_ModHandler { } else if (tObject instanceof String) { tRecipe[i] = GT_OreDictUnificator.getFirstOre(tObject, 1); if (tRecipe[i] == null) break; - }/* else if (tObject instanceof Boolean) { - // - } else { - throw new IllegalArgumentException(); - }*/ + } i++; } - removeRecipe(tRecipe); + if (sBufferCraftingRecipes && aBuffered) + removeRecipeDelayed(tRecipe); + else + removeRecipe(tRecipe); } catch (Throwable e) { e.printStackTrace(GT_Log.err); } @@ -1252,14 +1287,8 @@ public class GT_ModHandler { */ public static ItemStack removeRecipe(ItemStack... aRecipe) { if (aRecipe == null) return null; - boolean temp = false; - for (byte i = 0; i < aRecipe.length; i++) { - if (aRecipe[i] != null) { - temp = true; - break; - } - } - if (!temp) return null; + if (Arrays.stream(aRecipe).noneMatch(Objects::nonNull)) return null; + ItemStack rReturn = null; InventoryCrafting aCrafting = new InventoryCrafting(new Container() { @Override @@ -1282,6 +1311,50 @@ public class GT_ModHandler { return rReturn; } + + public static void removeRecipeDelayed(ItemStack... aRecipe) { + if (!sBufferCraftingRecipes) { + removeRecipe(aRecipe); + return; + } + + if (aRecipe == null) return; + if (Arrays.stream(aRecipe).noneMatch(Objects::nonNull)) return; + + InventoryCrafting aCrafting = new InventoryCrafting(new Container() { + @Override + public boolean canInteractWith(EntityPlayer var1) { + return false; + } + }, 3, 3); + for (int i = 0; i < aRecipe.length && i < 9; i++) aCrafting.setInventorySlotContents(i, aRecipe[i]); + delayedRemovalByRecipe.add(aCrafting); + } + + public static void bulkRemoveByRecipe(List toRemove) { + ArrayList tList = (ArrayList) CraftingManager.getInstance().getRecipeList(); + + tList.removeIf(tRecipe -> { + if ((tRecipe instanceof IGT_CraftingRecipe) && !((IGT_CraftingRecipe) tRecipe).isRemovable()) return false; + return toRemove.stream().anyMatch(aCrafting -> tRecipe.matches(aCrafting, DW)); + }); + } + + public static boolean removeRecipeByOutputDelayed(ItemStack aOutput) { + if (sBufferCraftingRecipes) + return delayedRemovalByOutput.add(aOutput); + else + return removeRecipeByOutput(aOutput); + } + + public static boolean removeRecipeByOutputDelayed (ItemStack aOutput, boolean aIgnoreNBT, boolean aNotRemoveShapelessRecipes, boolean aOnlyRemoveNativeHandlers) { + if (sBufferCraftingRecipes && (aIgnoreNBT && !aNotRemoveShapelessRecipes && !aOnlyRemoveNativeHandlers)) + // Too lazy to handle deferred versions of the parameters that aren't used very often + return delayedRemovalByOutput.add(aOutput); + else + return removeRecipeByOutput(aOutput, aIgnoreNBT, aNotRemoveShapelessRecipes, aOnlyRemoveNativeHandlers); + } + public static boolean removeRecipeByOutput(ItemStack aOutput) { return removeRecipeByOutput(aOutput, true, false, false); } @@ -1308,7 +1381,10 @@ public class GT_ModHandler { if (sSpecialRecipeClasses.contains(tRecipe.getClass().getName())) continue; } ItemStack tStack = tRecipe.getRecipeOutput(); - if ((!(tRecipe instanceof IGT_CraftingRecipe) || ((IGT_CraftingRecipe) tRecipe).isRemovable()) && GT_Utility.areStacksEqual(GT_OreDictUnificator.get(tStack), aOutput, aIgnoreNBT)) { + if ( + (!(tRecipe instanceof IGT_CraftingRecipe) || ((IGT_CraftingRecipe) tRecipe).isRemovable()) + && GT_Utility.areStacksEqual(GT_OreDictUnificator.get(tStack), aOutput, aIgnoreNBT) + ) { tList.remove(i--); tList_sS=tList.size(); rReturn = true; } @@ -1316,6 +1392,20 @@ public class GT_ModHandler { return rReturn; } + public static boolean bulkRemoveRecipeByOutput(List toRemove) { + ArrayList tList = (ArrayList) CraftingManager.getInstance().getRecipeList(); + + Set setToRemove = toRemove.stream().map(GT_OreDictUnificator::get_nocopy).collect(Collectors.toSet()); + + tList.removeIf(tRecipe -> { + if ((tRecipe instanceof IGT_CraftingRecipe) && !((IGT_CraftingRecipe) tRecipe).isRemovable()) return false; + if (sSpecialRecipeClasses.contains(tRecipe.getClass().getName())) return false; + final ItemStack tStack = GT_OreDictUnificator.get_nocopy(tRecipe.getRecipeOutput()); + return setToRemove.stream().anyMatch(aOutput -> GT_Utility.areStacksEqual(tStack, aOutput, true)); + }); + return true; + } + /** * Checks all Crafting Handlers for Recipe Output * Used for the Autocrafting Table @@ -1326,8 +1416,8 @@ public class GT_ModHandler { if (aWorld == null) aWorld = DW; boolean temp = false; - for (byte i = 0; i < aRecipe.length; i++) { - if (aRecipe[i] != null) { + for (ItemStack itemStack : aRecipe) { + if (itemStack != null) { temp = true; break; } @@ -1393,15 +1483,8 @@ public class GT_ModHandler { * Used for Recipe Detection. */ public static ItemStack getRecipeOutput(boolean aUncopiedStack, ItemStack... aRecipe) { - if (aRecipe == null) return null; - boolean temp = false; - for (byte i = 0; i < aRecipe.length; i++) { - if (aRecipe[i] != null) { - temp = true; - break; - } - } - if (!temp) return null; + if (aRecipe == null || Arrays.stream(aRecipe).noneMatch(Objects::nonNull)) return null; + InventoryCrafting aCrafting = new InventoryCrafting(new Container() { @Override public boolean canInteractWith(EntityPlayer var1) { @@ -1410,15 +1493,17 @@ public class GT_ModHandler { }, 3, 3); for (int i = 0; i < 9 && i < aRecipe.length; i++) aCrafting.setInventorySlotContents(i, aRecipe[i]); ArrayList tList = (ArrayList) CraftingManager.getInstance().getRecipeList(); - for (int i = 0; i < tList.size(); i++) { - temp = false; + boolean found = false; + + for (IRecipe iRecipe : tList) { + found = false; try { - temp = tList.get(i).matches(aCrafting, DW); + found = iRecipe.matches(aCrafting, DW); } catch (Throwable e) { e.printStackTrace(GT_Log.err); } - if (temp) { - ItemStack tOutput = aUncopiedStack ? tList.get(i).getRecipeOutput() : tList.get(i).getCraftingResult(aCrafting); + if (found) { + ItemStack tOutput = aUncopiedStack ? iRecipe.getRecipeOutput() : iRecipe.getCraftingResult(aCrafting); if (tOutput == null || tOutput.stackSize <= 0) { // Seriously, who would ever do that shit? if (!GregTech_API.sPostloadFinished) @@ -1635,7 +1720,7 @@ public class GT_ModHandler { for (Entry tEntry : aRecipeList.entrySet()) { if (tEntry.getKey().matches(aInput)) { if (tEntry.getKey().getAmount() <= aInput.stackSize) { - ItemStack[] tList = tEntry.getValue().items.toArray(new ItemStack[tEntry.getValue().items.size()]); + ItemStack[] tList = tEntry.getValue().items.toArray(new ItemStack[0]); if (tList.length == 0) break; ItemStack[] rList = new ItemStack[aOutputSlots.length]; rRecipeMetaData.setTag("return", tEntry.getValue().metadata); @@ -1957,6 +2042,10 @@ public class GT_ModHandler { * Only adds the Recipe if it has an Output */ public static long ONLY_ADD_IF_RESULT_IS_NOT_NULL = B[12]; + /** + * Don't remove shapeless recipes with this output + */ + public static long DONT_REMOVE_SHAPELESS = B[13]; } /** diff --git a/src/main/java/gregtech/api/util/GT_OreDictUnificator.java b/src/main/java/gregtech/api/util/GT_OreDictUnificator.java index 188af9cfaa..f3eb77bc40 100644 --- a/src/main/java/gregtech/api/util/GT_OreDictUnificator.java +++ b/src/main/java/gregtech/api/util/GT_OreDictUnificator.java @@ -31,10 +31,10 @@ import static gregtech.api.enums.GT_Values.*; * P.S. It is intended to be named "Unificator" and not "Unifier", because that sounds more awesome. */ public class GT_OreDictUnificator { - private static final /*ConcurrentHash*/Map sName2StackMap = new /*ConcurrentHash*/HashMap(); - private static final /*ConcurrentHash*/Map sItemStack2DataMap = new /*ConcurrentHash*/HashMap(); - private static final /*ConcurrentHash*/Map> sUnificationTable = new /*ConcurrentHash*/HashMap>(); - private static final GT_HashSet sNoUnificationList = new GT_HashSet(); + private static final Map sName2StackMap = new HashMap<>(); + private static final Map sItemStack2DataMap = new HashMap<>(); + private static final Map> sUnificationTable = new HashMap<>(); + private static final GT_HashSet sNoUnificationList = new GT_HashSet<>(); public static volatile int VERSION = 509; private static int isRegisteringOre = 0, isAddingOre = 0; private static boolean mRunThroughTheList = true; @@ -156,6 +156,12 @@ public class GT_OreDictUnificator { return GT_Utility.copyAmount(aStack.stackSize, rStack); } + /** Doesn't copy the returned stack or set quantity. Be careful and do not mutate it; + * intended only to optimize comparisons */ + public static ItemStack get_nocopy(ItemStack aStack) { + return get_nocopy(true, aStack); + } + /** Doesn't copy the returned stack or set quantity. Be careful and do not mutate it; * intended only to optimize comparisons */ static ItemStack get_nocopy(boolean aUseBlackList, ItemStack aStack) { @@ -217,10 +223,8 @@ public class GT_OreDictUnificator { ItemStack tStack1 = get(false, tStack0); if (!GT_Utility.areStacksEqual(tStack0, tStack1)) { GT_ItemStack tGTStack1 = new GT_ItemStack(tStack1); - List list = sUnificationTable.get(tGTStack1); - if (list == null) - sUnificationTable.put(tGTStack1, list = new ArrayList()); - if (!list.contains(tStack0)) + List list = sUnificationTable.computeIfAbsent(tGTStack1, k -> new ArrayList<>()); + if (!list.contains(tStack0)) list.add(tStack0); } } @@ -233,7 +237,7 @@ public class GT_OreDictUnificator { aStacks = (ItemStack[]) obj; else if (obj instanceof List) aStacks = (ItemStack[]) ((List)obj).toArray(new ItemStack[0]); - List rList = new ArrayList(); + List rList = new ArrayList<>(); for (ItemStack aStack : aStacks) { rList.add(aStack); List tList = sUnificationTable.get(new GT_ItemStack(aStack)); @@ -340,8 +344,8 @@ public class GT_OreDictUnificator { ArrayList tList = getOres(tName); - for (int i = 0; i < tList.size(); i++) - if (GT_Utility.areStacksEqual(tList.get(i), aStack, true)) + for (ItemStack itemStack : tList) + if (GT_Utility.areStacksEqual(itemStack, aStack, true)) return false; isRegisteringOre++; @@ -463,7 +467,7 @@ public class GT_OreDictUnificator { */ public static ArrayList getOres(Object aOreName) { String aName = aOreName == null ? E : aOreName.toString(); - ArrayList rList = new ArrayList(); + ArrayList rList = new ArrayList<>(); if (GT_Utility.isStringValid(aName)) rList.addAll(OreDictionary.getOres(aName)); return rList; } diff --git a/src/main/java/gregtech/api/util/GT_Utility.java b/src/main/java/gregtech/api/util/GT_Utility.java index adc0f95881..8171c8798d 100644 --- a/src/main/java/gregtech/api/util/GT_Utility.java +++ b/src/main/java/gregtech/api/util/GT_Utility.java @@ -1,17 +1,28 @@ package gregtech.api.util; import cofh.api.transport.IItemDuct; +import com.google.common.collect.Maps; import com.mojang.authlib.GameProfile; import cpw.mods.fml.common.FMLCommonHandler; import gregtech.api.GregTech_API; import gregtech.api.damagesources.GT_DamageSources; import gregtech.api.enchants.Enchantment_Radioactivity; -import gregtech.api.enums.*; +import gregtech.api.enums.GT_Values; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Materials; +import gregtech.api.enums.OrePrefixes; +import gregtech.api.enums.SubTag; +import gregtech.api.enums.Textures; import gregtech.api.events.BlockScanningEvent; import gregtech.api.interfaces.IDebugableBlock; import gregtech.api.interfaces.IProjectileItem; import gregtech.api.interfaces.ITexture; -import gregtech.api.interfaces.tileentity.*; +import gregtech.api.interfaces.tileentity.IBasicEnergyContainer; +import gregtech.api.interfaces.tileentity.ICoverable; +import gregtech.api.interfaces.tileentity.IGregTechDeviceInformation; +import gregtech.api.interfaces.tileentity.IGregTechTileEntity; +import gregtech.api.interfaces.tileentity.IMachineProgress; +import gregtech.api.interfaces.tileentity.IUpgradableMachine; import gregtech.api.items.GT_EnergyArmor_Item; import gregtech.api.items.GT_Generic_Item; import gregtech.api.items.GT_MetaGenerated_Tool; @@ -28,7 +39,11 @@ import ic2.api.recipe.RecipeOutput; import net.minecraft.block.Block; import net.minecraft.enchantment.Enchantment; import net.minecraft.enchantment.EnchantmentHelper; -import net.minecraft.entity.*; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityList; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.EnumCreatureAttribute; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -64,8 +79,12 @@ import net.minecraftforge.common.util.FakePlayerFactory; import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.event.ForgeEventFactory; import net.minecraftforge.event.world.BlockEvent; -import net.minecraftforge.fluids.*; +import net.minecraftforge.fluids.Fluid; import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData; +import net.minecraftforge.fluids.FluidStack; +import net.minecraftforge.fluids.FluidTankInfo; +import net.minecraftforge.fluids.IFluidContainerItem; +import net.minecraftforge.fluids.IFluidHandler; import net.minecraftforge.oredict.OreDictionary; import java.lang.reflect.Constructor; @@ -74,11 +93,32 @@ import java.lang.reflect.Method; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.text.NumberFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; +import java.util.UUID; import static gregtech.GT_Mod.GT_FML_LOGGER; -import static gregtech.api.enums.GT_Values.*; +import static gregtech.api.enums.GT_Values.D1; +import static gregtech.api.enums.GT_Values.DW; +import static gregtech.api.enums.GT_Values.E; +import static gregtech.api.enums.GT_Values.GT; +import static gregtech.api.enums.GT_Values.L; +import static gregtech.api.enums.GT_Values.M; +import static gregtech.api.enums.GT_Values.NW; +import static gregtech.api.enums.GT_Values.V; +import static gregtech.api.enums.GT_Values.W; import static gregtech.common.GT_Proxy.GTPOLLUTION; import static gregtech.common.GT_UndergroundOil.undergroundOilReadInformation; @@ -91,12 +131,12 @@ public class GT_Utility { /** * Forge screwed the Fluid Registry up again, so I make my own, which is also much more efficient than the stupid Stuff over there. */ - private static final List sFluidContainerList = new ArrayList(); - private static final Map sFilledContainerToData = new /*Concurrent*/HashMap(); - private static final Map> sEmptyContainerToFluidToData = new /*Concurrent*/HashMap>(); + private static final List sFluidContainerList = new ArrayList<>(); + private static final Map sFilledContainerToData = new /*Concurrent*/HashMap<>(); + private static final Map> sEmptyContainerToFluidToData = new /*Concurrent*/HashMap<>(); public static volatile int VERSION = 509; public static boolean TE_CHECK = false, BC_CHECK = false, CHECK_ALL = true, RF_CHECK = false; - public static Map sPlayedSoundMap = new /*Concurrent*/HashMap(); + public static Map sPlayedSoundMap = new /*Concurrent*/HashMap<>(); private static int sBookCount = 0; public static UUID defaultUuid = null; // maybe default non-null? UUID.fromString("00000000-0000-0000-0000-000000000000"); @@ -251,8 +291,7 @@ public class GT_Utility { Field[] var3 = EntityLiving.class.getDeclaredFields(); int var4 = var3.length; - for (int var5 = 0; var5 < var4; ++var5) { - Field var6 = var3[var5]; + for (Field var6 : var3) { if (var6.getType() == HashMap.class) { tPotionHashmap = var6; tPotionHashmap.setAccessible(true); @@ -261,7 +300,7 @@ public class GT_Utility { } if (tPotionHashmap != null) - return ((HashMap) tPotionHashmap.get(aPlayer)).get(Integer.valueOf(aPotionIndex)) != null; + return ((HashMap) tPotionHashmap.get(aPlayer)).get(aPotionIndex) != null; } catch (Throwable e) { if (D1) e.printStackTrace(GT_Log.err); } @@ -280,8 +319,7 @@ public class GT_Utility { Field[] var3 = EntityLiving.class.getDeclaredFields(); int var4 = var3.length; - for (int var5 = 0; var5 < var4; ++var5) { - Field var6 = var3[var5]; + for (Field var6 : var3) { if (var6.getType() == HashMap.class) { tPotionHashmap = var6; tPotionHashmap.setAccessible(true); @@ -289,7 +327,7 @@ public class GT_Utility { } } - if (tPotionHashmap != null) ((HashMap) tPotionHashmap.get(aPlayer)).remove(Integer.valueOf(aPotionIndex)); + if (tPotionHashmap != null) ((HashMap) tPotionHashmap.get(aPlayer)).remove(aPotionIndex); } catch (Throwable e) { if (D1) e.printStackTrace(GT_Log.err); } @@ -394,16 +432,16 @@ public class GT_Utility { if (aTileEntity2 != null) { checkAvailabilities(); if (TE_CHECK && aTileEntity2 instanceof IItemDuct) { - for (int i = 0; i < aGrabSlots.length; i++) { - if (listContainsItem(aFilter, aTileEntity1.getStackInSlot(aGrabSlots[i]), true, aInvertFilter)) { - if (isAllowedToTakeFromSlot(aTileEntity1, aGrabSlots[i], (byte) aGrabFrom, aTileEntity1.getStackInSlot(aGrabSlots[i]))) { - if (Math.max(aMinMoveAtOnce, aMinTargetStackSize) <= aTileEntity1.getStackInSlot(aGrabSlots[i]).stackSize) { - ItemStack tStack = copyAmount(Math.min(aTileEntity1.getStackInSlot(aGrabSlots[i]).stackSize, Math.min(aMaxMoveAtOnce, aMaxTargetStackSize)), aTileEntity1.getStackInSlot(aGrabSlots[i])); + for (int aGrabSlot : aGrabSlots) { + if (listContainsItem(aFilter, aTileEntity1.getStackInSlot(aGrabSlot), true, aInvertFilter)) { + if (isAllowedToTakeFromSlot(aTileEntity1, aGrabSlot, (byte) aGrabFrom, a