Skip to content

Commit 9883ff9

Browse files
Yet another Crafting station fix PR (GregTechCEu#1255)
* cache the tested itemstacks * cull some recipe matches() call. really helps with shapeless recipes * formatting * special handling for our transfer energy recipes
1 parent dba3a5d commit 9883ff9

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

src/main/java/gregtech/common/metatileentities/storage/CachedRecipeData.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
import gregtech.api.recipes.KeySharedStack;
44
import gregtech.api.util.ItemStackKey;
5+
import gregtech.api.util.ShapedOreEnergyTransferRecipe;
56
import gregtech.common.inventory.IItemList;
67
import gregtech.common.inventory.itemsource.ItemSources;
8+
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
9+
import it.unimi.dsi.fastutil.objects.Object2BooleanOpenHashMap;
710
import net.minecraft.inventory.InventoryCrafting;
811
import net.minecraft.item.ItemStack;
912
import net.minecraft.item.crafting.IRecipe;
13+
import net.minecraft.item.crafting.Ingredient;
1014
import net.minecraft.world.World;
1115

1216
import java.util.HashMap;
@@ -17,6 +21,7 @@ public class CachedRecipeData {
1721
private final ItemSources itemSources;
1822
private IRecipe recipe;
1923
private final Map<ItemStackKey, Integer> requiredItems = new HashMap<>();
24+
private final Map<Integer, Map<ItemStackKey, Boolean>> replaceAttemptMap = new Int2ObjectArrayMap<>();
2025
private final InventoryCrafting inventory;
2126

2227
public CachedRecipeData(ItemSources sourceList, IRecipe recipe, InventoryCrafting inventoryCrafting) {
@@ -74,17 +79,48 @@ public boolean getIngredientEquivalent(int slot) {
7479
return true;
7580
}
7681

82+
ItemStack previousStack = recipe.getCraftingResult(inventory);
83+
84+
Map<ItemStackKey, Boolean> map = replaceAttemptMap.computeIfAbsent(slot, (m) -> new Object2BooleanOpenHashMap<>());
85+
7786
//iterate stored items to find equivalent
7887
for (ItemStackKey itemStackKey : itemSources.getStoredItems()) {
88+
if (map.containsKey(itemStackKey)) {
89+
if (!map.get(itemStackKey)) {
90+
continue;
91+
} else {
92+
return true;
93+
}
94+
}
95+
7996
ItemStack itemStack = itemStackKey.getItemStack();
97+
98+
boolean matched = false;
99+
//Matching shapeless recipes actually is very bad for performance, as it checks the entire
100+
//recipe ingredients recursively, so we fail early here if none of the recipes ingredients can
101+
//take the stack
102+
for (Ingredient in : recipe.getIngredients()) {
103+
if (in.apply(itemStack)) {
104+
matched = true;
105+
break;
106+
}
107+
}
108+
if (!matched) {
109+
map.put(itemStackKey, false);
110+
continue;
111+
}
112+
80113
//update item in slot, and check that recipe matches and output item is equal to the expected one
81114
inventory.setInventorySlotContents(slot, itemStack);
82-
if (recipe.matches(inventory, itemSources.getWorld())) {
115+
if (recipe.matches(inventory, itemSources.getWorld()) &&
116+
(ItemStack.areItemStacksEqual(recipe.getCraftingResult(inventory), previousStack) || recipe instanceof ShapedOreEnergyTransferRecipe)) {
117+
map.put(itemStackKey, true);
83118
//ingredient matched, attempt to extract it and return if successful
84119
if (simulateExtractItem(itemStackKey)) {
85120
return true;
86121
}
87122
}
123+
map.put(itemStackKey, false);
88124
inventory.setInventorySlotContents(slot, currentStack);
89125
}
90126
//nothing matched, so return null
@@ -110,6 +146,7 @@ public boolean matches(InventoryCrafting inventoryCrafting, World world) {
110146

111147
public void setRecipe(IRecipe newRecipe) {
112148
this.recipe = newRecipe;
149+
this.replaceAttemptMap.clear();
113150
}
114151

115152
public IRecipe getRecipe() {

0 commit comments

Comments
 (0)