diff --git a/src/main/java/codechicken/nei/AnimatedItemStack.java b/src/main/java/codechicken/nei/AnimatedItemStack.java new file mode 100644 index 00000000..6045ef43 --- /dev/null +++ b/src/main/java/codechicken/nei/AnimatedItemStack.java @@ -0,0 +1,76 @@ +package codechicken.nei; + +import static codechicken.nei.ItemsGrid.SLOT_SIZE; + +import codechicken.nei.guihook.GuiContainerManager; +import net.minecraft.item.ItemStack; +import org.lwjgl.opengl.GL11; + +public class AnimatedItemStack { + + private static final int steep = 10; + private static final float scaleSpeed = 0.1f; + + private int lastPosX = -1; + private int lastPosY = -1; + private float currentScale = 0; + private final boolean doMoveAnim; + private final boolean doPopAnim; + + public ItemStack itemStack; + + public AnimatedItemStack(ItemStack itemStack, boolean doMoveAnim, boolean doPopAnim) { + this.itemStack = itemStack; + this.doMoveAnim = doMoveAnim; + this.doPopAnim = doPopAnim; + } + + public void drawItem(int x, int y) { + drawItem(x, y, false, null, false); + } + + public void drawItem(int x, int y, boolean smallAmount, String stackSize, boolean blockMoveAnimOnce) { + if (NEIClientConfig.areBookmarksAnimated()) { + if (doPopAnim && currentScale < 1) { + drawPoppingItem(x, y, smallAmount, stackSize); + return; + } + if (doMoveAnim && (lastPosX != x || lastPosY != y) && !blockMoveAnimOnce) { + drawMovingItem(x, y, smallAmount, stackSize); + return; + } + } + currentScale = 1; + lastPosX = x; + lastPosY = y; + GuiContainerManager.drawItem(x, y, itemStack, smallAmount, stackSize); + } + + private void drawPoppingItem(int x, int y, boolean smallAmount, String stackSize) { + currentScale += scaleSpeed; + GL11.glScalef(currentScale, currentScale, currentScale); // push & pop matrix crashes the game + GuiContainerManager.drawItem( + (int) ((x + (SLOT_SIZE / 2 - currentScale * SLOT_SIZE / 2)) / currentScale), + (int) ((y + (SLOT_SIZE / 2 - currentScale * SLOT_SIZE / 2)) / currentScale), + itemStack, + smallAmount, + stackSize); + GL11.glScalef(1 / currentScale, 1 / currentScale, 1 / currentScale); + } + + private void drawMovingItem(int x, int y, boolean smallAmount, String stackSize) { + if (lastPosX != -1 && lastPosY != -1) { + int xDiff = x - lastPosX; + int yDiff = y - lastPosY; + int moveX = xDiff / steep + ((xDiff % steep == 0) ? 0 : (xDiff > 0 ? 1 : -1)); + int moveY = yDiff / steep + ((yDiff % steep == 0) ? 0 : (yDiff > 0 ? 1 : -1)); + GuiContainerManager.drawItem(lastPosX + moveX, lastPosY + moveY, itemStack, smallAmount, stackSize); + lastPosX = lastPosX + moveX; + lastPosY = lastPosY + moveY; + } else { + lastPosX = x; + lastPosY = y; + GuiContainerManager.drawItem(x, y, itemStack, smallAmount, stackSize); + } + } +} diff --git a/src/main/java/codechicken/nei/BookmarkPanel.java b/src/main/java/codechicken/nei/BookmarkPanel.java index a1af6d5b..945659d4 100644 --- a/src/main/java/codechicken/nei/BookmarkPanel.java +++ b/src/main/java/codechicken/nei/BookmarkPanel.java @@ -1,8 +1,7 @@ package codechicken.nei; -import static codechicken.lib.gui.GuiDraw.drawRect; -import static codechicken.lib.gui.GuiDraw.getMousePosition; -import static codechicken.nei.NEIClientUtils.translate; +import static codechicken.lib.gui.GuiDraw.*; +import static codechicken.nei.NEIClientUtils.*; import codechicken.core.CommonUtils; import codechicken.lib.vec.Rectangle4i; @@ -30,6 +29,7 @@ import java.util.Map; import javax.annotation.Nullable; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import org.apache.commons.io.IOUtils; @@ -49,6 +49,9 @@ public class BookmarkPanel extends PanelWidget { protected List namespaces = new ArrayList<>(); protected int activeNamespaceIndex = 0; + private BookmarkStackMeta draggedStackMeta; + private int draggedStackOriginIndex = -1; + protected static class BookmarkStackMeta { public int factor; public BookmarkRecipeId recipeId; @@ -207,7 +210,7 @@ public class BookmarkPanel extends PanelWidget { final BookmarkStackMeta meta = getMetadata(idx); if ((recipeId == null && meta.recipeId == null || recipeId != null && meta.recipeId != null && recipeId.equals(meta.recipeId)) - && StackInfo.equalItemAndNBT(stackA, realItems.get(idx), useNBT)) { + && StackInfo.equalItemAndNBT(stackA, getItem(idx), useNBT)) { return idx; } } @@ -219,14 +222,24 @@ public class BookmarkPanel extends PanelWidget { return metadata.get(idx); } - public void addItem(ItemStack stackA, BookmarkStackMeta meta) { - realItems.add(stackA); + public void addItem(ItemStack stackA, BookmarkStackMeta meta, boolean doPopAnim) { + addRealItem(stackA, true, doPopAnim); metadata.add(meta); onGridChanged(); } + public void addItem(ItemStack stackA, BookmarkStackMeta meta, int index) { + if (index == -1) { + addItem(stackA, meta, true); + return; + } + addRealItem(index, stackA, true, true); + metadata.add(index, meta); + onGridChanged(); + } + public void replaceItem(int idx, ItemStack stack) { - realItems.set(idx, stack); + setRealItem(idx, stack, true, true); onGridChanged(); } @@ -318,12 +331,14 @@ public class BookmarkPanel extends PanelWidget { final ItemStack stack = getItem(idx); final BookmarkStackMeta meta = getMetadata(idx); - GuiContainerManager.drawItem( - rect.x + 1, - rect.y + 1, - stack, - true, - meta.factor < 0 || meta.fluidDisplay ? "" : String.valueOf(stack.stackSize)); + realItems + .get(idx) + .drawItem( + rect.x + 1, + rect.y + 1, + true, + meta.factor < 0 || meta.fluidDisplay ? "" : String.valueOf(stack.stackSize), + draggedStack == null); if (meta.recipeId != null && !meta.ingredient && NEIClientConfig.showRecipeMarker()) { drawRecipeMarker(rect.x, rect.y, GuiContainerManager.getFontRenderer(stack)); @@ -407,12 +422,26 @@ public class BookmarkPanel extends PanelWidget { addOrRemoveItem(stackA, null, null, false, false); } + public void addOrRemoveItem(ItemStack stackA, int index) { + addOrRemoveItem(stackA, null, null, false, false, index); + } + public void addOrRemoveItem( ItemStack stackover, final String handlerName, final List ingredients, boolean saveIngredients, boolean saveStackSize) { + addOrRemoveItem(stackover, handlerName, ingredients, saveIngredients, saveStackSize, -1); + } + + public void addOrRemoveItem( + ItemStack stackover, + final String handlerName, + final List ingredients, + boolean saveIngredients, + boolean saveStackSize, + int addIndex) { loadBookmarksIfNeeded(); final Point mousePos = getMousePosition(); @@ -462,7 +491,8 @@ public class BookmarkPanel extends PanelWidget { recipeId != null ? recipeId.copy() : null, (saveStackSize ? 1 : -1) * count, true, - nbTag.hasKey("gtFluidName"))); + nbTag.hasKey("gtFluidName")), + addIndex); } } @@ -472,7 +502,8 @@ public class BookmarkPanel extends PanelWidget { recipeId, (saveStackSize ? 1 : -1) * nbTagA.getInteger("Count"), false, - nbTagA.hasKey("gtFluidName"))); + nbTagA.hasKey("gtFluidName")), + addIndex); } } @@ -739,7 +770,8 @@ public class BookmarkPanel extends PanelWidget { .get("ingredient") .getAsBoolean() : false, - itemStackNBT.hasKey("gtFluidName"))); + itemStackNBT.hasKey("gtFluidName")), + false); } else { NEIClientConfig.logger.warn( "Failed to load bookmarked ItemStack from json string, the item no longer exists:\n{}", @@ -863,8 +895,8 @@ public class BookmarkPanel extends PanelWidget { @Override public void mouseDragged(int mousex, int mousey, int button, long heldTime) { - - if (button == 0 && NEIClientUtils.shiftKey() && mouseDownSlot >= 0) { + // legacy sort + if (button == 0 && NEIClientUtils.shiftKey() && mouseDownSlot >= 0 && draggedStack == null) { ItemPanelSlot mouseOverSlot = getSlotMouseOver(mousex, mousey); if (sortedStackIndex == -1) { @@ -893,7 +925,7 @@ public class BookmarkPanel extends PanelWidget { final BookmarkStackMeta meta = sortedGrid.getMetadata(sortedStackIndex); sortedGrid.removeItem(sortedStackIndex); - hoverGrid.addItem(stack, meta); + hoverGrid.addItem(stack, meta, true); sortedNamespaceIndex = activeNamespaceIndex; sortedStackIndex = hoverGrid.indexOf(stack, meta.recipeId); @@ -935,7 +967,80 @@ public class BookmarkPanel extends PanelWidget { return; } - super.mouseDragged(mousex, mousey, button, heldTime); + if (mouseDownSlot >= 0 + && draggedStack == null + && NEIClientUtils.getHeldItem() == null + && NEIClientConfig.hasSMPCounterPart()) { + ItemPanelSlot mouseOverSlot = getSlotMouseOver(mousex, mousey); + + if (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 500) { + draggedStack = getDraggedStackWithQuantity(mouseDownSlot); + draggedStackMeta = ((BookmarkGrid) grid).getMetadata(mouseDownSlot); + draggedStackOriginIndex = mouseDownSlot; + ((BookmarkGrid) grid).removeItem(mouseDownSlot); + saveBookmarks(); + fixCountOfNamespaces(); + mouseDownSlot = -1; + } + } + } + + @Override + public void update() { + int mouseX = getMousePosition().x; + int mouseY = getMousePosition().y; + if (draggedStack != null) { + + if (!contains(mouseX, mouseY)) { + if (sortedStackIndex != -1 && sortedStackIndex < grid.realItems.size()) { + ((BookmarkGrid) grid).removeItem(sortedStackIndex); + sortedStackIndex = -1; + } + } else { + ItemPanelSlot mouseOverSlot = getSlotMouseOver(mouseX, mouseY); + if (sortedStackIndex == -1) { + sortedNamespaceIndex = activeNamespaceIndex; + if (mouseOverSlot != null) { + sortedStackIndex = mouseOverSlot.slotIndex; + } else { + sortedStackIndex = grid.size(); + } + // dummy item + addOrRemoveItem( + new ItemStack(Items.paper).setStackDisplayName("this is a dummy item"), sortedStackIndex); + } else if (mouseOverSlot != null && mouseOverSlot.slotIndex != sortedStackIndex) { + final BookmarkGrid sortedGrid = namespaces.get(sortedNamespaceIndex); + if (sortedStackIndex >= grid.size()) sortedStackIndex = grid.size() - 1; + if (sortedGrid.getViewMode() == BookmarkViewMode.DEFAULT) { + sortedGrid.moveItem(sortedStackIndex, mouseOverSlot.slotIndex); + sortedStackIndex = mouseOverSlot.slotIndex; + } else if (sortedGrid.getViewMode() == BookmarkViewMode.TODO_LIST) { + final ItemStack stack = sortedGrid.getItem(sortedStackIndex); + final BookmarkStackMeta meta = sortedGrid.getMetadata(sortedStackIndex); + final boolean isIngredient = sortedStackIndex > 0 + && meta.recipeId != null + && meta.ingredient + && meta.recipeId.equals(sortedGrid.getRecipeId(sortedStackIndex - 1)); + + if (!isIngredient) { + mouseOverSlot = getSlotMouseOver(grid.marginLeft + grid.paddingLeft, mouseY); + + if (mouseOverSlot != null && sortedStackIndex != mouseOverSlot.slotIndex) { + sortedGrid.moveItem(sortedStackIndex, mouseOverSlot.slotIndex); + sortedStackIndex = sortedGrid.indexOf(stack, meta.recipeId); + } + + } else if (meta.recipeId != null + && sortedGrid.getMetadata(mouseOverSlot.slotIndex).ingredient + && meta.recipeId.equals(sortedGrid.getRecipeId(mouseOverSlot.slotIndex))) { + sortedGrid.moveItem(sortedStackIndex, mouseOverSlot.slotIndex); + sortedStackIndex = sortedGrid.indexOf(stack, meta.recipeId); + } + } + } + } + } + super.update(); } private ItemPanelSlot getNextSlot(int mousex, int mousey, boolean line) { @@ -960,7 +1065,8 @@ public class BookmarkPanel extends PanelWidget { @Override public void postDraw(int mousex, int mousey) { - if (sortedStackIndex != -1) { + // legacy sort + if (sortedStackIndex != -1 && shiftKey() && draggedStack == null) { GuiContainerManager.drawItems.zLevel += 100; GuiContainerManager.drawItem( mousex - 8, @@ -996,6 +1102,39 @@ public class BookmarkPanel extends PanelWidget { } } + @Override + protected boolean handleDraggedClick(int mouseX, int mouseY, int button) { + if (contains(mouseX, mouseY)) { + ((BookmarkGrid) grid).removeItem(sortedStackIndex); + if (draggedStackMeta != null) { + ((BookmarkGrid) grid).addItem(draggedStack, draggedStackMeta, sortedStackIndex); + fixCountOfNamespaces(); + saveBookmarks(); + } else addOrRemoveItem(draggedStack, sortedStackIndex); + sortedStackIndex = -1; + draggedStack = null; + draggedStackMeta = null; + draggedStackOriginIndex = -1; + return true; + } + return false; + } + + public void restoreBookmark() { + if (draggedStack != null && draggedStackOriginIndex != -1) { + if (sortedStackIndex != -1) ((BookmarkGrid) grid).removeItem(sortedStackIndex); + if (draggedStackMeta != null) { + ((BookmarkGrid) grid).addItem(draggedStack, draggedStackMeta, draggedStackOriginIndex); + fixCountOfNamespaces(); + saveBookmarks(); + } else addOrRemoveItem(draggedStack, draggedStackOriginIndex); + sortedStackIndex = -1; + draggedStack = null; + draggedStackMeta = null; + draggedStackOriginIndex = -1; + } + } + @Override public List handleTooltip(int mx, int my, List tooltip) { @@ -1009,8 +1148,7 @@ public class BookmarkPanel extends PanelWidget { @Override public void mouseUp(int mousex, int mousey, int button) { - if (sortedStackIndex != -1) { - draggedStack = null; + if (sortedStackIndex != -1 && draggedStack == null) { sortedNamespaceIndex = -1; sortedStackIndex = -1; mouseDownSlot = -1; @@ -1089,4 +1227,9 @@ public class BookmarkPanel extends PanelWidget { BGrid.replaceItem(slotIndex, StackInfo.loadFromNBT(nbTag)); } } + + public void deleteDraggedMeta() { + draggedStackMeta = null; + draggedStackOriginIndex = -1; + } } diff --git a/src/main/java/codechicken/nei/ItemPanel.java b/src/main/java/codechicken/nei/ItemPanel.java index 57fa0aed..89d5ee87 100644 --- a/src/main/java/codechicken/nei/ItemPanel.java +++ b/src/main/java/codechicken/nei/ItemPanel.java @@ -57,7 +57,8 @@ public class ItemPanel extends PanelWidget { public void refresh(GuiContainer gui) { if (newItems != null) { - realItems = newItems; + realItems.clear(); + addRealItems(newItems, false, false); newItems = null; onGridChanged(); } diff --git a/src/main/java/codechicken/nei/ItemsGrid.java b/src/main/java/codechicken/nei/ItemsGrid.java index 5b38e59a..57911e6e 100644 --- a/src/main/java/codechicken/nei/ItemsGrid.java +++ b/src/main/java/codechicken/nei/ItemsGrid.java @@ -9,7 +9,9 @@ import codechicken.nei.guihook.GuiContainerManager; import codechicken.nei.recipe.StackInfo; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; import javax.annotation.Nullable; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.ScaledResolution; @@ -31,7 +33,7 @@ public class ItemsGrid { protected int paddingLeft; - protected ArrayList realItems = new ArrayList<>(); + protected ArrayList realItems = new ArrayList<>(); protected int page; protected int perPage; @@ -49,11 +51,27 @@ public class ItemsGrid { protected boolean refreshBuffer = true; public ArrayList getItems() { - return realItems; + return realItems.stream().map(e -> e.itemStack).collect(Collectors.toCollection(ArrayList::new)); } public ItemStack getItem(int idx) { - return realItems.get(idx); + return realItems.get(idx).itemStack; + } + + protected void addRealItems(Collection itemStack, boolean doMoveAnim, boolean doPopAnim) { + itemStack.forEach(e -> addRealItem(e, doMoveAnim, doPopAnim)); + } + + protected void addRealItem(ItemStack itemStack, boolean doMoveAnim, boolean doPopAnim) { + realItems.add(new AnimatedItemStack(itemStack, doMoveAnim, doPopAnim)); + } + + protected void addRealItem(int index, ItemStack itemStack, boolean doMoveAnim, boolean doPopAnim) { + realItems.add(index, new AnimatedItemStack(itemStack, doMoveAnim, doPopAnim)); + } + + protected void setRealItem(int index, ItemStack itemStack, boolean doMoveAnim, boolean doPopAnim) { + realItems.set(index, new AnimatedItemStack(itemStack, doMoveAnim, doPopAnim)); } public int size() { @@ -63,7 +81,7 @@ public class ItemsGrid { public int indexOf(ItemStack stackA, boolean useNBT) { for (int idx = 0; idx < realItems.size(); idx++) { - if (StackInfo.equalItemAndNBT(stackA, realItems.get(idx), useNBT)) { + if (StackInfo.equalItemAndNBT(stackA, getItem(idx), useNBT)) { return idx; } } @@ -317,7 +335,7 @@ public class ItemsGrid { } protected void drawItem(Rectangle4i rect, int idx) { - GuiContainerManager.drawItem(rect.x + 1, rect.y + 1, getItem(idx)); + realItems.get(idx).drawItem(rect.x + 1, rect.y + 1); } public ItemPanelSlot getSlotMouseOver(int mousex, int mousey) { diff --git a/src/main/java/codechicken/nei/NEIClientConfig.java b/src/main/java/codechicken/nei/NEIClientConfig.java index 3a9991bf..0e26db1a 100644 --- a/src/main/java/codechicken/nei/NEIClientConfig.java +++ b/src/main/java/codechicken/nei/NEIClientConfig.java @@ -237,6 +237,10 @@ public class NEIClientConfig { .setComment("Use NBT in Bookmarks") .getBooleanValue(true); API.addOption(new OptionToggleButton("inventory.useNBTInBookmarks", true)); + tag.getTag("inventory.bookmarksAnimationEnabled") + .setComment("REI Style Animation in Bookmarks") + .getBooleanValue(true); + API.addOption(new OptionToggleButton("inventory.bookmarksAnimationEnabled", true)); tag.getTag("inventory.showRecipeMarker") .setComment("Show Recipe Marker") .getBooleanValue(false); @@ -504,6 +508,10 @@ public class NEIClientConfig { return getBooleanSetting("inventory.useNBTInBookmarks"); } + public static boolean areBookmarksAnimated() { + return getBooleanSetting("inventory.bookmarksAnimationEnabled"); + } + public static boolean showRecipeMarker() { return getBooleanSetting("inventory.showRecipeMarker"); } diff --git a/src/main/java/codechicken/nei/PanelWidget.java b/src/main/java/codechicken/nei/PanelWidget.java index a705c781..439a972d 100644 --- a/src/main/java/codechicken/nei/PanelWidget.java +++ b/src/main/java/codechicken/nei/PanelWidget.java @@ -15,7 +15,7 @@ import net.minecraft.item.ItemStack; public abstract class PanelWidget extends Widget { protected static final int PADDING = 2; - public ItemStack draggedStack; + public static ItemStack draggedStack; public int mouseDownSlot = -1; public Button pagePrev; @@ -183,8 +183,7 @@ public abstract class PanelWidget extends Widget { if (mouseDownSlot >= 0 && draggedStack == null && NEIClientUtils.getHeldItem() == null - && NEIClientConfig.hasSMPCounterPart() - && !GuiInfo.hasCustomSlots(NEIClientUtils.getGuiContainer())) { + && NEIClientConfig.hasSMPCounterPart()) { ItemPanelSlot mouseOverSlot = getSlotMouseOver(mousex, mousey); if (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 500) { @@ -241,14 +240,30 @@ public abstract class PanelWidget extends Widget { @Override public boolean handleClickExt(int mouseX, int mouseY, int button) { - if (ItemPanels.itemPanel.draggedStack != null) { - return ItemPanels.itemPanel.handleDraggedClick(mouseX, mouseY, button); - } + if (draggedStack != null) { + boolean succeed = ItemPanels.bookmarkPanel.handleDraggedClick(mouseX, mouseY, button) + || ItemPanels.itemPanel.handleDraggedClick(mouseX, mouseY, button); + if (succeed) return true; - if (ItemPanels.bookmarkPanel.draggedStack != null) { - return ItemPanels.bookmarkPanel.handleDraggedClick(mouseX, mouseY, button); - } + if (handleGUIContainerClick(draggedStack, mouseX, mouseY, button)) { + if (draggedStack.stackSize == 0) { + ItemPanels.bookmarkPanel.restoreBookmark(); + draggedStack = null; + } + return true; + } + + final GuiContainer gui = NEIClientUtils.getGuiContainer(); + if (mouseX < gui.guiLeft + || mouseY < gui.guiTop + || mouseX >= gui.guiLeft + gui.xSize + || mouseY >= gui.guiTop + gui.ySize) { + ItemPanels.bookmarkPanel.deleteDraggedMeta(); + draggedStack = null; + return true; + } + } if (NEIClientUtils.getHeldItem() != null) { final ItemStack draggedStack = NEIClientUtils.getHeldItem().copy(); return handleGUIContainerClick(draggedStack, mouseX, mouseY, button); @@ -258,28 +273,7 @@ public abstract class PanelWidget extends Widget { } protected boolean handleDraggedClick(int mouseX, int mouseY, int button) { - if (draggedStack == null) { - return false; - } - - if (handleGUIContainerClick(draggedStack, mouseX, mouseY, button)) { - - if (draggedStack.stackSize == 0) { - draggedStack = null; - } - - return true; - } - - final GuiContainer gui = NEIClientUtils.getGuiContainer(); - if (mouseX < gui.guiLeft - || mouseY < gui.guiTop - || mouseX >= gui.guiLeft + gui.xSize - || mouseY >= gui.guiTop + gui.ySize) { - draggedStack = null; - } - - return true; + return false; } protected boolean handleGUIContainerClick(final ItemStack draggedStack, int mouseX, int mouseY, int button) { diff --git a/src/main/resources/assets/nei/lang/en_US.lang b/src/main/resources/assets/nei/lang/en_US.lang index b41b8d62..22b6bb89 100644 --- a/src/main/resources/assets/nei/lang/en_US.lang +++ b/src/main/resources/assets/nei/lang/en_US.lang @@ -146,6 +146,9 @@ nei.options.inventory.saveCurrentRecipeInBookmarksEnabled.false=Disabled nei.options.inventory.useNBTInBookmarks=Use NBT in Bookmarks nei.options.inventory.useNBTInBookmarks.true=Yes nei.options.inventory.useNBTInBookmarks.false=No +nei.options.inventory.bookmarksAnimationEnabled=REI Style Animation in Bookmarks +nei.options.inventory.bookmarksAnimationEnabled.true=Yes +nei.options.inventory.bookmarksAnimationEnabled.false=No nei.options.inventory.showRecipeMarker=Show Recipe Marker nei.options.inventory.showRecipeMarker.true=Yes nei.options.inventory.showRecipeMarker.false=No