diff --git a/src/main/java/codechicken/nei/BookmarkPanel.java b/src/main/java/codechicken/nei/BookmarkPanel.java index a93dea8c..9c8a026b 100644 --- a/src/main/java/codechicken/nei/BookmarkPanel.java +++ b/src/main/java/codechicken/nei/BookmarkPanel.java @@ -1094,10 +1094,13 @@ public class BookmarkPanel extends PanelWidget { } activeStack = items.get((items.size() - shift + stackIndex) % items.size()); - this.acceptsFollowingTooltipLineHandler.setActiveStack(activeStack); - this.grid.getBookmarkItem(Math.abs(itemIndex)).itemStack = activeStack; - this.grid.onItemsChanged(); + + final int targetItemIndex = Math.abs(itemIndex); + final BookmarkItem oldItem = this.grid.getBookmarkItem(targetItemIndex); + final BookmarkItem newItem = oldItem.copyWithPerm(activeStack); + + this.grid.replaceBookmarkItem(targetItemIndex, newItem); } return true; diff --git a/src/main/java/codechicken/nei/bookmark/BookmarkGrid.java b/src/main/java/codechicken/nei/bookmark/BookmarkGrid.java index 912d410b..ec6abfb2 100644 --- a/src/main/java/codechicken/nei/bookmark/BookmarkGrid.java +++ b/src/main/java/codechicken/nei/bookmark/BookmarkGrid.java @@ -879,6 +879,16 @@ public class BookmarkGrid extends ItemsGrid= this.bookmarkItems.size()) { + return; + } + + this.bookmarkItems.set(itemIndex, newItem); + onItemsChanged(); + } + public int getAbsoluteSlotIndex(int itemIndex) { return this.gridGenerator.itemToSlot.getOrDefault(itemIndex, -1); } diff --git a/src/main/java/codechicken/nei/bookmark/BookmarkItem.java b/src/main/java/codechicken/nei/bookmark/BookmarkItem.java index 48bc0f52..6e2ae404 100644 --- a/src/main/java/codechicken/nei/bookmark/BookmarkItem.java +++ b/src/main/java/codechicken/nei/bookmark/BookmarkItem.java @@ -228,11 +228,15 @@ public class BookmarkItem { final List items = type == BookmarkItemType.RESULT ? recipe.getResults() : recipe.getIngredients(); final Builder builder = builder(groupId, stack).type(type).recipe(recipe); + final ItemStack emptyStack = StackInfo.withAmount(stack, 0); long amount = 0; for (RecipeIngredient res : items) { - if (res.contains(stack)) { - amount += 1L * res.getAmount() * res.getChance(); + for (ItemStack perm : res.getPermutations()) { + if (NEIClientUtils.areStacksSameTypeWithNBT(emptyStack, StackInfo.withAmount(perm, 0))) { + amount += 1L * StackInfo.getAmount(perm) * res.getChance(); + break; + } } } @@ -308,6 +312,47 @@ public class BookmarkItem { return copyWithMultiplier(this.multiplier); } + public BookmarkItem copyWithPerm(ItemStack stack) { + + if (this.recipeId != null + && !NEIClientUtils.areStacksSameTypeWithNBT(StackInfo.withAmount(stack, 0), this.getItemStack(0))) { + final ItemStack oldPerm = findPermutation(this.itemStack); + final ItemStack newPerm = findPermutation(stack); + + if (oldPerm != null && newPerm != null) { + final long oldAmount = StackInfo.getAmount(oldPerm); + final long amount = oldAmount > 0 ? this.factor * this.chance * StackInfo.getAmount(newPerm) / oldAmount + : 0; + final long factor = (amount % PositionedStack.CHANCE_FULL) == 0 ? amount / PositionedStack.CHANCE_FULL + : 1; + final long chance = factor == 1 ? amount : PositionedStack.CHANCE_FULL; + + return new BookmarkItem( + this.groupId, + this.multiplier, + factor, + chance, + newPerm, + this.permutations, + this.recipeId, + this.type); + } + } + + return copy(); + } + + private ItemStack findPermutation(ItemStack stack) { + + for (ItemStack itemStack : this.permutations.values()) { + if (StackInfo.equalItemAndNBT(stack, itemStack, true)) { + return itemStack; + } + } + + return null; + } + public boolean containsItems(BookmarkItem item) { return this.permutations.keySet().stream().anyMatch(item.permutations::containsKey); } @@ -316,21 +361,47 @@ public class BookmarkItem { return getAmount(this.multiplier); } + public long getAmount(long multiplier, ItemStack perm) { + + if (this.recipeId != null && perm != null + && !NEIClientUtils.areStacksSameTypeWithNBT(StackInfo.withAmount(perm, 0), this.getItemStack(0))) { + final ItemStack oldPerm = findPermutation(this.itemStack); + final ItemStack newPerm = findPermutation(perm); + + if (oldPerm != null && newPerm != null) { + final long oldAmount = StackInfo.getAmount(oldPerm); + final long amount = oldAmount > 0 ? this.factor * this.chance * StackInfo.getAmount(newPerm) / oldAmount + : 0; + final long factor = (amount % PositionedStack.CHANCE_FULL) == 0 ? amount / PositionedStack.CHANCE_FULL + : 1; + final long chance = factor == 1 ? amount : PositionedStack.CHANCE_FULL; + + return getAmount(multiplier, factor, chance); + } + } + + return getAmount(multiplier); + } + public long getAmount(long multiplier) { - long amount = this.factor * multiplier; + return getAmount(multiplier, this.factor, this.chance); + } + + protected long getAmount(long multiplier, long factor, long chance) { + long amount = factor * multiplier; if (this.fluidCellAmount > 1) { amount = amount * this.fluidCellAmount; } - if (this.chance != PositionedStack.CHANCE_FULL) { + if (chance != PositionedStack.CHANCE_FULL) { if (this.type == BookmarkItemType.INGREDIENT) { // For ingredients, round up the expected amount to be conservative. - amount = (amount * this.chance + PositionedStack.CHANCE_FULL - 1) / PositionedStack.CHANCE_FULL; + return (amount * chance + PositionedStack.CHANCE_FULL - 1) / PositionedStack.CHANCE_FULL; } else { // For results, round down the expected amount to be conservative. - amount = (amount * this.chance) / PositionedStack.CHANCE_FULL; + return (amount * chance) / PositionedStack.CHANCE_FULL; } } diff --git a/src/main/java/codechicken/nei/recipe/Recipe.java b/src/main/java/codechicken/nei/recipe/Recipe.java index 46154700..269b7ce2 100644 --- a/src/main/java/codechicken/nei/recipe/Recipe.java +++ b/src/main/java/codechicken/nei/recipe/Recipe.java @@ -335,30 +335,19 @@ public class Recipe { public void setActiveIndex(int activeIndex) { this.activeIndex = Math.max(0, Math.min(activeIndex, this.items.length - 1)); + this.amount = StackInfo.getAmount(this.items[this.activeIndex]); } public boolean contains(ItemStack stackA) { - return getPermutations().stream() - .anyMatch(stackB -> NEIClientUtils.areStacksSameTypeWithNBT(stackB, stackA)); + final ItemStack stack = StackInfo.withAmount(stackA, 0); + return getPermutations().stream().anyMatch( + stackB -> NEIClientUtils.areStacksSameTypeWithNBT(StackInfo.withAmount(stackB, 0), stack)); } public List getPermutations() { return Arrays.asList(this.items); } - public RecipeIngredient setAmount(int amount) { - - for (int index = 0; index < this.items.length; index++) { - this.items[index] = StackInfo.withAmount(this.items[index], amount); - } - - return this; - } - - public void setChance(int chance) { - this.chance = chance; - } - public RecipeIngredient copy() { return new RecipeIngredient( this.relx, diff --git a/src/main/java/codechicken/nei/recipe/chain/RecipeChainMath.java b/src/main/java/codechicken/nei/recipe/chain/RecipeChainMath.java index 729453e7..a3015eb2 100644 --- a/src/main/java/codechicken/nei/recipe/chain/RecipeChainMath.java +++ b/src/main/java/codechicken/nei/recipe/chain/RecipeChainMath.java @@ -233,7 +233,7 @@ public class RecipeChainMath { final long amount = item.getAmount(multiplier); rootIngredients.add( BookmarkItem.builder(-1, item.getItemStack(amount)).factor(item.getStackSize(amount)) - .permutations(BookmarkItem.Builder.generatePermutations(item.itemStack)) + .permutations(BookmarkItem.Builder.generatePermutations(item.getItemStack(amount))) .recipeId(ROOT_RECIPE_ID).type(BookmarkItemType.INGREDIENT).build()); } @@ -348,14 +348,14 @@ public class RecipeChainMath { for (BookmarkItem prefItem : this.recipeResults) { if (!prefItem.emptyFactor() && this.outputRecipes.containsKey(prefItem.recipeId)) { - final long prefAmount = prefItem.getAmount(this.outputRecipes.get(prefItem.recipeId)); + final long prefMultiplier = this.outputRecipes.get(prefItem.recipeId); if (prefItem.itemStack.getItem().hasContainerItem(prefItem.itemStack)) { this.containerItemsBlacklist.add(prefItem.itemStack); } this.preferredItems.put(prefItem, prefItem); - calculateSuitableRecipe(prefItem, prefAmount, new ArrayList<>(), visitor); + calculateSuitableRecipe(prefItem, prefMultiplier, new ArrayList<>(), visitor); this.preferredItems.remove(prefItem); } } @@ -372,9 +372,11 @@ public class RecipeChainMath { return this; } - private void calculateSuitableRecipe(BookmarkItem ingrItem, long ingrAmount, List visited, + private void calculateSuitableRecipe(BookmarkItem ingrItem, long ingrMultiplier, List visited, ChainVisitor visitor) { final BookmarkItem prefItem = this.preferredItems.get(ingrItem); + long ingrAmount = ingrItem + .getAmount(ingrMultiplier, prefItem != null ? prefItem.itemStack : ingrItem.itemStack); visitor.addIngredient(prefItem != null ? prefItem : ingrItem, ingrAmount); @@ -426,7 +428,7 @@ public class RecipeChainMath { for (BookmarkItem item : this.recipeIngredients) { if (!item.emptyFactor() && recipeId.equals(item.recipeId)) { - calculateSuitableRecipe(item, item.getAmount(multiplier), visited, visitor); + calculateSuitableRecipe(item, multiplier, visited, visitor); } }