diff options
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/java/gregtech/GT_Mod.java | 6 | ||||
-rw-r--r-- | src/main/java/gregtech/api/GregTech_API.java | 2 | ||||
-rw-r--r-- | src/main/java/gregtech/api/util/GT_OreDictUnificator.java | 24 | ||||
-rw-r--r-- | src/main/java/gregtech/api/util/GT_RecipeRegistrator.java | 127 | ||||
-rw-r--r-- | src/main/java/gregtech/api/util/GT_Utility.java | 28 |
5 files changed, 154 insertions, 33 deletions
diff --git a/src/main/java/gregtech/GT_Mod.java b/src/main/java/gregtech/GT_Mod.java index 23ef836960..1d1f8cb0d6 100644 --- a/src/main/java/gregtech/GT_Mod.java +++ b/src/main/java/gregtech/GT_Mod.java @@ -29,6 +29,7 @@ import gregtech.api.enums.Materials; import gregtech.api.enums.OrePrefixes; import gregtech.api.enums.Textures; import gregtech.api.interfaces.internal.IGT_Mod; +import gregtech.api.objects.GT_ItemStack; import gregtech.api.objects.ItemData; import gregtech.api.objects.ReverseShapedRecipe; import gregtech.api.objects.ReverseShapelessRecipe; @@ -751,9 +752,8 @@ public class GT_Mod implements IGT_Mod { GT_Utility.reInit(); GT_Recipe.reInit(); try { - for (Map<gregtech.api.objects.GT_ItemStack, ?> gt_itemStackMap : GregTech_API.sItemStackMappings) { - //noinspection rawtypes,unchecked// Deal with legacy Minecraft raw types,rawtypes - GT_Utility.reMap((Map) gt_itemStackMap); + for (Map<? extends GT_ItemStack, ?> gt_itemStackMap : GregTech_API.sItemStackMappings) { + GT_Utility.reMap(gt_itemStackMap); } } catch (Throwable e) { e.printStackTrace(GT_Log.err); diff --git a/src/main/java/gregtech/api/GregTech_API.java b/src/main/java/gregtech/api/GregTech_API.java index 56e80d4971..b565190507 100644 --- a/src/main/java/gregtech/api/GregTech_API.java +++ b/src/main/java/gregtech/api/GregTech_API.java @@ -99,7 +99,7 @@ public class GregTech_API { /** * Fixes the HashMap Mappings for ItemStacks once the Server started */ - public static final Collection<Map<GT_ItemStack, ?>> sItemStackMappings = new ArrayList<>(); + public static final Collection<Map<? extends GT_ItemStack, ?>> sItemStackMappings = new ArrayList<>(); public static final Collection<Map<Fluid, ?>> sFluidMappings = new ArrayList<>(); /** diff --git a/src/main/java/gregtech/api/util/GT_OreDictUnificator.java b/src/main/java/gregtech/api/util/GT_OreDictUnificator.java index 81038645e9..48882bb72f 100644 --- a/src/main/java/gregtech/api/util/GT_OreDictUnificator.java +++ b/src/main/java/gregtech/api/util/GT_OreDictUnificator.java @@ -9,16 +9,18 @@ import gregtech.api.enums.Dyes; import gregtech.api.enums.Materials; import gregtech.api.enums.OrePrefixes; import gregtech.api.enums.SubTag; -import gregtech.api.objects.GT_HashSet; import gregtech.api.objects.GT_ItemStack; +import gregtech.api.objects.GT_ItemStack2; import gregtech.api.objects.ItemData; import gregtech.api.objects.MaterialStack; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import javax.annotation.Nullable; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; @@ -35,9 +37,9 @@ import net.minecraftforge.oredict.OreDictionary; */ public class GT_OreDictUnificator { private static final Map<String, ItemStack> sName2StackMap = new HashMap<>(); - private static final Map<GT_ItemStack, ItemData> sItemStack2DataMap = new HashMap<>(); - private static final Map<GT_ItemStack, List<ItemStack>> sUnificationTable = new HashMap<>(); - private static final GT_HashSet<GT_ItemStack> sNoUnificationList = new GT_HashSet<>(); + private static final Map<GT_ItemStack2, ItemData> sItemStack2DataMap = new HashMap<>(); + private static final Map<GT_ItemStack2, List<ItemStack>> sUnificationTable = new HashMap<>(); + private static final Set<GT_ItemStack2> sNoUnificationList = new HashSet<>(); public static volatile int VERSION = 509; private static int isRegisteringOre = 0, isAddingOre = 0; private static boolean mRunThroughTheList = true; @@ -53,7 +55,7 @@ public class GT_OreDictUnificator { */ public static void addToBlacklist(ItemStack aStack) { if (GT_Utility.isStackValid(aStack) && !GT_Utility.isStackInList(aStack, sNoUnificationList)) - sNoUnificationList.add(aStack); + sNoUnificationList.add(new GT_ItemStack2(aStack)); } public static boolean isBlacklisted(ItemStack aStack) { @@ -250,7 +252,7 @@ public class GT_OreDictUnificator { ItemStack tStack0 = tGTStack0.toStack(); ItemStack tStack1 = get_nocopy(false, tStack0); if (!GT_Utility.areStacksEqual(tStack0, tStack1)) { - GT_ItemStack tGTStack1 = new GT_ItemStack(tStack1); + GT_ItemStack2 tGTStack1 = new GT_ItemStack2(tStack1); List<ItemStack> list = sUnificationTable.computeIfAbsent(tGTStack1, k -> new ArrayList<>()); // greg's original code tries to dedupe the list using List#contains, which won't work // on vanilla ItemStack. I removed it since it never worked and can be slow. @@ -267,7 +269,7 @@ public class GT_OreDictUnificator { List<ItemStack> rList = new ArrayList<>(); for (ItemStack aStack : aStacks) { rList.add(aStack); - List<ItemStack> tList = sUnificationTable.get(new GT_ItemStack(aStack)); + List<ItemStack> tList = sUnificationTable.get(new GT_ItemStack2(aStack)); if (tList != null) { for (ItemStack tStack : tList) { ItemStack tStack1 = GT_Utility.copyAmount(aStack.stackSize, tStack); @@ -294,7 +296,7 @@ public class GT_OreDictUnificator { for (MaterialStack tMaterial : aData.mByProducts) tMaterial.mAmount /= aStack.stackSize; aStack = GT_Utility.copyAmount(1, aStack); } - sItemStack2DataMap.put(new GT_ItemStack(aStack), aData); + sItemStack2DataMap.put(new GT_ItemStack2(aStack), aData); if (aData.hasValidMaterialData()) { long tValidMaterialAmount = aData.mMaterial.mMaterial.contains(SubTag.NO_RECYCLING) ? 0 @@ -308,7 +310,7 @@ public class GT_OreDictUnificator { if (mRunThroughTheList) { if (GregTech_API.sLoadStarted) { mRunThroughTheList = false; - for (Entry<GT_ItemStack, ItemData> tEntry : sItemStack2DataMap.entrySet()) + for (Entry<GT_ItemStack2, ItemData> tEntry : sItemStack2DataMap.entrySet()) if (!tEntry.getValue().hasValidPrefixData() || tEntry.getValue().mPrefix.mAllowNormalRecycling) GT_RecipeRegistrator.registerMaterialRecycling( tEntry.getKey().toStack(), tEntry.getValue()); @@ -335,8 +337,8 @@ public class GT_OreDictUnificator { public static ItemData getItemData(ItemStack aStack) { if (GT_Utility.isStackInvalid(aStack)) return null; - ItemData rData = sItemStack2DataMap.get(new GT_ItemStack(aStack)); - if (rData == null) rData = sItemStack2DataMap.get(new GT_ItemStack(aStack, true)); + ItemData rData = sItemStack2DataMap.get(new GT_ItemStack2(aStack)); + if (rData == null) rData = sItemStack2DataMap.get(new GT_ItemStack2(aStack, true)); return rData; } diff --git a/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java b/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java index 1b1654d8a6..a01ee332ae 100644 --- a/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java +++ b/src/main/java/gregtech/api/util/GT_RecipeRegistrator.java @@ -4,17 +4,25 @@ import static gregtech.api.enums.GT_Values.*; import static gregtech.api.enums.Materials.*; import static gregtech.api.enums.Materials.Void; +import com.google.common.collect.ImmutableList; import gregtech.GT_Mod; import gregtech.api.GregTech_API; import gregtech.api.enums.*; import gregtech.api.objects.ItemData; import gregtech.api.objects.MaterialStack; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import ic2.api.reactor.IReactorComponent; +import java.util.*; +import java.util.stream.Collectors; import net.minecraft.init.Blocks; import net.minecraft.init.Items; +import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.ShapedRecipes; +import net.minecraft.item.crafting.ShapelessRecipes; +import net.minecraftforge.oredict.ShapedOreRecipe; +import net.minecraftforge.oredict.ShapelessOreRecipe; /** * Class for Automatic Recipe registering. @@ -73,6 +81,7 @@ public class GT_RecipeRegistrator { new RecipeShape(sMt1, sMt1, null, sMt2, null, sMt1, sMt2, null, null), new RecipeShape(null, sMt1, sMt1, sMt1, null, sMt2, null, null, sMt2) }; + private static volatile Map<RecipeShape, List<IRecipe>> indexedRecipeListCache; private static final String[][] sShapesA = new String[][] { null, null, @@ -121,6 +130,11 @@ public class GT_RecipeRegistrator { }; public static volatile int VERSION = 509; + static { + // flush the cache on post load finish + GregTech_API.sAfterGTPostload.add(() -> indexedRecipeListCache = null); + } + public static void registerMaterialRecycling( ItemStack aStack, Materials aMaterial, long aMaterialAmount, MaterialStack aByproduct) { if (GT_Utility.isStackInvalid(aStack)) return; @@ -445,6 +459,102 @@ public class GT_RecipeRegistrator { } } + private static List<IRecipe> getRecipeList(RecipeShape shape) { + boolean force = !GregTech_API.sPostloadStarted || GregTech_API.sPostloadFinished; + if (force || indexedRecipeListCache == null) { + synchronized (GT_RecipeRegistrator.class) { + if (indexedRecipeListCache == null || force) { + indexedRecipeListCache = createIndexedRecipeListCache(); + } + } + } + return indexedRecipeListCache.get(shape); + } + + private static Map<RecipeShape, List<IRecipe>> createIndexedRecipeListCache() { + Map<RecipeShape, List<IRecipe>> result = new IdentityHashMap<>(); + @SuppressWarnings("unchecked") + ArrayList<IRecipe> allRecipeList = + (ArrayList<IRecipe>) CraftingManager.getInstance().getRecipeList(); + // filter using the empty slots in the shape. + // if the empty slots doesn't match, the recipe will definitely fail + Map<List<Integer>, List<RecipeShape>> filter = + Arrays.stream(sShapes).collect(Collectors.groupingBy(RecipeShape::getEmptySlots)); + List<Integer> x = new ArrayList<>(9); + for (IRecipe tRecipe : allRecipeList) { + if (tRecipe instanceof ShapelessRecipes || tRecipe instanceof ShapelessOreRecipe) { + // we don't target shapeless recipes + continue; + } + x.clear(); + ItemStack tStack = tRecipe.getRecipeOutput(); + if (GT_Utility.isStackValid(tStack) + && tStack.getMaxStackSize() == 1 + && tStack.getMaxDamage() > 0 + && !(tStack.getItem() instanceof ItemBlock) + && !(tStack.getItem() instanceof IReactorComponent) + && !GT_ModHandler.isElectricItem(tStack) + && !GT_Utility.isStackInList(tStack, GT_ModHandler.sNonReplaceableItems)) { + if (tRecipe instanceof ShapedOreRecipe) { + boolean allValid = true; + Object[] input = ((ShapedOreRecipe) tRecipe).getInput(); + for (int i = 0, inputLength = input.length; i < inputLength; i++) { + Object tObject = input[i]; + if (tObject != null) { + if (tObject instanceof ItemStack + && (((ItemStack) tObject).getItem() == null + || ((ItemStack) tObject).getMaxStackSize() < 2 + || ((ItemStack) tObject).getMaxDamage() > 0 + || ((ItemStack) tObject).getItem() instanceof ItemBlock)) { + allValid = false; + break; + } + if (tObject instanceof List && ((List<?>) tObject).isEmpty()) { + allValid = false; + break; + } + } else { + x.add(i); + } + } + if (allValid) { + for (RecipeShape s : filter.getOrDefault(x, Collections.emptyList())) { + result.computeIfAbsent(s, k -> new ArrayList<>()).add(tRecipe); + } + } + } else if (tRecipe instanceof ShapedRecipes) { + boolean allValid = true; + ItemStack[] recipeItems = ((ShapedRecipes) tRecipe).recipeItems; + for (int i = 0, recipeItemsLength = recipeItems.length; i < recipeItemsLength; i++) { + ItemStack tObject = recipeItems[i]; + if (tObject != null + && (tObject.getItem() == null + || tObject.getMaxStackSize() < 2 + || tObject.getMaxDamage() > 0 + || tObject.getItem() instanceof ItemBlock)) { + allValid = false; + break; + } else { + x.add(i); + } + } + if (allValid) { + for (RecipeShape s : filter.getOrDefault(x, Collections.emptyList())) { + result.computeIfAbsent(s, k -> new ArrayList<>()).add(tRecipe); + } + } + } else { + for (RecipeShape s : sShapes) { + // unknown recipe type. cannot determine empty slots. we choose to add to the recipe list for + // all shapes + result.computeIfAbsent(s, k -> new ArrayList<>()).add(tRecipe); + } + } + } + } + return result; + } + private static synchronized void registerStickStuff(String aPlate, ItemData aItemData, boolean aRecipeReplacing) { ItemStack tStack; for (Materials tMaterial : sRodMaterialList) { @@ -457,7 +567,8 @@ public class GT_RecipeRegistrator { for (int i = 0; i < sShapes.length; i++) { RecipeShape tRecipe = sShapes[i]; - for (ItemStack tCrafted : GT_ModHandler.getVanillyToolRecipeOutputs(tRecipe.shape)) { + for (ItemStack tCrafted : + GT_ModHandler.getRecipeOutputs(getRecipeList(tRecipe), true, tRecipe.shape)) { if (aItemData != null && aItemData.hasValidPrefixMaterialData()) GT_OreDictUnificator.addItemData( tCrafted, @@ -547,5 +658,13 @@ public class GT_RecipeRegistrator { if (stack == sMt2) this.amount2++; } } + + public List<Integer> getEmptySlots() { + ImmutableList.Builder<Integer> b = ImmutableList.builder(); + for (int i = 0; i < shape.length; i++) { + if (shape[i] == null) b.add(i); + } + return b.build(); + } } } diff --git a/src/main/java/gregtech/api/util/GT_Utility.java b/src/main/java/gregtech/api/util/GT_Utility.java index 50106795eb..b35b703ab9 100644 --- a/src/main/java/gregtech/api/util/GT_Utility.java +++ b/src/main/java/gregtech/api/util/GT_Utility.java @@ -44,6 +44,7 @@ import gregtech.api.items.GT_MetaGenerated_Tool; import gregtech.api.net.GT_Packet_Sound; import gregtech.api.objects.CollectorUtils; import gregtech.api.objects.GT_ItemStack; +import gregtech.api.objects.GT_ItemStack2; import gregtech.api.objects.ItemData; import gregtech.api.threads.GT_Runnable_Sound; import gregtech.api.util.extensions.ArrayExt; @@ -60,21 +61,8 @@ import java.math.BigInteger; import java.math.RoundingMode; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -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.*; import java.util.Map.Entry; -import java.util.Objects; -import java.util.Optional; -import java.util.UUID; import java.util.function.Function; import java.util.function.IntFunction; import java.util.function.Supplier; @@ -2933,11 +2921,23 @@ public class GT_Utility { return isStackInList(new GT_ItemStack(aStack), aList); } + public static boolean isStackInList(ItemStack aStack, Set<GT_ItemStack2> aList) { + if (aStack == null) { + return false; + } + return isStackInList(new GT_ItemStack2(aStack), aList); + } + public static boolean isStackInList(GT_ItemStack aStack, Collection<GT_ItemStack> aList) { return aStack != null && (aList.contains(aStack) || aList.contains(new GT_ItemStack(aStack.mItem, aStack.mStackSize, W))); } + public static boolean isStackInList(GT_ItemStack2 aStack, Set<GT_ItemStack2> aList) { + return aStack != null + && (aList.contains(aStack) || aList.contains(new GT_ItemStack2(aStack.mItem, aStack.mStackSize, W))); + } + /** * re-maps all Keys of a Map after the Keys were weakened. */ |