diff --git a/src/main/java/codechicken/nei/recipe/chain/RecipeChainMath.java b/src/main/java/codechicken/nei/recipe/chain/RecipeChainMath.java index 264d21fc..729453e7 100644 --- a/src/main/java/codechicken/nei/recipe/chain/RecipeChainMath.java +++ b/src/main/java/codechicken/nei/recipe/chain/RecipeChainMath.java @@ -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 visited) { + private void calculateSuitableRecipe(BookmarkItem ingrItem, long ingrAmount, List 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 visited) { + private void prepareIngredients(RecipeId recipeId, long multiplier, List 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;