aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/gregtech/GT_Mod.java6
-rw-r--r--src/main/java/gregtech/api/GregTech_API.java2
-rw-r--r--src/main/java/gregtech/api/util/GT_OreDictUnificator.java24
-rw-r--r--src/main/java/gregtech/api/util/GT_RecipeRegistrator.java127
-rw-r--r--src/main/java/gregtech/api/util/GT_Utility.java28
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.
*/