Added Bookmark Chain Visitor (#991)

This commit is contained in:
slprime authored and GitHub committed 2026-08-01 20:35:19 +03:00
1 parent f47a8766a9
commit 5fb5ab6698
1 file changed
+52 -10
@@ -25,6 +25,34 @@ import codechicken.nei.recipe.StackInfo;
public class RecipeChainMath {
public interface ChainVisitor {
void enterRecipe(RecipeId recipeId, long multiplier);
void addIngredient(BookmarkItem ingrItem, long requestedAmount);
void addIngredientFresh(BookmarkItem ingrItem, long freshAmount);
void leaveRecipe();
}
private static class EmptyChainVisitor implements ChainVisitor {
@Override
public void enterRecipe(RecipeId recipeId, long multiplier) {}
@Override
public void addIngredient(BookmarkItem ingrItem, long requestedAmount) {}
@Override
public void addIngredientFresh(BookmarkItem ingrItem, long freshAmount) {}
@Override
public void leaveRecipe() {}
}
private static class ContainerItemResult {
public ItemStack stack;
@@ -38,6 +66,8 @@ public class RecipeChainMath {
}
}
private static final ChainVisitor EMPTY_CHAIN_VISITOR = new EmptyChainVisitor();
private static final ItemStack ROOT_ITEM = new ItemStack(Blocks.fire);
private static final RecipeId ROOT_RECIPE_ID = RecipeId
.of(ROOT_ITEM, "recipe-autocrafting", Collections.emptyList());
@@ -298,6 +328,10 @@ public class RecipeChainMath {
}
public RecipeChainMath refresh() {
return refresh(EMPTY_CHAIN_VISITOR);
}
public RecipeChainMath refresh(ChainVisitor visitor) {
final boolean isPausedItemDamageSound = StackInfo.isPausedItemDamageSound();
StackInfo.pauseItemDamageSound(true);
@@ -321,7 +355,7 @@ public class RecipeChainMath {
}
this.preferredItems.put(prefItem, prefItem);
calculateSuitableRecipe(prefItem, prefAmount, new ArrayList<>());
calculateSuitableRecipe(prefItem, prefAmount, new ArrayList<>(), visitor);
this.preferredItems.remove(prefItem);
}
}
@@ -338,9 +372,12 @@ public class RecipeChainMath {
return this;
}
private void calculateSuitableRecipe(BookmarkItem ingrItem, long ingrAmount, List<RecipeId> visited) {
private void calculateSuitableRecipe(BookmarkItem ingrItem, long ingrAmount, List<RecipeId> visited,
ChainVisitor visitor) {
final BookmarkItem prefItem = this.preferredItems.get(ingrItem);
visitor.addIngredient(prefItem != null ? prefItem : ingrItem, ingrAmount);
// calculate existing containers
if (ingrAmount > 0) {
for (ItemStack stack : ingrItem.permutations.values()) {
@@ -358,7 +395,7 @@ public class RecipeChainMath {
if (ingrAmount > 0) {
for (BookmarkItem item : this.initialItems) {
if (item.containsItems(ingrItem)
&& (ingrAmount = addRequiredAmount(item, ingrAmount, item.getAmount())) == 0) {
&& (ingrAmount = addRequiredAmount(item, ingrAmount, item.getAmount(), visitor)) == 0) {
break;
}
}
@@ -366,33 +403,37 @@ public class RecipeChainMath {
// shift amount
if (prefItem == null) {
addRequiredAmount(ingrItem, ingrAmount, Long.MAX_VALUE);
addRequiredAmount(ingrItem, ingrAmount, Long.MAX_VALUE, visitor);
} else if (visited.contains(prefItem.recipeId)) {
addRequiredAmount(prefItem, ingrAmount, Long.MAX_VALUE);
addRequiredAmount(prefItem, ingrAmount, Long.MAX_VALUE, visitor);
} else {
addRequiredAmount(prefItem, ingrAmount, Long.MAX_VALUE);
addRequiredAmount(prefItem, ingrAmount, Long.MAX_VALUE, visitor);
final long multiplier = Math
.max(0, prefItem.getMultiplierFromAmount(this.requiredAmount.get(prefItem)) - prefItem.multiplier);
if (multiplier > 0) {
addShift(prefItem.recipeId, multiplier);
visited.add(prefItem.recipeId);
prepareIngredients(prefItem.recipeId, multiplier, visited);
prepareIngredients(prefItem.recipeId, multiplier, visited, visitor);
visited.remove(prefItem.recipeId);
}
}
}
private void prepareIngredients(RecipeId recipeId, long multiplier, List<RecipeId> visited) {
private void prepareIngredients(RecipeId recipeId, long multiplier, List<RecipeId> visited, ChainVisitor visitor) {
visitor.enterRecipe(recipeId, multiplier);
for (BookmarkItem item : this.recipeIngredients) {
if (!item.emptyFactor() && recipeId.equals(item.recipeId)) {
calculateSuitableRecipe(item, item.getAmount(multiplier), visited);
calculateSuitableRecipe(item, item.getAmount(multiplier), visited, visitor);
}
}
visitor.leaveRecipe();
}
private long addRequiredAmount(BookmarkItem prefItem, long ingrAmount, long maxAmount) {
private long addRequiredAmount(BookmarkItem prefItem, long ingrAmount, long maxAmount, ChainVisitor visitor) {
long shiftAmount = this.requiredAmount.getOrDefault(prefItem, 0L);
if (hasContainerItem(prefItem.itemStack)) {
@@ -449,6 +490,7 @@ public class RecipeChainMath {
ingrAmount -= initAmount;
}
visitor.addIngredientFresh(prefItem, shiftAmount - this.requiredAmount.getOrDefault(prefItem, 0L));
this.requiredAmount.put(prefItem, shiftAmount);
return ingrAmount;