diff --git a/src/main/java/codechicken/nei/api/IStackStringifyHandler.java b/src/main/java/codechicken/nei/api/IStackStringifyHandler.java index 6984489b..0ee443cb 100644 --- a/src/main/java/codechicken/nei/api/IStackStringifyHandler.java +++ b/src/main/java/codechicken/nei/api/IStackStringifyHandler.java @@ -1,7 +1,5 @@ package codechicken.nei.api; -import java.util.Optional; - import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraftforge.fluids.FluidStack; @@ -20,10 +18,6 @@ public interface IStackStringifyHandler { return null; } - default Optional getContainerItem(ItemStack stack) { - return null; - } - - default void playItemDamageSound(boolean enabled) {} + default void pauseItemDamageSound(boolean pause) {} } diff --git a/src/main/java/codechicken/nei/api/ShortcutInputHandler.java b/src/main/java/codechicken/nei/api/ShortcutInputHandler.java index 9b0b9975..23dea821 100644 --- a/src/main/java/codechicken/nei/api/ShortcutInputHandler.java +++ b/src/main/java/codechicken/nei/api/ShortcutInputHandler.java @@ -9,7 +9,6 @@ import java.util.Map; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.item.ItemStack; import net.minecraftforge.oredict.OreDictionary; @@ -470,15 +469,15 @@ public abstract class ShortcutInputHandler { private static void autocraftingIgnoreInventory(RecipeChainMath math) { final GuiContainer guiContainer = NEIClientUtils.getGuiContainer(); - final InventoryPlayer playerInventory = guiContainer.mc.thePlayer.inventory; + final List playerInventory = AutoCraftingManager.getInventoryItems(guiContainer).values(); final RecipeId rootRecipeId = math.createMasterRoot(); for (BookmarkItem item : math.recipeIngredients) { if (item.amount > 0 && rootRecipeId.equals(item.recipeId)) { long amount = 0; - for (ItemStack stack : playerInventory.mainInventory) { - if (stack != null && NEIClientUtils.areStacksSameTypeCraftingWithNBT(stack, item.itemStack)) { + for (ItemStack stack : playerInventory) { + if (NEIClientUtils.areStacksSameTypeCraftingWithNBT(stack, item.itemStack)) { amount += StackInfo.getAmount(stack); } } diff --git a/src/main/java/codechicken/nei/recipe/AutoCraftingManager.java b/src/main/java/codechicken/nei/recipe/AutoCraftingManager.java index f365be62..7c38dd5d 100644 --- a/src/main/java/codechicken/nei/recipe/AutoCraftingManager.java +++ b/src/main/java/codechicken/nei/recipe/AutoCraftingManager.java @@ -1,12 +1,12 @@ package codechicken.nei.recipe; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Map; import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.inventory.Slot; +import net.minecraft.inventory.SlotCrafting; import codechicken.nei.ItemPanels; import codechicken.nei.ItemStackAmount; @@ -26,19 +26,17 @@ public class AutoCraftingManager { @Override public void execute() { final GuiContainer guiContainer = NEIClientUtils.getGuiContainer(); - final InventoryPlayer playerInventory = guiContainer.mc.thePlayer.inventory; - final ItemStackAmount inventory = ItemStackAmount.of(Arrays.asList(playerInventory.mainInventory)); - final List initialItems = prepareInitialItems(math, inventory); + final List initialItems = prepareInitialItems(math, getInventoryItems(guiContainer)); boolean processed = false; boolean changed = false; - StackInfo.playItemDamageSound(false); + StackInfo.pauseItemDamageSound(true); do { changed = false; RecipeChainIterator iterator = new RecipeChainIterator(math, initialItems); - iterator.updateInventory(playerInventory.mainInventory); + iterator.updateInventory(getInventoryItems(guiContainer)); while (iterator.hasNext() && !interrupted(guiContainer)) { final Map recipes = iterator.next(); @@ -64,13 +62,13 @@ public class AutoCraftingManager { if (craft) { changed = true; processed = true; - iterator.updateInventory(playerInventory.mainInventory); + iterator.updateInventory(getInventoryItems(guiContainer)); } } } while (changed && !interrupted(guiContainer)); - StackInfo.playItemDamageSound(true); + StackInfo.pauseItemDamageSound(false); if (processed && !changed && !interrupted(guiContainer)) { NEIClientUtils.playClickSound(); @@ -121,4 +119,16 @@ public class AutoCraftingManager { return AutoCraftingManager.math != null && !task.interrupted(); } + public static ItemStackAmount getInventoryItems(GuiContainer guiContainer) { + final ItemStackAmount inventory = new ItemStackAmount(); + + for (Slot slot : guiContainer.inventorySlots.inventorySlots) { + if (slot.getHasStack() && !(slot instanceof SlotCrafting) && slot.canTakeStack(guiContainer.mc.thePlayer)) { + inventory.add(slot.getStack()); + } + } + + return inventory; + } + } diff --git a/src/main/java/codechicken/nei/recipe/DefaultOverlayHandler.java b/src/main/java/codechicken/nei/recipe/DefaultOverlayHandler.java index dd08c4ca..10753dc5 100644 --- a/src/main/java/codechicken/nei/recipe/DefaultOverlayHandler.java +++ b/src/main/java/codechicken/nei/recipe/DefaultOverlayHandler.java @@ -6,7 +6,6 @@ import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.Optional; import net.minecraft.client.entity.EntityClientPlayerMP; import net.minecraft.client.gui.inventory.GuiContainer; @@ -15,6 +14,7 @@ import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.Slot; import net.minecraft.inventory.SlotCrafting; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import codechicken.lib.inventory.InventoryUtils; import codechicken.nei.FastTransferManager; @@ -339,9 +339,20 @@ public class DefaultOverlayHandler implements IOverlayHandler { if (!istack.isContainerItem && pstack.getMaxStackSize() == 1 && pstack.getItem().hasContainerItem(pstack)) { - final Optional containerItem = StackInfo.getContainerItem(pstack); - if (containerItem != null && containerItem.isPresent()) { - istack.isContainerItem = pstack.getItem() == containerItem.get().getItem(); + final NBTTagCompound tagCompound = pstack.getTagCompound(); + + if (tagCompound != null && tagCompound.hasKey("GT.ToolStats")) { + istack.isContainerItem = true; + } else { + final boolean isPausedItemDamageSound = StackInfo.isPausedItemDamageSound(); + StackInfo.pauseItemDamageSound(true); + + final ItemStack containerItem = pstack.getItem().getContainerItem(pstack); + if (containerItem != null) { + istack.isContainerItem = pstack.getItem() == containerItem.getItem(); + } + + StackInfo.pauseItemDamageSound(isPausedItemDamageSound); } } } diff --git a/src/main/java/codechicken/nei/recipe/StackInfo.java b/src/main/java/codechicken/nei/recipe/StackInfo.java index a4934d7e..e2eaa095 100644 --- a/src/main/java/codechicken/nei/recipe/StackInfo.java +++ b/src/main/java/codechicken/nei/recipe/StackInfo.java @@ -4,7 +4,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Optional; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTBase; @@ -31,6 +30,7 @@ public class StackInfo { private static final Map> guidfilters = new HashMap<>(); private static final ItemStackMap guidcache = new ItemStackMap<>(); private static final LRUCache fluidcache = new LRUCache<>(200); + private static boolean isPausedItemDamageSound = false; static { stackStringifyHandlers.add(new DefaultStackStringifyHandler()); @@ -74,20 +74,16 @@ public class StackInfo { return stack; } - public static Optional getContainerItem(ItemStack stack) { - Optional result = null; - - for (int i = stackStringifyHandlers.size() - 1; i >= 0 && result == null; i--) { - result = stackStringifyHandlers.get(i).getContainerItem(stack); + public static void pauseItemDamageSound(boolean pause) { + if (isPausedItemDamageSound != (isPausedItemDamageSound = pause)) { + for (IStackStringifyHandler handler : stackStringifyHandlers) { + handler.pauseItemDamageSound(pause); + } } - - return result; } - public static void playItemDamageSound(boolean enabled) { - for (IStackStringifyHandler handler : stackStringifyHandlers) { - handler.playItemDamageSound(enabled); - } + public static boolean isPausedItemDamageSound() { + return isPausedItemDamageSound; } public static ItemStack withAmount(ItemStack stack, long customCount) { diff --git a/src/main/java/codechicken/nei/recipe/chain/RecipeChainMath.java b/src/main/java/codechicken/nei/recipe/chain/RecipeChainMath.java index 42be6fb7..3de62b73 100644 --- a/src/main/java/codechicken/nei/recipe/chain/RecipeChainMath.java +++ b/src/main/java/codechicken/nei/recipe/chain/RecipeChainMath.java @@ -6,11 +6,12 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import net.minecraft.init.Blocks; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import codechicken.nei.ItemStackAmount; import codechicken.nei.NEIClientUtils; @@ -22,6 +23,19 @@ import codechicken.nei.recipe.StackInfo; public class RecipeChainMath { + private static class ContainerItemResult { + + public ItemStack stack; + public ItemStack containerItem; + public long leftSteps; + + public ContainerItemResult(ItemStack stack, long leftSteps, ItemStack containerItem) { + this.stack = stack; + this.leftSteps = leftSteps; + this.containerItem = containerItem; + } + } + 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()); @@ -280,6 +294,9 @@ public class RecipeChainMath { } public RecipeChainMath refresh() { + final boolean isPausedItemDamageSound = StackInfo.isPausedItemDamageSound(); + StackInfo.pauseItemDamageSound(true); + resetCalculation(); if (this.outputRecipes.containsKey(ROOT_RECIPE_ID)) { @@ -313,6 +330,7 @@ public class RecipeChainMath { } } + StackInfo.pauseItemDamageSound(isPausedItemDamageSound); return this; } @@ -405,22 +423,13 @@ public class RecipeChainMath { ItemStack bStack = this.containerItems.get(i); if (bStack != null && NEIClientUtils.areStacksSameTypeCraftingWithNBT(aStack, bStack)) { + final ContainerItemResult result = getToolsContainerItems(bStack, steps); - while (bStack != null && steps > 0) { - final Optional containerItem = StackInfo.getContainerItem(bStack); + bStack = result.stack; + steps = result.leftSteps; - steps--; - - if (containerItem != null && containerItem.isPresent()) { - bStack = containerItem.get(); - - if (aStack.getItem() != bStack.getItem()) { - this.containerItems.add(bStack); - bStack = null; - } - } else { - bStack = null; - } + if (result.containerItem != null) { + this.containerItems.add(result.containerItem); } this.containerItems.set(i, bStack); @@ -433,6 +442,60 @@ public class RecipeChainMath { return steps; } + private ContainerItemResult getToolsContainerItems(ItemStack aStack, long steps) { + final NBTTagCompound tagCompound = aStack.getTagCompound(); + + if (tagCompound != null && tagCompound.hasKey("GT.ToolStats")) { + final int damagePerContainerCraft = getGTToolDamagePerContainerCraft(aStack); + + if (damagePerContainerCraft > 0) { + final NBTTagCompound toolStats = tagCompound.getCompoundTag("GT.ToolStats"); + final long maxDamage = toolStats.getLong("MaxDamage"); + final long damage = toolStats.getLong("Damage"); + final long leftSteps = (maxDamage - damage) / damagePerContainerCraft; + final long availableSteps = Math.min(steps, Math.max(1, leftSteps)); + + steps -= availableSteps; + + if ((damage + availableSteps * damagePerContainerCraft) == maxDamage || leftSteps <= 0) { + aStack = null; + } else { + toolStats.setLong("Damage", damage + availableSteps * damagePerContainerCraft); + } + + return new ContainerItemResult(aStack, steps, null); + } + + } + + final Item item = aStack.getItem(); + + while (aStack != null && steps > 0) { + aStack = item.getContainerItem(aStack); + + steps--; + + if (aStack != null && item != aStack.getItem()) { + return new ContainerItemResult(null, steps, aStack); + } + } + + return new ContainerItemResult(aStack, steps, null); + } + + private int getGTToolDamagePerContainerCraft(ItemStack aStack) { + + try { + final Object toolStats = aStack.getItem().getClass().getMethod("getToolStats", ItemStack.class) + .invoke(aStack.getItem(), aStack); + return (int) toolStats.getClass().getMethod("getToolDamagePerContainerCraft").invoke(toolStats); + } catch (Throwable th) { + th.printStackTrace(); + } + + return 0; + } + private boolean hasContainerItem(ItemStack aStack) { if (aStack.getItem().hasContainerItem(aStack)) { diff --git a/src/main/java/codechicken/nei/recipe/chain/RecipeChainTooltipLineHandler.java b/src/main/java/codechicken/nei/recipe/chain/RecipeChainTooltipLineHandler.java index 8831f183..0b82f67f 100644 --- a/src/main/java/codechicken/nei/recipe/chain/RecipeChainTooltipLineHandler.java +++ b/src/main/java/codechicken/nei/recipe/chain/RecipeChainTooltipLineHandler.java @@ -7,10 +7,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import net.minecraft.client.entity.EntityClientPlayerMP; import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.inventory.Slot; -import net.minecraft.inventory.SlotCrafting; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumChatFormatting; @@ -22,6 +19,8 @@ import codechicken.nei.ItemsTooltipLineHandler; import codechicken.nei.NEIClientConfig; import codechicken.nei.NEIClientUtils; import codechicken.nei.bookmark.BookmarkItem; +import codechicken.nei.recipe.AutoCraftingManager; +import codechicken.nei.recipe.GuiRecipe; import codechicken.nei.recipe.Recipe.RecipeId; import codechicken.nei.recipe.StackInfo; @@ -57,14 +56,9 @@ public class RecipeChainTooltipLineHandler implements ITooltipLineHandler { final List remainder = new ArrayList<>(); final ItemStackAmount inventory = new ItemStackAmount(); final GuiContainer currentGui = NEIClientUtils.getGuiContainer(); - final EntityClientPlayerMP thePlayer = currentGui.mc.thePlayer; - if (this.lastShiftKey) { - for (Slot slot : currentGui.inventorySlots.inventorySlots) { - if (slot.getHasStack() && !(slot instanceof SlotCrafting) && slot.canTakeStack(thePlayer)) { - inventory.add(slot.getStack()); - } - } + if (this.lastShiftKey && !(currentGui instanceof GuiRecipe)) { + inventory.putAll(AutoCraftingManager.getInventoryItems(currentGui)); } if (!this.math.outputRecipes.isEmpty()) { @@ -89,7 +83,10 @@ public class RecipeChainTooltipLineHandler implements ITooltipLineHandler { if (amount >= item.amount) { final long itemAmount = item.factor * this.math.outputRecipes.get(item.recipeId); - amount += itemAmount - amount % itemAmount; + if (itemAmount > 0) { + amount += itemAmount - amount % itemAmount; + } + this.math.outputRecipes.put( item.recipeId, Math.max(this.math.outputRecipes.get(item.recipeId), amount / item.factor)); diff --git a/src/main/java/codechicken/nei/recipe/stackinfo/DefaultStackStringifyHandler.java b/src/main/java/codechicken/nei/recipe/stackinfo/DefaultStackStringifyHandler.java index 0383f166..6c984ce4 100644 --- a/src/main/java/codechicken/nei/recipe/stackinfo/DefaultStackStringifyHandler.java +++ b/src/main/java/codechicken/nei/recipe/stackinfo/DefaultStackStringifyHandler.java @@ -1,7 +1,5 @@ package codechicken.nei.recipe.stackinfo; -import java.util.Optional; - import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -58,14 +56,4 @@ public class DefaultStackStringifyHandler implements IStackStringifyHandler { return fluidStack; } - @Override - public Optional getContainerItem(ItemStack stack) { - - if (stack.getItem().hasContainerItem(stack)) { - return Optional.ofNullable(stack.getItem().getContainerItem(stack)); - } - - return null; - } - } diff --git a/src/main/java/codechicken/nei/recipe/stackinfo/GTFluidStackStringifyHandler.java b/src/main/java/codechicken/nei/recipe/stackinfo/GTFluidStackStringifyHandler.java index 741f23f9..79661d42 100644 --- a/src/main/java/codechicken/nei/recipe/stackinfo/GTFluidStackStringifyHandler.java +++ b/src/main/java/codechicken/nei/recipe/stackinfo/GTFluidStackStringifyHandler.java @@ -2,7 +2,6 @@ package codechicken.nei.recipe.stackinfo; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.Optional; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -22,7 +21,6 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler { protected static Method getFluidFromDisplayStack = null; public static boolean replaceAE2FCFluidDrop = false; private static Class gtMetaGeneratedTool = null; - private static Method getContainerItem = null; private static Field playSound = null; static { @@ -38,13 +36,11 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler { getFluidFromDisplayStack = gtUtility.getMethod("getFluidFromDisplayStack", ItemStack.class); getFluidDisplayStack = gtUtility.getMethod("getFluidDisplayStack", FluidStack.class, boolean.class); - gtMetaGeneratedTool = ReflectionHelper.getClass(loader, "gregtech.api.items.MetaGeneratedTool"); - getContainerItem = gtMetaGeneratedTool - .getDeclaredMethod("getContainerItem", ItemStack.class, boolean.class, boolean.class); - getContainerItem.setAccessible(true); - + gtMetaGeneratedTool = ReflectionHelper.getClass( + loader, + "gregtech.api.items.MetaGeneratedTool", + "gregtech.api.items.GT_MetaGenerated_Tool"); playSound = gtMetaGeneratedTool.getDeclaredField("playSound"); - playSound.setAccessible(true); } catch (Exception ignored) { /* Do nothing */ } @@ -119,23 +115,10 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler { } @Override - public Optional getContainerItem(ItemStack stack) { - - if (getContainerItem != null && gtMetaGeneratedTool.isInstance(stack.getItem()) - && stack.getItem().hasContainerItem(stack)) { - try { - return Optional.ofNullable((ItemStack) getContainerItem.invoke(stack.getItem(), stack, false, true)); - } catch (Exception ex) {} - } - - return null; - } - - @Override - public void playItemDamageSound(boolean enabled) { + public void pauseItemDamageSound(boolean pause) { if (playSound != null) { try { - playSound.setBoolean(null, enabled); + playSound.setBoolean(null, !pause); } catch (Exception e) {} }