From effe46a69d26d05b5f4d9360b92414e1cee7b387 Mon Sep 17 00:00:00 2001 From: Madeleaan <70163122+Madeleaan@users.noreply.github.com> Date: Sat, 3 Aug 2024 17:50:56 +0200 Subject: Add accessory bag overlay features (#1269) Co-authored-by: nopo --- .../miscgui/AccessoryBagOverlay.java | 1093 ++++++++++---------- .../notenoughupdates/options/NEUConfig.java | 9 +- .../profileviewer/PlayerStats.java | 309 ++++-- .../notenoughupdates/util/GuiTextures.java | 4 +- .../notenoughupdates/accessory_bag_overlay.png | Bin 429 -> 0 bytes .../notenoughupdates/accessory_bag_overlay_v2.png | Bin 0 -> 4992 bytes 6 files changed, 817 insertions(+), 598 deletions(-) delete mode 100644 src/main/resources/assets/notenoughupdates/accessory_bag_overlay.png create mode 100644 src/main/resources/assets/notenoughupdates/accessory_bag_overlay_v2.png diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java index 6e81351a..013807c3 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/AccessoryBagOverlay.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 NotEnoughUpdates contributors + * Copyright (C) 2022-2024 NotEnoughUpdates contributors * * This file is part of NotEnoughUpdates. * @@ -22,41 +22,47 @@ package io.github.moulberry.notenoughupdates.miscgui; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NEUManager; +import io.github.moulberry.notenoughupdates.NEUOverlay; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.auction.APIManager; import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe; -import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.core.util.ArrowPagesUtils; import io.github.moulberry.notenoughupdates.events.ButtonExclusionZoneEvent; -import io.github.moulberry.notenoughupdates.listener.RenderListener; +import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer; +import io.github.moulberry.notenoughupdates.options.NEUConfig; +import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import io.github.moulberry.notenoughupdates.profileviewer.PlayerStats; import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.ItemUtils; import io.github.moulberry.notenoughupdates.util.Rectangle; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.gui.inventory.GuiChest; -import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.RenderHelper; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.inventory.ContainerChest; import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.util.EnumChatFormatting; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL14; import java.awt.*; -import java.io.ByteArrayInputStream; -import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -66,20 +72,35 @@ import java.util.Set; import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; import static io.github.moulberry.notenoughupdates.util.GuiTextures.accessory_bag_overlay; @NEUAutoSubscribe public class AccessoryBagOverlay { - private static final int TAB_BASIC = 0; - private static final int TAB_TOTAL = 1; - private static final int TAB_BONUS = 2; - private static final int TAB_DUP = 3; - private static final int TAB_MISSING = 4; - private static final int TAB_OPTIMIZER = 5; + private enum Tabs { + TAB_BASIC, TAB_TOTAL, TAB_DUP, TAB_MISSING + } public static final AccessoryBagOverlay INSTANCE = new AccessoryBagOverlay(); + // Arrow pages variables + private static int statsPageActive = 0; + private static int statsPagesTotal = 0; + private static int dupePageActive = 0; + private static int dupePagesTotal = 0; + private static int missingPageActive = 0; + private static int missingPagesTotal = 0; + + // Page-specific button variables + private static boolean dupe_highlight = true; + private static boolean dupe_showPersonal = false; + private static boolean missing_showAllTiers = true; + private static boolean missing_useMP = true; + + private static List tooltipToDisplay = null; + private static boolean offsetButtons = false; + @SubscribeEvent public void onButtonExclusionZones(ButtonExclusionZoneEvent event) { if (isInAccessoryBag()) { @@ -87,7 +108,7 @@ public class AccessoryBagOverlay { new Rectangle( event.getGuiBaseRect().getRight(), event.getGuiBaseRect().getTop(), - 80 /*pane*/ + 24 /*tabs*/ + 4 /*space*/, 150 + 168 /*pane*/ + (offsetButtons ? 24 : 0) /*tabs*/ + 5 /*space*/, 128 ), ButtonExclusionZoneEvent.PushDirection.TOWARDS_RIGHT ); @@ -101,23 +122,15 @@ public class AccessoryBagOverlay { Utils.createItemStack(Items.diamond_sword, EnumChatFormatting.DARK_AQUA + "Total Stat Bonuses", 0 ), - Utils.createItemStack( - Item.getItemFromBlock(Blocks.anvil), - EnumChatFormatting.DARK_AQUA + "Total Stat Bonuses (from reforges)", - 0 - ), Utils.createItemStack(Items.dye, EnumChatFormatting.DARK_AQUA + "Duplicates", 8 ), Utils.createItemStack(Item.getItemFromBlock(Blocks.barrier), EnumChatFormatting.DARK_AQUA + "Missing", 0 - ), - Utils.createItemStack(Item.getItemFromBlock(Blocks.redstone_block), EnumChatFormatting.DARK_AQUA + "Optimizer", - 0 - ), + ) }; - private static int currentTab = TAB_BASIC; + private static Tabs currentTab = Tabs.TAB_BASIC; public static boolean mouseClick() { if (Minecraft.getMinecraft().currentScreen instanceof GuiChest) { @@ -133,75 +146,71 @@ public class AccessoryBagOverlay { if (!Mouse.getEventButtonState()) return false; try { - ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); - - int width = scaledResolution.getScaledWidth(); - int height = scaledResolution.getScaledHeight(); + AccessorGuiContainer accessor = (AccessorGuiContainer) Minecraft.getMinecraft().currentScreen; + int xSize = accessor.getXSize(); + int guiLeft = accessor.getGuiLeft(); + int guiTop = accessor.getGuiTop(); + + if (mouseX() < guiLeft + xSize + 3 || mouseX() > guiLeft + xSize + 168 + 28) return false; + if (mouseY() < guiTop || mouseY() > guiTop + 128) return false; + + if (mouseX() > guiLeft + xSize + 168 + 3 && mouseY() < guiTop + 20 * Tabs.values().length + 22) { + int tabClicked = (mouseY() - guiTop) / 20; + tabClicked = Math.min(Math.max(0, tabClicked), Tabs.values().length - 1); + currentTab = Tabs.values()[tabClicked]; + playPressSound(); + } - int mouseX = Mouse.getX() / scaledResolution.getScaleFactor(); - int mouseY = height - Mouse.getY() / scaledResolution.getScaleFactor(); + if (currentTab == Tabs.TAB_TOTAL) { + if (statsPagesTotal > 1) ArrowPagesUtils.onPageSwitchMouse( + guiLeft + xSize + 3, + guiTop, + new int[]{60, 110}, + statsPageActive, + statsPagesTotal, + integer -> statsPageActive = integer + ); + } + if (currentTab == Tabs.TAB_DUP) { + if (dupePagesTotal > 1) ArrowPagesUtils.onPageSwitchMouse( + guiLeft + xSize + 3, + guiTop, + new int[]{60, 110}, + dupePageActive, + dupePagesTotal, + integer -> dupePageActive = integer + ); - int xSize = (int) Utils.getField( - GuiContainer.class, - Minecraft.getMinecraft().currentScreen, - "xSize", - "field_146999_f" - ); - int ySize = (int) Utils.getField( - GuiContainer.class, - Minecraft.getMinecraft().currentScreen, - "ySize", - "field_147000_g" - ); - int guiLeft = (int) Utils.getField( - GuiContainer.class, - Minecraft.getMinecraft().currentScreen, - "guiLeft", - "field_147003_i" - ); - int guiTop = (int) Utils.getField( - GuiContainer.class, - Minecraft.getMinecraft().currentScreen, - "guiTop", - "field_147009_r" - ); + if (new Rectangle(guiLeft + xSize + 3 + 120, guiTop + 108, 16, 16).contains(mouseX(), mouseY())) { + dupe_highlight = !dupe_highlight; + playPressSound(); + } - if (mouseX < guiLeft + xSize + 3 || mouseX > guiLeft + xSize + 80 + 28) return false; - if (mouseY < guiTop || mouseY > guiTop + 166) return false; + if (new Rectangle(guiLeft + xSize + 3 + 141, guiTop + 108, 16, 16).contains(mouseX(), mouseY())) { + dupe_showPersonal = !dupe_showPersonal; + playPressSound(); + } - if (mouseX > guiLeft + xSize + 83 && mouseY < guiTop + 20 * TAB_MISSING + 22) { - currentTab = (mouseY - guiTop) / 20; - if (currentTab < 0) currentTab = 0; - if (currentTab > TAB_MISSING) currentTab = TAB_MISSING; } + if (currentTab == Tabs.TAB_MISSING) { + if (missingPagesTotal > 1) ArrowPagesUtils.onPageSwitchMouse( + guiLeft + xSize + 3, + guiTop, + new int[]{60, 110}, + missingPageActive, + missingPagesTotal, + integer -> missingPageActive = integer + ); - if (currentTab == TAB_OPTIMIZER) { - int x = guiLeft + xSize + 3; - int y = guiTop; - - if (mouseY > y + 92 && mouseY < y + 103) { - if (mouseX > x + 5 && mouseX < x + 75) { - mainWeapon = (int) Math.floor((mouseX - x - 5) / 70f * 9); - if (mainWeapon < 1) { - mainWeapon = 1; - } else if (mainWeapon > 9) { - mainWeapon = 9; - } - } + if (new Rectangle(guiLeft + xSize + 3 + 120, guiTop + 108, 16, 16).contains(mouseX(), mouseY())) { + missing_useMP = !missing_useMP; + missing = null; + playPressSound(); } - - if (mouseX > x + 5 && mouseX < x + 35 || mouseX > x + 45 && mouseX < x + 75) { - boolean set = mouseX > x + 5 && mouseX < x + 35; - - if (mouseY > y + 32 && mouseY < y + 43) { - forceCC = set; - } else if (mouseY > y + 52 && mouseY < y + 63) { - forceAS = set; - } else if (mouseY > y + 72 && mouseY < y + 83) { - useGodPot = set; - } else if (mouseY > y + 92 && mouseY < y + 103) { - allowShaded = set; - } + if (new Rectangle(guiLeft + xSize + 3 + 141, guiTop + 108, 16, 16).contains(mouseX(), mouseY())) { + missing_showAllTiers = !missing_showAllTiers; + missing = null; + playPressSound(); } } @@ -216,7 +225,6 @@ public class AccessoryBagOverlay { pagesVisited = new HashSet<>(); talismanCountRarity = null; totalStats = null; - reforgeStats = null; duplicates = null; missing = null; } @@ -225,8 +233,8 @@ public class AccessoryBagOverlay { private static Set pagesVisited = new HashSet<>(); public static void renderVisitOverlay(int x, int y) { - Utils.drawStringCenteredScaledMaxWidth("Please visit all", x + 40, y + 78, true, 70, -1); - Utils.drawStringCenteredScaledMaxWidth("pages of the bag", x + 40, y + 86, true, 70, -1); + Utils.drawStringCenteredScaledMaxWidth("Please visit all", x + 80, y + 60, true, 140, -1); + Utils.drawStringCenteredScaledMaxWidth("pages of the bag", x + 80, y + 72, true, 140, -1); } private static TreeMap talismanCountRarity = null; @@ -242,7 +250,7 @@ public class AccessoryBagOverlay { } } - drawString(x, y, "# By Rarity"); + drawTitle(x, y, "Total Counts By Rarity"); int yIndex = 0; for (Map.Entry entry : talismanCountRarity.descendingMap().entrySet()) { @@ -250,12 +258,21 @@ public class AccessoryBagOverlay { Utils.renderAlignedString( rarityName, EnumChatFormatting.WHITE.toString() + entry.getValue(), - x + 5, + x + 34, y + 20 + 11 * yIndex, - 70 + 100 ); yIndex++; } + + NEUConfig.HiddenProfileSpecific profileSpecific = NotEnoughUpdates.INSTANCE.config.getProfileSpecific(); + int mp = 0; + if (profileSpecific != null) mp = profileSpecific.magicalPower; + Utils.renderAlignedString( + EnumChatFormatting.AQUA + "Magical Power", + mp != 0 ? EnumChatFormatting.WHITE.toString() + mp : EnumChatFormatting.RED + "NO DATA, DO /PV", + x + 20, y + 25 + 88, 130 + ); } private static PlayerStats.Stats totalStats = null; @@ -264,77 +281,37 @@ public class AccessoryBagOverlay { if (totalStats == null) { totalStats = new PlayerStats.Stats(); for (ItemStack stack : accessoryStacks) { - if (stack != null) totalStats.add(getStatForItem(stack, STAT_PATTERN_MAP, true)); + if (stack != null) totalStats.add(getStatForItem(stack, PlayerStats.STAT_PATTERN_MAP, true)); } } - drawString(x, y, "Total Stats"); + drawTitle(x, y, "Total Stats"); int yIndex = 0; + List> statPairs = new ArrayList<>(); for (int i = 0; i < PlayerStats.defaultStatNames.length; i++) { String statName = PlayerStats.defaultStatNames[i]; String statNamePretty = PlayerStats.defaultStatNamesPretty[i]; int val = Math.round(totalStats.get(statName)); - if (Math.abs(val) < 1E-5) continue; - - GlStateManager.color(1, 1, 1, 1); - GlStateManager.enableBlend(); - GL14.glBlendFuncSeparate( - GL11.GL_SRC_ALPHA, - GL11.GL_ONE_MINUS_SRC_ALPHA, - GL11.GL_ONE, - GL11.GL_ONE_MINUS_SRC_ALPHA - ); - Utils.renderAlignedString( - statNamePretty, - EnumChatFormatting.WHITE.toString() + val, - x + 5, - y + 20 + 11 * yIndex, - 70 - ); - - yIndex++; + if (Math.abs(val) >= 1E-5) statPairs.add(new ImmutablePair<>(statNamePretty, val)); } - } - - private static PlayerStats.Stats reforgeStats = null; - - public static void renderReforgeStatsOverlay(int x, int y) { - if (reforgeStats == null) { - reforgeStats = new PlayerStats.Stats(); - for (ItemStack stack : accessoryStacks) { - if (stack != null) reforgeStats.add(getStatForItem(stack, STAT_PATTERN_MAP_BONUS, false)); - } - } - - drawString(x, y, "Reforge Stats"); - int yIndex = 0; - for (int i = 0; i < PlayerStats.defaultStatNames.length; i++) { - String statName = PlayerStats.defaultStatNames[i]; - String statNamePretty = PlayerStats.defaultStatNamesPretty[i]; - int val = Math.round(reforgeStats.get(statName)); - - if (Math.abs(val) < 1E-5) continue; - - GlStateManager.color(1, 1, 1, 1); - GlStateManager.enableBlend(); - GL14.glBlendFuncSeparate( - GL11.GL_SRC_ALPHA, - GL11.GL_ONE_MINUS_SRC_ALPHA, - GL11.GL_ONE, - GL11.GL_ONE_MINUS_SRC_ALPHA - ); + statsPageActive = Math.min(statsPageActive, (statPairs.size() / 8)); + for (Pair pair : statPairs.subList(statsPageActive * 8, statPairs.size())) { Utils.renderAlignedString( - statNamePretty, - EnumChatFormatting.WHITE.toString() + val, - x + 5, - y + 20 + 11 * yIndex, - 70 + pair.getKey(), + EnumChatFormatting.WHITE.toString() + pair.getValue(), + x + 6, + y + 20 + 11 * yIndex, 158 ); + if (yIndex++ >= 7 && statPairs.size() > 9) break; + } - yIndex++; + statsPagesTotal = (int) Math.ceil(statPairs.size() / 8.0); + if (statPairs.size() > 9) { + GlStateManager.color(1f, 1f, 1f, 1f); + ArrowPagesUtils.onDraw(x, y, new int[]{60, 110}, statsPageActive, statsPagesTotal); } } @@ -344,71 +321,68 @@ public class AccessoryBagOverlay { if (duplicates == null) { JsonObject misc = Constants.MISC; if (misc == null) { - drawString(x, y, "Duplicates: ERROR"); - return; - } - JsonElement talisman_upgrades_element = misc.get("talisman_upgrades"); - if (talisman_upgrades_element == null) { - drawString(x, y, "Duplicates: ERROR"); + drawTitle(x, y, "Duplicates: REPO ERROR"); + Utils.showOutdatedRepoNotification("misc.json"); return; } - JsonObject talisman_upgrades = talisman_upgrades_element.getAsJsonObject(); - - duplicates = new HashSet<>(); - - Set prevInternalnames = new HashSet<>(); - for (ItemStack stack : accessoryStacks) { - String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); - - if (prevInternalnames.contains(internalname)) { - duplicates.add(stack); - continue; - } - prevInternalnames.add(internalname); - - if (talisman_upgrades.has(internalname)) { - JsonArray upgrades = talisman_upgrades.get(internalname).getAsJsonArray(); - for (ItemStack stack2 : accessoryStacks) { - if (stack != stack2) { - String internalname2 = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack2); - for (int j = 0; j < upgrades.size(); j++) { - String upgrade = upgrades.get(j).getAsString(); - if (internalname2.equals(upgrade)) { - duplicates.add(stack); - break; - } - } - } - } - } - } } if (duplicates.isEmpty()) { - drawString(x, y, "No Duplicates"); + drawTitle(x, y, "No Duplicates"); } else { - drawString(x, y, "Duplicates: " + duplicates.size()); + drawTitle(x, y, "Duplicates: " + duplicates.size()); int yIndex = 0; - for (ItemStack duplicate : duplicates) { + List sortedDupes = + duplicates.stream().sorted((Comparator.comparing(ItemStack::getDisplayName))).collect(Collectors.toList()); + + dupePageActive = Math.min(dupePageActive, (duplicates.size() / 8)); + for (ItemStack duplicate : sortedDupes.subList(dupePageActive * 8, sortedDupes.size())) { String s = duplicate.getDisplayName(); - Utils.renderShadowedString(s, x + 40, y + 20 + 11 * yIndex, 70); - if (duplicates.size() > 11) { - if (++yIndex >= 10) break; - } else { - if (++yIndex >= 11) break; - } + Utils.renderShadowedString(s.substring(0, Math.min(s.length(), 35)), x + 84, y + 20 + 11 * yIndex, 158); + if (++yIndex >= 8 && sortedDupes.size() > 9) break; } - if (duplicates.size() > 11) { - Utils.drawStringCenteredScaledMaxWidth( - "+" + (duplicates.size() - 10) + " More", - x + 40, y + 16 + 121, - false, - 70, - gray() - ); + dupePagesTotal = (int) Math.ceil(sortedDupes.size() / 8.0); + if (sortedDupes.size() > 9) { + GlStateManager.color(1f, 1f, 1f, 1f); + ArrowPagesUtils.onDraw(x, y, new int[]{60, 110}, dupePageActive, dupePagesTotal); } } + + List highlightTooltip = new ArrayList<>(); + if (dupe_highlight) { + highlightTooltip.add("§aHighlight dupes"); + highlightTooltip.add("§7Will highlight accessories"); + highlightTooltip.add("§7you have duplicates of."); + } else { + highlightTooltip.add("§cDon't highlight dupes"); + highlightTooltip.add("§7Will not highlight accessories"); + highlightTooltip.add("§7you have duplicates of."); + } + renderButton( + new ItemStack(dupe_highlight ? Items.ender_eye : Items.ender_pearl), + x + 120, + y + 107, + highlightTooltip + ); + + List compDeletorTooltip = new ArrayList<>(); + if (dupe_showPersonal) { + compDeletorTooltip.add("§aHighlight Compactors & Deletors"); + compDeletorTooltip.add("§7Will highlight all duplicates."); + } else { + compDeletorTooltip.add("§cDon't highlight Compactors & Deletors"); + compDeletorTooltip.add("§7Duplicates allow you to specify"); + compDeletorTooltip.add("§7more things to compact and delete,"); + compDeletorTooltip.add("§7but they do not give more MP!"); + } + renderButton( + NotEnoughUpdates.INSTANCE.manager.createItem(dupe_showPersonal ? "PERSONAL_DELETOR_4000" : "DISPENSER"), + x + 141, + y + 107, + compDeletorTooltip + ); + } private static List missing = null; @@ -417,12 +391,14 @@ public class AccessoryBagOverlay { if (missing == null) { JsonObject misc = Constants.MISC; if (misc == null) { - drawString(x, y, "Duplicates: ERROR"); + drawTitle(x, y, "Missing: REPO ERROR"); + Utils.showOutdatedRepoNotification("misc.json"); return; } JsonElement talisman_upgrades_element = misc.get("talisman_upgrades"); if (talisman_upgrades_element == null) { - drawString(x, y, "Duplicates: ERROR"); + drawTitle(x, y, "Missing: REPO ERROR"); + Utils.showOutdatedRepoNotification("misc.json talisman_upgrades"); return; } JsonObject talisman_upgrades = talisman_upgrades_element.getAsJsonObject(); @@ -453,7 +429,8 @@ public class AccessoryBagOverlay { } for (ItemStack stack : accessoryStacks) { - String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); + String internalname = + NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery().withItemStack(stack).resolveInternalName(); missingInternal.remove(internalname); for (Map.Entry talisman_upgrade_element : talisman_upgrades.entrySet()) { @@ -466,9 +443,15 @@ public class AccessoryBagOverlay { } } } - } - missingInternal.sort(getItemComparator()); + if (internalname.contains("ABICASE")) { + missingInternal.removeAll(missingInternal + .stream() + .filter(s -> s.contains("ABICASE")) + .collect(Collectors.toList())); + } + } + missingInternal.sort(getItemComparator(missing_useMP)); Set missingDisplayNames = new HashSet<>(); for (String internal : missingInternal) { @@ -493,222 +476,88 @@ public class AccessoryBagOverlay { missingDisplayNames.add(stack.getDisplayName()); if (hasDup) { + if (!missing_showAllTiers) continue; stack.setStackDisplayName(stack.getDisplayName() + "*"); } missing.add(stack); } } if (missing.isEmpty()) { - drawString(x, y, "No Missing"); + drawTitle(x, y, "No Missing"); } else { - drawString(x, y, "Missing: " + missing.size()); + drawTitle(x, y, "Missing: " + missing.size()); int yIndex = 0; - long currentTime = System.currentTimeMillis(); - for (ItemStack missingStack : missing) { + missingPageActive = Math.min(missingPageActive, missing.size() / 8); + for (ItemStack missingStack : missing.subList(missingPageActive * 8, missing.size())) { String s = missingStack.getDisplayName(); + String internal = NotEnoughUpdates.INSTANCE.manager + .createItemResolutionQuery() + .withItemStack(missingStack) + .resolveInternalName(); + if (internal.equals("RIFT_PRISM") && hasConsumedRiftPrism()) continue; + double price = getItemPrice(internal); + Utils.renderAlignedString( + s, + price != -1 + ? "§6" + Utils.shortNumberFormat(price, 0) + : "§c" + "NO DATA", + x + 5, + y + 20 + 11 * yIndex, + 158 + ); + Rectangle rect = new Rectangle(x, y + 20 + 11 * yIndex, 168, 11); + renderAccessoryHover(rect, missingStack); + if (++yIndex >= 8 && missing.size() > 9) break; + } - s = Minecraft.getMinecraft().fontRendererObj.trimStringToWidth(s, 70); - - String clean = StringUtils.cleanColourNotModifiers(s); - for (int xO = -1; xO <= 1; xO++) { - for (int yO = -1; yO <= 1; yO++) { - int col = 0xff202020; - //if(xO != 0 && yO != 0) col = 0xff252525; - Minecraft.getMinecraft().fontRendererObj.drawString( - clean, - x + 5 + xO, - y + 20 + 11 * yIndex + yO, - col, - false - ); - } - } - Minecraft.getMinecraft().fontRendererObj.drawString(s, x + 5, y + 20 + 11 * yIndex, 0xffffff, false); - if (missing.size() > 11) { - if (++yIndex >= 10) break; - } else { - if (++yIndex >= 11) break; - } + missingPagesTotal = (int) Math.ceil(missing.size() / 8.0); + if (missing.size() > 9) { + GlStateManager.color(1f, 1f, 1f, 1f); + ArrowPagesUtils.onDraw(x, y, new int[]{60, 110}, missingPageActive, missingPagesTotal); } - if (missing.size() > 11) { - Utils.drawStringCenteredScaledMaxWidth("Show All", x + 40, y + 16 + 121, false, 70, gray()); - - final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); - final int scaledWidth = scaledresolution.getScaledWidth(); - final int scaledHeight = scaledresolution.getScaledHeight(); - int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth; - int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1; - - if (mouseX > x && mouseX < x + 80 && - mouseY > y + 11 + 121 && mouseY < y + 21 + 121) { - List text = new ArrayList<>(); - StringBuilder line = new StringBuilder(); - int leftMaxSize = 0; - int middleMaxSize = 0; - for (int i = 0; i < missing.size(); i += 3) { - leftMaxSize = Math.max(leftMaxSize, Minecraft.getMinecraft().fontRendererObj. - getStringWidth(missing.get(i).getDisplayName())); - } - for (int i = 1; i < missing.size(); i += 3) { - middleMaxSize = Math.max(middleMaxSize, Minecraft.getMinecraft().fontRendererObj. - getStringWidth(missing.get(i).getDisplayName())); - } - for (int i = 0; i < missing.size(); i++) { - if (i % 3 == 0 && i > 0) { - text.add(line.toString()); - line = new StringBuilder(); - } - StringBuilder name = new StringBuilder(missing.get(i).getDisplayName()); - int nameLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(name.toString()); - - int padSize = -1; - if (i % 3 == 0) padSize = leftMaxSize; - if (i % 3 == 1) padSize = middleMaxSize; - if (padSize > 0) { - float padNum = (padSize - nameLen) / 4.0f; - int remainder = (int) ((padNum % 1) * 4); - while (padNum >= 1) { - if (remainder > 0) { - name.append(EnumChatFormatting.BOLD).append(" "); - remainder--; - } else { - name.append(EnumChatFormatting.RESET).append(" "); - } - padNum--; - } - } - line.append('\u00A7').append(Utils.getPrimaryColourCode(missing.get(i).getDisplayName())); - if (i < 9) { - line.append((char) ('\u2776' + i)).append(' '); - } else { - line.append("\u2b24 "); - } - line.append(name); - if (i % 3 < 2) line.append(" "); - } + List mpTooltip = new ArrayList<>(); + if (missing_useMP) { + mpTooltip.add("§bSort by Magical Power"); + mpTooltip.add("§7Will sort the accessories"); + mpTooltip.add("§7by the best MP gain."); + } else { + mpTooltip.add("§6Sort by Coins"); + mpTooltip.add("§7Will sort the accessories"); + mpTooltip.add("§7by the cheapest options."); + } + renderButton(ItemUtils.getCoinItemStack(missing_useMP ? 10_000_000 : 100_000), x + 120, y + 107, mpTooltip); - GlStateManager.pushMatrix(); - GlStateManager.scale(2f / scaledresolution.getScaleFactor(), 2f / scaledresolution.getScaleFactor(), 1); - Utils.drawHoveringText(text, - mouseX * scaledresolution.getScaleFactor() / 2, - mouseY * scaledresolution.getScaleFactor() / 2, - scaledWidth * scaledresolution.getScaleFactor() / 2, - scaledHeight * scaledresolution.getScaleFactor() / 2, -1 - ); - GlStateManager.popMatrix(); - } + List tieredTooltip = new ArrayList<>(); + if (missing_showAllTiers) { + tieredTooltip.add("§aShow all tiers"); + tieredTooltip.add("§7Will show all the tiers"); + tieredTooltip.add("§7to get the cheapest options."); + } else { + tieredTooltip.add("§6Show highest tier"); + tieredTooltip.add("§7Will show only the highest tier"); + tieredTooltip.add("§7to avoid wasting money on lower ones."); } + renderButton(new ItemStack(missing_showAllTiers ? Items.coal : Items.diamond), x + 141, y + 107, tieredTooltip); } } - private static void drawString(int x, int y, String abc) { - Utils.drawStringCenteredScaledMaxWidth(abc, x + 40, y + 12, false, 70, gray()); - } - - private static boolean forceCC = false; - private static boolean forceAS = false; - private static boolean useGodPot = true; - private static boolean allowShaded = true; - private static int mainWeapon = 1; - - public static void renderOptimizerOverlay(int x, int y) { - Utils.drawStringCenteredScaledMaxWidth("Optimizer", x + 40, y + 12, false, 70, gray()); - - int light = new Color(220, 220, 220).getRGB(); - int dark = new Color(170, 170, 170).getRGB(); - - Gui.drawRect(x + 5, y + 32, x + 35, y + 43, forceCC ? dark : light); - Gui.drawRect(x + 45, y + 32, x + 75, y + 43, forceCC ? light : dark); - - Gui.drawRect(x + 5, y + 52, x + 35, y + 63, forceAS ? dark : light); - Gui.drawRect(x + 45, y + 52, x + 75, y + 63, forceAS ? light : dark); - - Gui.drawRect(x + 5, y + 72, x + 35, y + 83, useGodPot ? dark : light); - Gui.drawRect(x + 45, y + 72, x + 75, y + 83, useGodPot ? light : dark); - - Gui.drawRect(x + 5, y + 92, x + 35, y + 103, allowShaded ? dark : light); - Gui.drawRect(x + 45, y + 92, x + 75, y + 103, allowShaded ? light : dark); - - Gui.drawRect(x + 5, y + 102, x + 75, y + 113, light); - Gui.drawRect( - x + 5 + (int) ((mainWeapon - 1) / 9f * 70), - y + 102, - x + 5 + (int) (mainWeapon / 9f * 70), - y + 113, - dark - ); - - Utils.drawStringCenteredScaledMaxWidth("Force 100% CC", x + 40, y + 27, false, 70, gray()); - Utils.drawStringCenteredScaledMaxWidth( - (forceCC ? EnumChatFormatting.GREEN : EnumChatFormatting.GRAY) + "YES", x + 20, y + 37, true, 30, gray() - ); - Utils.drawStringCenteredScaledMaxWidth( - (forceCC ? EnumChatFormatting.GRAY : EnumChatFormatting.RED) + "NO", - x + 60, y + 37, true, 30, gray() - ); - - Utils.drawStringCenteredScaledMaxWidth("Force 100% ATKSPEED", x + 40, y + 47, false, 70, gray()); - Utils.drawStringCenteredScaledMaxWidth( - (forceAS ? EnumChatFormatting.GREEN : EnumChatFormatting.GRAY) + "YES", - x + 20, y + 57, true, 30, gray() - ); - Utils.drawStringCenteredScaledMaxWidth( - (forceAS ? EnumChatFormatting.GRAY : EnumChatFormatting.RED) + "NO", - x + 60, y + 57, true, 30, gray() - ); - - Utils.drawStringCenteredScaledMaxWidth("Use God Potion", x + 40, y + 67, false, 70, gray()); - Utils.drawStringCenteredScaledMaxWidth( - (useGodPot ? EnumChatFormatting.GREEN : EnumChatFormatting.GRAY) + "YES", - x + 20, y + 77, true, 30, gray() - ); - Utils.drawStringCenteredScaledMaxWidth( - (useGodPot ? EnumChatFormatting.GRAY : EnumChatFormatting.RED) + "NO", - x + 60, y + 77, true, 30, gray() - ); - - Utils.drawStringCenteredScaledMaxWidth("Use God Potion", x + 40, y + 87, false, 70, gray()); - Utils.drawStringCenteredScaledMaxWidth((allowShaded ? EnumChatFormatting.GREEN : EnumChatFormatting.GRAY) + "YES", - x + 20, y + 97, true, 30, gray() - ); - Utils.drawStringCenteredScaledMaxWidth((allowShaded ? EnumChatFormatting.GRAY : EnumChatFormatting.RED) + "NO", - x + 60, y + 97, - true, 30, gray() - ); - - Utils.drawStringCenteredScaledMaxWidth("Main Weapon", x + 40, y + 107, false, 70, gray()); - Utils.drawStringCenteredScaled("1 2 3 4 5 6 7 8 9", x + 40, y + 117, true, 70, gray()); + private static void drawTitle(int x, int y, String abc) { + Utils.drawStringCenteredScaledMaxWidth(abc, x + 84, y + 12, false, 158, gray()); } private static int gray() { return new Color(80, 80, 80).getRGB(); } - private static Comparator getItemComparator() { + private static Comparator getItemComparator(boolean accountMP) { return (o1, o2) -> { - double cost1; - JsonObject o1Auc = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(o1); - if (o1Auc != null && o1Auc.has("price")) { - cost1 = o1Auc.get("price").getAsFloat(); - } else { - APIManager.CraftInfo info = NotEnoughUpdates.INSTANCE.manager.auctionManager.getCraftCost(o1); - if (info != null) - cost1 = info.craftCost; - else - cost1 = -1; - } - double cost2; - JsonObject o2Auc = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(o2); - if (o2Auc != null && o2Auc.has("price")) { - cost2 = o2Auc.get("price").getAsFloat(); - } else { - APIManager.CraftInfo info = NotEnoughUpdates.INSTANCE.manager.auctionManager.getCraftCost(o2); - if (info != null) - cost2 = info.craftCost; - else - cost2 = -1; + double cost1 = getItemPrice(o1); + double cost2 = getItemPrice(o2); + if (accountMP) { + cost1 /= cost1 != -1 ? getMagicalPowerForItem(o1) : -1E-99; // Artificially push items with -1 price to the end + cost2 /= cost2 != -1 ? getMagicalPowerForItem(o2) : -1E-99; // since they would be put at the start otherwise } if (cost1 == -1 && cost2 == -1) return o1.compareTo(o2); @@ -730,7 +579,8 @@ public class AccessoryBagOverlay { public static void renderOverlay() { inAccessoryBag = false; - if (Minecraft.getMinecraft().currentScreen instanceof GuiChest && RenderListener.inventoryLoaded) { + offsetButtons = false; + if (Minecraft.getMinecraft().currentScreen instanceof GuiChest) { GuiChest eventGui = (GuiChest) Minecraft.getMinecraft().currentScreen; ContainerChest cc = (ContainerChest) eventGui.inventorySlots; String containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); @@ -738,10 +588,10 @@ public class AccessoryBagOverlay { !containerName.contains("Upgrades")) { inAccessoryBag = true; try { - int xSize = (int) Utils.getField(GuiContainer.class, eventGui, "xSize", "field_146999_f"); - int ySize = (int) Utils.getField(GuiContainer.class, eventGui, "ySize", "field_147000_g"); - int guiLeft = (int) Utils.getField(GuiContainer.class, eventGui, "guiLeft", "field_147003_i"); - int guiTop = (int) Utils.getField(GuiContainer.class, eventGui, "guiTop", "field_147009_r"); + AccessorGuiContainer accessor = (AccessorGuiContainer) Minecraft.getMinecraft().currentScreen; + int xSize = accessor.getXSize(); + int guiLeft = accessor.getGuiLeft(); + int guiTop = accessor.getGuiTop(); if (accessoryStacks.isEmpty()) { for (ItemStack stack : Minecraft.getMinecraft().thePlayer.inventory.mainInventory) { @@ -754,42 +604,40 @@ public class AccessoryBagOverlay { if (containerName.trim().contains("(")) { String first = containerName.trim().split("\\(")[1].split("/")[0]; Integer currentPageNumber = Integer.parseInt(first); - //System.out.println("current:"+currentPageNumber); - if (!pagesVisited.contains(currentPageNumber)) { - boolean hasStack = false; - if (Minecraft.getMinecraft().thePlayer.openContainer instanceof ContainerChest) { - IInventory inv = - ((ContainerChest) Minecraft.getMinecraft().thePlayer.openContainer).getLowerChestInventory(); - for (int i = 0; i < inv.getSizeInventory(); i++) { - ItemStack stack = inv.getStackInSlot(i); - if (stack != null) { - hasStack = true; - if (isAccessory(stack)) { - accessoryStacks.add(stack); + boolean hasStack = false; + if (Minecraft.getMinecraft().thePlayer.openContainer instanceof ContainerChest) { + IInventory inv = + ((ContainerChest) Minecraft.getMinecraft().thePlayer.openContainer).getLowerChestInventory(); + for (int i = 0; i < inv.getSizeInventory(); i++) { + ItemStack stack = inv.getStackInSlot(i); + if (stack != null) { + hasStack = true; + if (isAccessory(stack)) { + boolean toAdd = true; + for (ItemStack accessoryStack : accessoryStacks) { + String s = NEUManager.getUUIDForItem(accessoryStack); + + String ss = NEUManager.getUUIDForItem(stack); + if (ss != null && ss.equals(s)) { + toAdd = false; + break; + } } + if (toAdd) accessoryStacks.add(stack); } } } - - if (hasStack) pagesVisited.add(currentPageNumber); } + if (hasStack) pagesVisited.add(currentPageNumber); + String second = containerName.trim().split("/")[1].split("\\)")[0]; //System.out.println(second + ":" + pagesVisited.size()); if (Integer.parseInt(second) > pagesVisited.size()) { GlStateManager.color(1, 1, 1, 1); Minecraft.getMinecraft().getTextureManager().bindTexture(accessory_bag_overlay); - Utils.drawTexturedRect( - guiLeft + xSize + 3, - guiTop, - 80, - 149, - 0, - 80 / 256f, - 0, - 149 / 256f, - GL11.GL_NEAREST - ); + GlStateManager.disableLighting(); + Utils.drawTexturedRect(guiLeft + xSize + 4, guiTop, 168, 128, 0, 168 / 196f, 0, 1f, GL11.GL_NEAREST); renderVisitOverlay(guiLeft + xSize + 3, guiTop); return; @@ -814,103 +662,76 @@ public class AccessoryBagOverlay { } GlStateManager.disableLighting(); + offsetButtons = true; - for (int i = 0; i <= TAB_MISSING; i++) { - if (i != currentTab) { + for (int i = 0; i <= Tabs.values().length - 1; i++) { + if (i != currentTab.ordinal()) { GlStateManager.color(1, 1, 1, 1); Minecraft.getMinecraft().getTextureManager().bindTexture(accessory_bag_overlay); - Utils.drawTexturedRect(guiLeft + xSize + 80, guiTop + 20 * i, 25, 22, - 80 / 256f, 105 / 256f, 0, 22 / 256f, GL11.GL_NEAREST + Utils.drawTexturedRect(guiLeft + xSize + 168, guiTop + 20 * i, 25, 22, + 168 / 196f, 193f / 196f, 0f, 22 / 128f, GL11.GL_NEAREST ); - Utils.drawItemStack(TAB_STACKS[i], guiLeft + xSize + 80 + 5, guiTop + 20 * i + 3); + RenderHelper.enableGUIStandardItemLighting(); + Utils.drawItemStack(TAB_STACKS[i], guiLeft + xSize + 168 + 5, guiTop + 20 * i + 3); } } GlStateManager.color(1, 1, 1, 1); Minecraft.getMinecraft().getTextureManager().bindTexture(accessory_bag_overlay); - Utils.drawTexturedRect(guiLeft + xSize + 3, guiTop, 80, 149, 0, 80 / 256f, 0, 149 / 256f, GL11.GL_NEAREST); + Utils.drawTexturedRect(guiLeft + xSize + 4, guiTop, 168, 128, 0, 168 / 196f, 0, 1f, GL11.GL_NEAREST); - if (pagesVisited.size() < 1) { + if (pagesVisited.isEmpty()) { renderVisitOverlay(guiLeft + xSize + 3, guiTop); return; } Minecraft.getMinecraft().getTextureManager().bindTexture(accessory_bag_overlay); - Utils.drawTexturedRect(guiLeft + xSize + 80, guiTop + 20 * currentTab, 28, 22, - 80 / 256f, 108 / 256f, 22 / 256f, 44 / 256f, GL11.GL_NEAREST + Utils.drawTexturedRect(guiLeft + xSize + 168, guiTop + 20 * currentTab.ordinal(), 28, 22, + 168 / 196f, 1f, 22 / 128f, 44 / 128f, GL11.GL_NEAREST + ); + RenderHelper.enableGUIStandardItemLighting(); + Utils.drawItemStack( + TAB_STACKS[currentTab.ordinal()], + guiLeft + xSize + 168 + 8, + guiTop + 20 * currentTab.ordinal() + 3 ); - Utils.drawItemStack(TAB_STACKS[currentTab], guiLeft + xSize + 80 + 8, guiTop + 20 * currentTab + 3); + + fillDuplicates(); switch (currentTab) { case TAB_BASIC: renderBasicOverlay(guiLeft + xSize + 3, guiTop); - return; + break; case TAB_TOTAL: renderTotalStatsOverlay(guiLeft + xSize + 3, guiTop); - return; - case TAB_BONUS: - renderReforgeStatsOverlay(guiLeft + xSize + 3, guiTop); - return; + break; case TAB_DUP: renderDuplicatesOverlay(guiLeft + xSize + 3, guiTop); - return; + break; case TAB_MISSING: renderMissingOverlay(guiLeft + xSize + 3, guiTop); - return; - case TAB_OPTIMIZER: - renderOptimizerOverlay(guiLeft + xSize + 3, guiTop); - return; + } + if (dupe_highlight) { + highlightDuplicates(); } } catch (Exception e) { e.printStackTrace(); } + if (tooltipToDisplay != null) { + Utils.drawHoveringText(tooltipToDisplay, mouseX(), mouseY(), eventGui.width, eventGui.height, -1); + tooltipToDisplay = null; + } } } } - - - - private static final HashMap STAT_PATTERN_MAP_BONUS = new HashMap() {{ - String STAT_PATTERN_BONUS_END = ": (?:\\+|-)[0-9]+(?:\\.[0-9]+)?\\%? \\(((?:\\+|-)[0-9]+)%?"; - put("health", Pattern.compile("^Health" + STAT_PATTERN_BONUS_END)); - put("defence", Pattern.compile("^Defense" + STAT_PATTERN_BONUS_END)); - put("strength", Pattern.compile("^Strength" + STAT_PATTERN_BONUS_END)); - put("speed", Pattern.compile("^Speed" + STAT_PATTERN_BONUS_END)); - put("crit_chance", Pattern.compile("^Crit Chance" + STAT_PATTERN_BONUS_END)); - put("crit_damage", Pattern.compile("^Crit Damage" + STAT_PATTERN_BONUS_END)); - put("bonus_attack_speed", Pattern.compile("^Bonus Attack Speed" + STAT_PATTERN_BONUS_END)); - put("intelligence", Pattern.compile("^Intelligence" + STAT_PATTERN_BONUS_END)); - put("sea_creature_chance", Pattern.compile("^Sea Creature Chance" + STAT_PATTERN_BONUS_END)); - put("ferocity", Pattern.compile("^Ferocity" + STAT_PATTERN_BONUS_END)); - put("mining_fortune", Pattern.compile("^Mining Fortune" + STAT_PATTERN_BONUS_END)); - put("mining_speed", Pattern.compile("^Mining Speed" + STAT_PATTERN_BONUS_END)); - put("magic_find", Pattern.compile("^Magic Find" + STAT_PATTERN_BONUS_END)); - }}; - - private static final HashMap STAT_PATTERN_MAP = new HashMap() {{ - String STAT_PATTERN_END = ": ((?:\\+|-)([0-9]+(\\.[0-9]+)?))%?"; - put("health", Pattern.compile("^Health" + STAT_PATTERN_END)); - put("defence", Pattern.compile("^Defense" + STAT_PATTERN_END)); - put("strength", Pattern.compile("^Strength" + STAT_PATTERN_END)); - put("speed", Pattern.compile("^Speed" + STAT_PATTERN_END)); - put("crit_chance", Pattern.compile("^Crit Chance" + STAT_PATTERN_END)); - put("crit_damage", Pattern.compile("^Crit Damage" + STAT_PATTERN_END)); - put("bonus_attack_speed", Pattern.compile("^Bonus Attack Speed" + STAT_PATTERN_END)); - put("intelligence", Pattern.compile("^Intelligence" + STAT_PATTERN_END)); - put("sea_creature_chance", Pattern.compile("^Sea Creature Chance" + STAT_PATTERN_END)); - put("ferocity", Pattern.compile("^Ferocity" + STAT_PATTERN_END)); - put("mining_fortune", Pattern.compile("^Mining Fortune" + STAT_PATTERN_END)); - put("mining_speed", Pattern.compile("^Mining Speed" + STAT_PATTERN_END)); - put("magic_find", Pattern.compile("^Magic Find" + STAT_PATTERN_END)); - }}; - private static PlayerStats.Stats getStatForItem( ItemStack stack, HashMap patternMap, boolean addExtras ) { - String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(stack); + String internalname = + NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery().withItemStack(stack).resolveInternalName(); NBTTagCompound tag = stack.getTagCompound(); PlayerStats.Stats stats = new PlayerStats.Stats(); @@ -931,6 +752,20 @@ public class AccessoryBagOverlay { stats.addStat(entry.getKey(), bonus); } } + if (line.startsWith(EnumChatFormatting.GRAY + "Current Bonus: ")) { + for (Map.Entry entry : patternMap.entrySet()) { + String prettyStatName = Utils.cleanColour( + PlayerStats.defaultStatNamesPretty[Arrays + .asList(PlayerStats.defaultStatNames) + .indexOf(entry.getKey())]); + if (line.contains(prettyStatName)) { + float bonus = Float.parseFloat( + line.split(prettyStatName)[0] + .replaceAll("§7Current Bonus: §.", "")); + stats.addStat(entry.getKey(), bonus); + } + } + } } } } @@ -941,56 +776,9 @@ public class AccessoryBagOverlay { stats.addStat(PlayerStats.STRENGTH, 2.5f); stats.addStat(PlayerStats.DEFENCE, 2.5f); } - - if (internalname.equals("NEW_YEAR_CAKE_BAG") && tag != null && tag.hasKey("ExtraAttributes", 10)) { - NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); - - byte[] bytes = null; - for (String key : ea.getKeySet()) { - if (key.endsWith("backpack_data") || key.equals("new_year_cake_bag_data")) { - bytes = ea.getByteArray(key); - try { - NBTTagCompound contents_nbt = CompressedStreamTools.readCompressed(new ByteArrayInputStream(bytes)); - NBTTagList items = contents_nbt.getTagList("i", 10); - HashSet cakes = new HashSet<>(); - for (int j = 0; j < items.tagCount(); j++) { - if (items.getCompoundTagAt(j).getKeySet().size() > 0) { - NBTTagCompound nbt = items.getCompoundTagAt(j).getCompoundTag("tag"); - if (nbt != null && nbt.hasKey("ExtraAttributes", 10)) { - NBTTagCompound ea2 = nbt.getCompoundTag("ExtraAttributes"); - if (ea2.hasKey("new_years_cake")) { - cakes.add(ea2.getInteger("new_years_cake")); - } - } - } - } - stats.addStat(PlayerStats.HEALTH, cakes.size()); - } catch (IOException e) { - e.printStackTrace(); - return stats; - } - break; - } - } - } return stats; } - // private static String[] rarityArr = new String[] { - // "COMMON", "UNCOMMON", "RARE", "EPIC", "LEGENDARY", "MYTHIC", "SPECIAL", "VERY SPECIAL", "SUPREME" - // }; - // private static String[] rarityArrC = new String[] { - // EnumChatFormatting.WHITE+EnumChatFormatting.BOLD.toString()+"COMMON", - // EnumChatFormatting.GREEN+EnumChatFormatting.BOLD.toString()+"UNCOMMON", - // EnumChatFormatting.BLUE+EnumChatFormatting.BOLD.toString()+"RARE", - // EnumChatFormatting.DARK_PURPLE+EnumChatFormatting.BOLD.toString()+"EPIC", - // EnumChatFormatting.GOLD+EnumChatFormatting.BOLD.toString()+"LEGENDARY", - // EnumChatFormatting.LIGHT_PURPLE+EnumChatFormatting.BOLD.toString()+"MYTHIC", - // EnumChatFormatting.RED+EnumChatFormatting.BOLD.toString()+"SPECIAL", - // EnumChatFormatting.RED+EnumChatFormatting.BOLD.toString()+"VERY SPECIAL", - // EnumChatFormatting.DARK_RED+EnumChatFormatting.BOLD.toString()+"SUPREME", - // }; - public static int checkItemType(ItemStack stack, boolean contains, String... typeMatches) { NBTTagCompound tag = stack.getTagCompound(); if (tag != null) { @@ -1059,4 +847,241 @@ public class AccessoryBagOverlay { } return -1; } + + public static double getItemPrice(String internal) { + APIManager.CraftInfo info = NotEnoughUpdates.INSTANCE.manager.auctionManager.getCraftCost(internal); + double bin = NotEnoughUpdates.INSTANCE.manager.auctionManager.getLowestBin(internal); + if (info == null) return bin; + if (bin == -1) return info.craftCost; + return Math.min(info.craftCost, bin); + } + + public static ScaledResolution getScaledResolution() { + return new ScaledResolution(Minecraft.getMinecraft()); + } + + public static int mouseX() { + return Mouse.getX() / getScaledResolution().getScaleFactor(); + } + + public static int mouseY() { + return getScaledResolution().getScaledHeight() - Mouse.getY() / getScaledResolution().getScaleFactor(); + } + + public static int getMagicalPowerForItem(String internal) { + int abi = 0; + JsonObject jsonStack = NotEnoughUpdates.INSTANCE.manager.getJsonForItem( + NotEnoughUpdates.INSTANCE.manager. + createItemResolutionQuery(). + withKnownInternalName(internal). + resolveToItemStack()); + int rarity = Utils.getRarityFromLore(jsonStack.get("lore").getAsJsonArray()); + + if (internal.equals("HEGEMONY_ARTIFACT")) { + switch (rarity) { + case 4: + return 16; + case 5: + return 22; + } + } + + if (internal.contains("ABICASE")) { + abi = getAbiphoneMagicPower(); + } + + switch (rarity) { + case 0: + case 6: + return abi + 3; + case 1: + case 7: + return abi + 5; + case 2: + return abi + 8; + case 3: + return abi + 12; + case 4: + return abi + 16; + case 5: + return abi + 22; + } + + return 0; + } + + public static void renderButton(ItemStack stack, int x, int y, List tooltip) { + GlStateManager.color(1, 1, 1, 1); + Minecraft.getMinecraft().getTextureManager().bindTexture(accessory_bag_overlay); + GlStateManager.disableLighting(); + Utils.drawTexturedRect(x, y, 17, 17, 168f / 196f, 184f / 196f, 112f / 128f, 1f, GL11.GL_NEAREST); // slot + RenderHelper.enableGUIStandardItemLighting(); + Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI(stack, x, y); // item + if (new Rectangle(x, y, 16, 16).contains(mouseX(), mouseY())) { + Utils.drawHoveringText( + tooltip, + mouseX(), mouseY(), + getScaledResolution().getScaledWidth(), + getScaledResolution().getScaledHeight(), + -1 + ); + } + } + + public static void highlightDuplicates() { + AccessorGuiContainer accessor = (AccessorGuiContainer) Minecraft.getMinecraft().currentScreen; + int guiLeft = accessor.getGuiLeft(); + int guiTop = accessor.getGuiTop(); + + for (Slot slot : Minecraft.getMinecraft().thePlayer.openContainer.inventorySlots) { + ItemStack stack = slot.getStack(); + if (stack != null && isAccessory(stack)) { + if (!dupe_showPersonal && NotEnoughUpdates.INSTANCE.manager + .createItemResolutionQuery() + .withItemStack(stack) + .resolveInternalName() + .matches("PERSONAL_(DELETOR|COMPACTOR)_[0-9]+")) continue; + if (duplicates != null && duplicates + .stream() + .map(ItemStack::getDisplayName) + .collect(Collectors.toList()) + .contains(stack.getDisplayName())) { + GlStateManager.translate(0, 0, 50); + GuiScreen.drawRect( + guiLeft + slot.xDisplayPosition, + guiTop + slot.yDisplayPosition, + guiLeft + slot.xDisplayPosition + 16, + guiTop + slot.yDisplayPosition + 16, + 0xBBFF0000 + ); + GlStateManager.translate(0, 0, -50); + } + } + } + } + + public static void fillDuplicates() { + if (duplicates != null) return; + JsonObject misc = Constants.MISC; + JsonElement talisman_upgrades_element = misc.get("talisman_upgrades"); + if (talisman_upgrades_element == null) { + Utils.showOutdatedRepoNotification("misc.json talisman_upgrades"); + return; + } + JsonObject talisman_upgrades = talisman_upgrades_element.getAsJsonObject(); + + duplicates = new HashSet<>(); + ArrayList duplicatesIDs = new ArrayList<>(); + + Set prevInternalnames = new HashSet<>(); + for (ItemStack stack : accessoryStacks) { + String internalname = + NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery().withItemStack(stack).resolveInternalName(); + + if (prevInternalnames.contains(internalname)) { + duplicates.add(stack); + duplicatesIDs.add(internalname); + continue; + } + prevInternalnames.add(internalname); + + if (talisman_upgrades.has(internalname)) { + JsonArray upgrades = talisman_upgrades.get(internalname).getAsJsonArray(); + for (ItemStack stack2 : accessoryStacks) { + if (stack != stack2) { + String internalname2 = NotEnoughUpdates.INSTANCE.manager + .createItemResolutionQuery() + .withItemStack(stack2) + .resolveInternalName(); + boolean toAdd = false; + ArrayList upgradeIDs = new ArrayList<>(); + for (int j = 0; j < upgrades.size(); j++) { + String upgrade = upgrades.get(j).getAsString(); + upgradeIDs.add(upgrade); + if (internalname2.equals(upgrade)) { + duplicates.add(stack); + toAdd = true; + } + } + if (toAdd) duplicatesIDs.addAll(upgradeIDs); + } + } + } + } + for (ItemStack accessoryStack : accessoryStacks) { + String internalID = NotEnoughUpdates.INSTANCE.manager + .createItemResolutionQuery() + .withItemStack(accessoryStack) + .resolveInternalName(); + if (duplicatesIDs.contains(internalID)) { + duplicates.add(accessoryStack); + } + } + } + + public static void renderAccessoryHover(Rectangle rect, ItemStack stack) { + if (rect.contains(mouseX(), mouseY())) { + String internal = NotEnoughUpdates.INSTANCE.manager + .createItemResolutionQuery() + .withItemStack(stack) + .resolveInternalName(); + tooltipToDisplay = Arrays.asList( + stack.getDisplayName().replace("*", ""), + "", + "§eClick to learn more!", + "§eCtrl+Click to search on ah!" + ); + handleAccessoryClick(stack, internal); + } + } + + public static void handleAccessoryClick(ItemStack stack, String internal) { + if (Mouse.isButtonDown(0) && internal != null) { + if (!Keyboard.isKeyDown(Keyboard.KEY_LCONTROL)) { + if (!NotEnoughUpdates.INSTANCE.manager.displayGuiItemRecipe(internal)) { + NEUOverlay.getTextField().setText("id:" + internal); + NotEnoughUpdates.INSTANCE.overlay.updateSearch(); + NotEnoughUpdates.INSTANCE.overlay.setSearchBarFocus(true); + } + } else { + String displayname = Utils.cleanColour(stack.getDisplayName()); + NotEnoughUpdates.INSTANCE.trySendCommand("/ahs " + displayname.replace("*", "")); + } + } + } + + public static boolean hasConsumedRiftPrism() { + NEUConfig.HiddenProfileSpecific profileSpecific = NotEnoughUpdates.INSTANCE.config.getProfileSpecific(); + if (profileSpecific == null) return false; + try { + JsonObject profileInfo = GuiProfileViewer.getSelectedProfile().getProfileJson(); + if (profileInfo.has("rift") && profileInfo.getAsJsonObject("rift").has("access")) { + profileSpecific.hasConsumedRiftPrism = profileInfo.getAsJsonObject( + "rift").getAsJsonObject("access").has("consumed_prism"); + } + } catch (NullPointerException ignored) { + } + return profileSpecific.hasConsumedRiftPrism; + } + + public static int getAbiphoneMagicPower() { + NEUConfig.HiddenProfileSpecific profileSpecific = NotEnoughUpdates.INSTANCE.config.getProfileSpecific(); + if (profileSpecific == null) return 0; + try { + JsonObject profileInfo = GuiProfileViewer.getSelectedProfile().getProfileJson(); + if (profileInfo.has("nether_island_player_data")) { + JsonObject data = profileInfo.get("nether_island_player_data").getAsJsonObject(); + if (data.has("abiphone") && data.get("abiphone").getAsJsonObject().has("active_contacts")) { // BatChest + int contact = data.get("abiphone").getAsJsonObject().get("active_contacts").getAsJsonArray().size(); + profileSpecific.abiphoneMagicPower = contact / 2; + } + } + } catch (NullPointerException ignored) { + } + return profileSpecific.abiphoneMagicPower; + } + + private static void playPressSound() { + if (NotEnoughUpdates.INSTANCE.config.misc.guiButtonClicks) Utils.playPressSound(); + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java index 7132c5f8..297a8afb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 NotEnoughUpdates contributors + * Copyright (C) 2022-2024 NotEnoughUpdates contributors * * This file is part of NotEnoughUpdates. * @@ -722,6 +722,13 @@ public class NEUConfig extends Config { @Expose public Map hotmTree = new HashMap<>(); + + @Expose + public boolean hasConsumedRiftPrism = false; + + @Expose + public int abiphoneMagicPower = 0; + } public HiddenLocationSpecific getLocationSpecific() { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java index 2b8ebf12..301acbc3 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 NotEnoughUpdates contributors + * Copyright (C) 2022-2024 NotEnoughUpdates contributors * * This file is part of NotEnoughUpdates. * @@ -47,70 +47,231 @@ import java.util.regex.Pattern; public class PlayerStats { + // Combat stats public static final String HEALTH = "health"; public static final String DEFENCE = "defence"; public static final String STRENGTH = "strength"; - public static final String SPEED = "speed"; + public static final String INTELLIGENCE = "intelligence"; public static final String CRIT_CHANCE = "crit_chance"; public static final String CRIT_DAMAGE = "crit_damage"; public static final String BONUS_ATTACK_SPEED = "bonus_attack_speed"; - public static final String INTELLIGENCE = "intelligence"; - public static final String SEA_CREATURE_CHANCE = "sea_creature_chance"; + public static final String ABILITY_DAMAGE = "ability_damage"; + public static final String TRUE_DEFENSE = "true_defense"; + public static final String FEROCITY = "ferocity"; + public static final String HEALTH_REGEN = "health_regen"; + public static final String VITALITY = "vitality"; + public static final String MENDING = "mending"; + public static final String SWING_RANGE = "swing_range"; + + // Gathering stats + public static final String MINING_SPEED = "mining_speed"; + public static final String MINING_FORTUNE = "mining_fortune"; + public static final String FARMING_FORTUNE = "farming_fortune"; + public static final String FORAGING_FORTUNE = "foraging_fortune"; + public static final String BREAKING_POWER = "breaking_power"; + public static final String PRISTINE = "pristine"; + public static final String WHEAT_FORTUNE = "wheat_fortune"; + public static final String CARROT_FORTUNE = "carrot_fortune"; + public static final String POTATO_FORTUNE = "potato_fortune"; + public static final String PUMPKIN_FORTUNE = "pumpkin_fortune"; + public static final String MELON_FORTUNE = "melon_fortune"; + public static final String MUSHROOM_FORTUNE = "mushroom_fortune"; + public static final String CACTUS_FORTUNE = "cactus_fortune"; + public static final String SUGAR_CANE_FORTUNE = "sugar_cane_fortune"; + public static final String NETHER_WART_FORTUNE = "nether_wart_fortune"; + public static final String COCOA_BEANS_FORTUNE = "cocoa_beans_fortune"; + + // Wisdom stats + public static final String COMBAT_WISDOM = "combat_wisdom"; + public static final String MINING_WISDOM = "mining_wisdom"; + public static final String FARMING_WISDOM = "farming_wisdom"; + public static final String FORAGING_WISDOM = "foraging_wisdom"; + public static final String FISHING_WISDOM = "fishing_wisdom"; + public static final String ENCHANTING_WISDOM = "enchanting_wisdom"; + public static final String ALCHEMY_WISDOM = "alchemy_wisdom"; + public static final String CARPENTRY_WISDOM = "carpentry_wisdom"; + public static final String RUNECRAFTING_WISDOM = "runecrafting_wisdom"; + public static final String SOCIAL_WISDOM = "social_wisdom"; + public static final String TAMING_WISDOM = "taming_wisdom"; + + // Misc stats + public static final String SPEED = "speed"; public static final String MAGIC_FIND = "magic_find"; public static final String PET_LUCK = "pet_luck"; - public static final String MINING_FORTUNE = "mining_fortune"; - public static final String MINING_SPEED = "mining_speed"; - - public static final String[] defaultStatNames = new String[] { - "health", - "defence", - "strength", - "speed", - "crit_chance", - "crit_damage", - "bonus_attack_speed", - "intelligence", - "sea_creature_chance", - "magic_find", - "pet_luck", - "ferocity", - "ability_damage", - "mining_fortune", - "mining_speed", + public static final String SEA_CREATURE_CHANCE = "sea_creature_chance"; + public static final String DOUBLE_HOOK_CHANCE = "double_hook_chance"; + public static final String FISHING_SPEED = "fishing_speed"; + public static final String COLD_RESISTANCE = "cold_resistance"; + public static final String BONUS_PEST_CHANCE = "bonus_pest_chance"; + + public static final String[] defaultStatNames = new String[]{ + HEALTH, + DEFENCE, + STRENGTH, + INTELLIGENCE, + CRIT_CHANCE, + CRIT_DAMAGE, + BONUS_ATTACK_SPEED, + ABILITY_DAMAGE, + TRUE_DEFENSE, + FEROCITY, + HEALTH_REGEN, + VITALITY, + MENDING, + SWING_RANGE, + + MINING_SPEED, + MINING_FORTUNE, + FARMING_FORTUNE, + FORAGING_FORTUNE, + BREAKING_POWER, + PRISTINE, + WHEAT_FORTUNE, + CARROT_FORTUNE, + POTATO_FORTUNE, + PUMPKIN_FORTUNE, + MELON_FORTUNE, + MUSHROOM_FORTUNE, + CACTUS_FORTUNE, + SUGAR_CANE_FORTUNE, + NETHER_WART_FORTUNE, + COCOA_BEANS_FORTUNE, + + COMBAT_WISDOM, + MINING_WISDOM, + FARMING_WISDOM, + FORAGING_WISDOM, + FISHING_WISDOM, + ENCHANTING_WISDOM, + ALCHEMY_WISDOM, + CARPENTRY_WISDOM, + RUNECRAFTING_WISDOM, + SOCIAL_WISDOM, + TAMING_WISDOM, + + SPEED, + MAGIC_FIND, + PET_LUCK, + SEA_CREATURE_CHANCE, + DOUBLE_HOOK_CHANCE, + FISHING_SPEED, + COLD_RESISTANCE, + BONUS_PEST_CHANCE, }; - public static final String[] defaultStatNamesPretty = new String[] { - EnumChatFormatting.RED + "\u2764 Health", - EnumChatFormatting.GREEN + "\u2748 Defence", - EnumChatFormatting.RED + "\u2741 Strength", - EnumChatFormatting.WHITE + "\u2726 Speed", - EnumChatFormatting.BLUE + "\u2623 Crit Chance", - EnumChatFormatting.BLUE + "\u2620 Crit Damage", - EnumChatFormatting.YELLOW + "\u2694 Attack Speed", - EnumChatFormatting.AQUA + "\u270e Intelligence", - EnumChatFormatting.DARK_AQUA + "\u03b1 SC Chance", - EnumChatFormatting.AQUA + "\u272f Magic Find", - EnumChatFormatting.LIGHT_PURPLE + "\u2663 Pet Luck", - EnumChatFormatting.RED + "\u2AFD Ferocity", - EnumChatFormatting.RED + "\u2739 Ability Damage", - EnumChatFormatting.GOLD + "\u2618 Mining Fortune", - EnumChatFormatting.GOLD + "\u2E15 Mining Speed", + public static final String[] defaultStatNamesPretty = new String[]{ + EnumChatFormatting.RED + "❤ Health", + EnumChatFormatting.GREEN + "❈ Defence", + EnumChatFormatting.RED + "❁ Strength", + EnumChatFormatting.AQUA + "✎ Intelligence", + EnumChatFormatting.BLUE + "☣ Crit Chance", + EnumChatFormatting.BLUE + "☠ Crit Damage", + EnumChatFormatting.YELLOW + "⚔ Bonus Attack Speed", + EnumChatFormatting.RED + "๑ Ability Damage", + EnumChatFormatting.WHITE + "❂ True Defense", + EnumChatFormatting.RED + "⫽ Ferocity", + EnumChatFormatting.RED + "❣ Health Regen", + EnumChatFormatting.DARK_RED + "♨ Vitality", + EnumChatFormatting.GREEN + "☄ Mending", + EnumChatFormatting.YELLOW + "Ⓢ Swing Range", + + EnumChatFormatting.GOLD + "⸕ Mining Speed", + EnumChatFormatting.GOLD + "☘ Mining Fortune", + EnumChatFormatting.GOLD + "☘ Farming Fortune", + EnumChatFormatting.GOLD + "☘ Foraging Fortune", + EnumChatFormatting.DARK_GREEN + "Ⓟ Breaking Power", + EnumChatFormatting.DARK_PURPLE + "✧ Pristine", + EnumChatFormatting.GOLD + "☘ Wheat Fortune", + EnumChatFormatting.GOLD + "☘ Carrot Fortune", + EnumChatFormatting.GOLD + "☘ Potato Fortune", + EnumChatFormatting.GOLD + "☘ Pumpkin Fortune", + EnumChatFormatting.GOLD + "☘ Melon Fortune", + EnumChatFormatting.GOLD + "☘ Mushroom Fortune", + EnumChatFormatting.GOLD + "☘ Cactus Fortune", + EnumChatFormatting.GOLD + "☘ Sugar Cane Fortune", + EnumChatFormatting.GOLD + "☘ Nether Wart Fortune", + EnumChatFormatting.GOLD + "☘ Cocoa Beans Fortune", + + EnumChatFormatting.DARK_AQUA + "☯ Combat Wisdom", + EnumChatFormatting.DARK_AQUA + "☯ Mining Wisdom", + EnumChatFormatting.DARK_AQUA + "☯ Farming Wisdom", + EnumChatFormatting.DARK_AQUA + "☯ Foraging Wisdom", + EnumChatFormatting.DARK_AQUA + "☯ Fishing Wisdom", + EnumChatFormatting.DARK_AQUA + "☯ Enchanting Wisdom", + EnumChatFormatting.DARK_AQUA + "☯ Alchemy Wisdom", + EnumChatFormatting.DARK_AQUA + "☯ Carpentry Wisdom", + EnumChatFormatting.DARK_AQUA + "☯ Runecrafting Wisdom", + EnumChatFormatting.DARK_AQUA + "☯ Social Wisdom", + EnumChatFormatting.DARK_AQUA + "☯ Taming Wisdom", + + EnumChatFormatting.WHITE + "✦ Speed", + EnumChatFormatting.AQUA + "✯ Magic Find", + EnumChatFormatting.LIGHT_PURPLE + "♣ Pet Luck", + EnumChatFormatting.DARK_AQUA + "α Sea Creature Chance", + EnumChatFormatting.BLUE + "⚓ Double Hook Chance", + EnumChatFormatting.AQUA + "☂ Fishing Speed", + EnumChatFormatting.AQUA + "❄ Cold Resistance", + EnumChatFormatting.DARK_GREEN + "ൠ Bonus Pest Chance" }; - private static final HashMap STAT_PATTERN_MAP = new HashMap() { + + public static final HashMap STAT_PATTERN_MAP = new HashMap() { { - put(HEALTH, Pattern.compile("^Health: ((?:\\