Skip to content

Commit 501917e

Browse files
committed
Throwing more code at it
- Fixed incorrect re-packager behaviour when ordering multiple recipes from a stock ticker with non-uniform ingredients
1 parent 6560a3e commit 501917e

File tree

3 files changed

+103
-26
lines changed

3 files changed

+103
-26
lines changed

src/main/java/com/simibubi/create/content/logistics/BigItemStack.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.simibubi.create.content.logistics;
22

3+
import java.util.ArrayList;
34
import java.util.Comparator;
5+
import java.util.List;
46
import java.util.Objects;
57

68
import net.minecraft.nbt.CompoundTag;
@@ -75,4 +77,11 @@ public String toString() {
7577
.getString() + " x" + count + ")";
7678
}
7779

80+
public static List<BigItemStack> duplicateWrappers(List<BigItemStack> list) {
81+
List<BigItemStack> copy = new ArrayList<>();
82+
for (BigItemStack bigItemStack : list)
83+
copy.add(new BigItemStack(bigItemStack.stack, bigItemStack.count));
84+
return copy;
85+
}
86+
7887
}

src/main/java/com/simibubi/create/content/logistics/factoryBoard/FactoryPanelScreen.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,15 @@ private void updateConfigs() {
9898
return;
9999
}
100100

101-
craftingIngredients = convertRecipeToPackageOrderContext(availableCraftingRecipe, inputConfig);
101+
craftingIngredients = convertRecipeToPackageOrderContext(availableCraftingRecipe, inputConfig, false);
102102
}
103103

104-
public static List<BigItemStack> convertRecipeToPackageOrderContext(CraftingRecipe availableCraftingRecipe, List<BigItemStack> inputs) {
104+
public static List<BigItemStack> convertRecipeToPackageOrderContext(CraftingRecipe availableCraftingRecipe, List<BigItemStack> inputs, boolean respectAmounts) {
105105
List<BigItemStack> craftingIngredients = new ArrayList<>();
106106
BigItemStack emptyIngredient = new BigItemStack(ItemStack.EMPTY, 1);
107107
NonNullList<Ingredient> ingredients = availableCraftingRecipe.getIngredients();
108-
108+
List<BigItemStack> mutableInputs = BigItemStack.duplicateWrappers(inputs);
109+
109110
int width = Math.min(3, ingredients.size());
110111
int height = Math.min(3, ingredients.size() / 3 + 1);
111112

@@ -125,9 +126,14 @@ public static List<BigItemStack> convertRecipeToPackageOrderContext(CraftingReci
125126
BigItemStack craftingIngredient = emptyIngredient;
126127

127128
if (!ingredient.isEmpty())
128-
for (BigItemStack bigItemStack : inputs)
129-
if (ingredient.test(bigItemStack.stack))
129+
for (BigItemStack bigItemStack : mutableInputs)
130+
if (bigItemStack.count > 0 && ingredient.test(bigItemStack.stack)) {
130131
craftingIngredient = new BigItemStack(bigItemStack.stack, 1);
132+
if (respectAmounts)
133+
bigItemStack.count -= 1;
134+
break;
135+
}
136+
131137
craftingIngredients.add(craftingIngredient);
132138

133139
if (width < 3 && (i + 1) % width == 0)

src/main/java/com/simibubi/create/content/logistics/stockTicker/StockKeeperRequestScreen.java

Lines changed: 83 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,10 +1368,45 @@ private void sendIt() {
13681368
for (CraftableBigItemStack cbis : recipesToOrder) {
13691369
if (!(cbis.recipe instanceof CraftingRecipe cr))
13701370
continue;
1371-
PackageOrder pattern =
1372-
new PackageOrder(FactoryPanelScreen.convertRecipeToPackageOrderContext(cr, itemsToOrder));
1373-
int count = cbis.count / cbis.getOutputCount(blockEntity.getLevel());
1374-
craftList.add(new CraftingEntry(pattern, count));
1371+
int craftedCount = 0;
1372+
int targetCount = cbis.count / cbis.getOutputCount(blockEntity.getLevel());
1373+
List<BigItemStack> mutableOrder = BigItemStack.duplicateWrappers(itemsToOrder);
1374+
1375+
while (craftedCount < targetCount) {
1376+
// Carefully split the ordered recipes based on what exactly will be used to craft them
1377+
PackageOrder pattern = new PackageOrder(FactoryPanelScreen.convertRecipeToPackageOrderContext(cr, mutableOrder, true));
1378+
int maxCrafts = targetCount - craftedCount;
1379+
int availableCrafts = 0;
1380+
1381+
boolean itemsExhausted = false;
1382+
Outer: while (availableCrafts < maxCrafts && !itemsExhausted) {
1383+
List<BigItemStack> previousSnapshot = BigItemStack.duplicateWrappers(mutableOrder);
1384+
itemsExhausted = true;
1385+
Pattern: for (BigItemStack patternStack : pattern.stacks()) {
1386+
if (patternStack.stack.isEmpty())
1387+
continue;
1388+
for (BigItemStack ordered : mutableOrder) {
1389+
if (!ItemHandlerHelper.canItemStacksStack(ordered.stack, patternStack.stack))
1390+
continue;
1391+
if (ordered.count == 0)
1392+
continue;
1393+
ordered.count -= 1;
1394+
itemsExhausted = false;
1395+
continue Pattern;
1396+
}
1397+
mutableOrder = previousSnapshot;
1398+
break Outer;
1399+
}
1400+
availableCrafts++;
1401+
}
1402+
1403+
if (availableCrafts == 0)
1404+
break;
1405+
1406+
craftList.add(new CraftingEntry(pattern, availableCrafts));
1407+
craftedCount += availableCrafts;
1408+
}
1409+
13751410
}
13761411
order = new PackageOrderWithCrafts(order.orderedStacks(), craftList);
13771412
}
@@ -1517,7 +1552,7 @@ private Pair<Integer, List<List<BigItemStack>>> maxCraftable(CraftableBigItemSta
15171552
Function<ItemStack, Integer> countModifier, int newTypeLimit) {
15181553
List<Ingredient> ingredients = cbis.getIngredients();
15191554
List<List<BigItemStack>> validEntriesByIngredient = new ArrayList<>();
1520-
List<ItemStack> visited = new ArrayList<>();
1555+
List<BigItemStack> alreadyCreated = new ArrayList<>();
15211556

15221557
for (Ingredient ingredient : ingredients) {
15231558
if (ingredient.isEmpty())
@@ -1528,17 +1563,18 @@ private Pair<Integer, List<List<BigItemStack>>> maxCraftable(CraftableBigItemSta
15281563
Entries:for (BigItemStack entry : list) {
15291564
if (!ingredient.test(entry.stack))
15301565
continue;
1566+
for (BigItemStack visitedStack : alreadyCreated) {
1567+
if (!ItemHandlerHelper.canItemStacksStack(visitedStack.stack, entry.stack))
1568+
continue;
1569+
valid.add(visitedStack);
1570+
continue Entries;
1571+
}
15311572
BigItemStack asBis = new BigItemStack(entry.stack,
15321573
summary.getCountOf(entry.stack) + countModifier.apply(entry.stack));
1533-
if (asBis.count > 0)
1574+
if (asBis.count > 0) {
15341575
valid.add(asBis);
1535-
for (ItemStack visitedStack : visited) {
1536-
if (!ItemHandlerHelper.canItemStacksStack(visitedStack, entry.stack))
1537-
continue;
1538-
visitedStack.grow(1);
1539-
continue Entries;
1576+
alreadyCreated.add(asBis);
15401577
}
1541-
visited.add(entry.stack.copyWithCount(1));
15421578
}
15431579

15441580
if (valid.isEmpty())
@@ -1562,15 +1598,7 @@ private Pair<Integer, List<List<BigItemStack>>> maxCraftable(CraftableBigItemSta
15621598
}
15631599

15641600
// Ingredients with shared items must divide counts
1565-
for (ItemStack visitedItem : visited) {
1566-
for (List<BigItemStack> list : validEntriesByIngredient) {
1567-
for (BigItemStack entry : list) {
1568-
if (!ItemHandlerHelper.canItemStacksStack(entry.stack, visitedItem))
1569-
continue;
1570-
entry.count = entry.count / visitedItem.getCount();
1571-
}
1572-
}
1573-
}
1601+
validEntriesByIngredient = resolveIngredientAmounts(validEntriesByIngredient);
15741602

15751603
// Determine the bottlenecking ingredient
15761604
int minCount = Integer.MAX_VALUE;
@@ -1616,6 +1644,40 @@ private void removeLeastEssentialItemStack(List<List<BigItemStack>> validIngredi
16161644
for (List<BigItemStack> list : validIngredients)
16171645
list.remove(chosen);
16181646
}
1647+
1648+
private List<List<BigItemStack>> resolveIngredientAmounts(List<List<BigItemStack>> validIngredients) {
1649+
List<List<BigItemStack>> resolvedIngredients = new ArrayList<>();
1650+
for (int i = 0; i < validIngredients.size(); i++)
1651+
resolvedIngredients.add(new ArrayList<>());
1652+
1653+
boolean everythingTaken = false;
1654+
while (!everythingTaken) {
1655+
everythingTaken = true;
1656+
Ingredients: for (int i = 0; i < validIngredients.size(); i++) {
1657+
List<BigItemStack> list = validIngredients.get(i);
1658+
List<BigItemStack> resolvedList = resolvedIngredients.get(i);
1659+
for (BigItemStack bigItemStack : list) {
1660+
if (bigItemStack.count == 0)
1661+
continue;
1662+
1663+
bigItemStack.count -= 1;
1664+
everythingTaken = false;
1665+
1666+
for (BigItemStack resolvedItemStack : resolvedList) {
1667+
if (resolvedItemStack.stack == bigItemStack.stack) {
1668+
resolvedItemStack.count++;
1669+
continue Ingredients;
1670+
}
1671+
}
1672+
1673+
resolvedList.add(new BigItemStack(bigItemStack.stack, 1));
1674+
continue Ingredients;
1675+
}
1676+
}
1677+
}
1678+
1679+
return resolvedIngredients;
1680+
}
16191681

16201682
private void syncJEI() {
16211683
if (Mods.JEI.isLoaded() && AllConfigs.client().syncJeiSearch.get())

0 commit comments

Comments
 (0)