From f29ebcc6cdf202a69f267a4dbdbfc9239929fd8a Mon Sep 17 00:00:00 2001 From: Lulonaut <67191924+Lulonaut@users.noreply.github.com> Date: Sun, 20 Mar 2022 08:47:29 +0100 Subject: dungeons and pv bingo tab (#93) --- .../moulberry/notenoughupdates/NEUOverlay.java | 3 +- .../commands/profile/CataCommand.java | 2 +- .../annotations/ConfigEditorDraggableList.java | 1 + .../config/gui/GuiOptionEditorDraggableList.java | 25 +- .../core/config/struct/ConfigProcessor.java | 2 +- .../notenoughupdates/dungeons/DungeonMap.java | 41 +- .../notenoughupdates/dungeons/DungeonWin.java | 7 +- .../miscfeatures/AuctionBINWarning.java | 48 +- .../notenoughupdates/options/NEUConfig.java | 16 +- .../options/seperateSections/AHTweaks.java | 17 +- .../options/seperateSections/Misc.java | 10 +- .../options/seperateSections/ProfileViewer.java | 63 + .../notenoughupdates/overlays/FarmingOverlay.java | 15 +- .../notenoughupdates/profileviewer/BingoPage.java | 309 +++++ .../profileviewer/GuiProfileViewer.java | 1343 ++++++++++++-------- .../profileviewer/ProfileViewer.java | 377 +++--- .../notenoughupdates/util/HypixelApi.java | 9 +- .../moulberry/notenoughupdates/util/SBInfo.java | 2 +- .../notenoughupdates/invbuttons/presets.json | 3 +- .../assets/notenoughupdates/pv_bingo_tab.png | Bin 0 -> 2635 bytes 20 files changed, 1475 insertions(+), 818 deletions(-) create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java create mode 100644 src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java create mode 100644 src/main/resources/assets/notenoughupdates/pv_bingo_tab.png (limited to 'src/main') diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index d9566f0d..5ad02f94 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -1361,7 +1361,8 @@ public class NEUOverlay extends Gui { "DUNGEON SWORD", "DUNGEON BOW", "DRILL", - "GAUNTLET" + "GAUNTLET", + "LONGSWORD" ) >= 0; } else if (getSortMode() == SORT_MODE_ARMOR) { return checkItemType( diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/CataCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/CataCommand.java index 09253e50..ccf72d73 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/CataCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/CataCommand.java @@ -11,7 +11,7 @@ public class CataCommand extends ViewProfileCommand { @Override public void processCommand(ICommandSender sender, String[] args) { - GuiProfileViewer.currentPage = GuiProfileViewer.ProfileViewerPage.DUNG; + GuiProfileViewer.currentPage = GuiProfileViewer.ProfileViewerPage.DUNGEON; super.processCommand(sender, args); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java index e171e0ae..5063d543 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java @@ -9,4 +9,5 @@ import java.lang.annotation.Target; @Target(ElementType.FIELD) public @interface ConfigEditorDraggableList { String[] exampleText(); + boolean allowRemovingElements() default true; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java index 08a1024f..df373dbf 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java @@ -24,6 +24,7 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor { private static final ResourceLocation DELETE = new ResourceLocation("notenoughupdates:core/delete.png"); private final String[] exampleText; + private final boolean allowRemovingElements; private final List activeText; private int currentDragging = -1; private int dragStartIndex = -1; @@ -35,9 +36,14 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor { private boolean dropdownOpen = false; - public GuiOptionEditorDraggableList(ConfigProcessor.ProcessedOption option, String[] exampleText) { + public GuiOptionEditorDraggableList( + ConfigProcessor.ProcessedOption option, + String[] exampleText, + boolean allowRemovingElements + ) { super(option); + this.allowRemovingElements = allowRemovingElements; this.exampleText = exampleText; this.activeText = (List) option.get(); } @@ -77,8 +83,11 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor { float greenBlue = LerpUtils.clampZeroOne((250 + trashHoverTime - currentTime) / 250f); GlStateManager.color(1, greenBlue, greenBlue, 1); } - Minecraft.getMinecraft().getTextureManager().bindTexture(DELETE); - Utils.drawTexturedRect(x + width / 6 + 27, y + 45 - 7 - 13, 11, 14, GL11.GL_NEAREST); + + if (allowRemovingElements) { + Minecraft.getMinecraft().getTextureManager().bindTexture(DELETE); + Utils.drawTexturedRect(x + width / 6 + 27, y + 45 - 7 - 13, 11, 14, GL11.GL_NEAREST); + } Gui.drawRect(x + 5, y + 45, x + width - 5, y + height - 5, 0xffdddddd); Gui.drawRect(x + 6, y + 46, x + width - 6, y + height - 6, 0xff000000); @@ -206,7 +215,9 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor { dragStartIndex >= 0 && Mouse.getEventButton() == 0 && mouseX >= x + width / 6 + 27 - 3 && mouseX <= x + width / 6 + 27 + 11 + 3 && mouseY >= y + 45 - 7 - 13 - 3 && mouseY <= y + 45 - 7 - 13 + 14 + 3) { - activeText.remove(dragStartIndex); + if (allowRemovingElements) { + activeText.remove(dragStartIndex); + } currentDragging = -1; dragStartIndex = -1; return false; @@ -215,13 +226,13 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor { if (!Mouse.isButtonDown(0) || dropdownOpen) { currentDragging = -1; dragStartIndex = -1; - if (trashHoverTime > 0) trashHoverTime = -System.currentTimeMillis(); + if (trashHoverTime > 0 && allowRemovingElements) trashHoverTime = -System.currentTimeMillis(); } else if (currentDragging >= 0 && mouseX >= x + width / 6 + 27 - 3 && mouseX <= x + width / 6 + 27 + 11 + 3 && mouseY >= y + 45 - 7 - 13 - 3 && mouseY <= y + 45 - 7 - 13 + 14 + 3) { - if (trashHoverTime < 0) trashHoverTime = System.currentTimeMillis(); + if (trashHoverTime < 0 && allowRemovingElements) trashHoverTime = System.currentTimeMillis(); } else { - if (trashHoverTime > 0) trashHoverTime = -System.currentTimeMillis(); + if (trashHoverTime > 0 && allowRemovingElements) trashHoverTime = -System.currentTimeMillis(); } if (Mouse.getEventButtonState()) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java index b5aa6ba8..3eb8a2d1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java @@ -147,7 +147,7 @@ public class ConfigProcessor { if (optionField.isAnnotationPresent(ConfigEditorDraggableList.class)) { ConfigEditorDraggableList configEditorAnnotation = optionField.getAnnotation(ConfigEditorDraggableList.class); - editor = new GuiOptionEditorDraggableList(option, configEditorAnnotation.exampleText()); + editor = new GuiOptionEditorDraggableList(option, configEditorAnnotation.exampleText(), configEditorAnnotation.allowRemovingElements()); } } if (optionType.isAssignableFrom(String.class)) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java index 592f5b19..e132d287 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java @@ -578,8 +578,8 @@ public class DungeonMap { GlStateManager.rotate(-rotation + 180, 0, 0, 1); if (NotEnoughUpdates.INSTANCE.config.dungeonMap.dmCenterPlayer && playerPos != null) { - float x = playerPos.getRenderX(); - float y = playerPos.getRenderY(); + float x = playerPos.getRenderX(0); + float y = playerPos.getRenderY(0); x -= minRoomX * (renderRoomSize + renderConnSize); y -= minRoomY * (renderRoomSize + renderConnSize); @@ -648,8 +648,8 @@ public class DungeonMap { for (Map.Entry entry : playerMarkerMapPositions.entrySet()) { String name = entry.getKey(); MapPosition pos = entry.getValue(); - float x = pos.getRenderX(); - float y = pos.getRenderY(); + float x = pos.getRenderX(0); + float y = pos.getRenderY(0); float angle = pos.rotation; boolean doInterp = NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPlayerInterp; @@ -657,19 +657,8 @@ public class DungeonMap { MapPosition entityPos = playerEntityMapPositions.get(name); angle = entityPos.rotation; - float deltaX = entityPos.getRenderX() - pos.getRenderX(); - float deltaY = entityPos.getRenderY() - pos.getRenderY(); - - /*if(deltaX > (renderRoomSize + renderConnSize)/2) { - deltaX -= (renderRoomSize + renderConnSize); - } else if(deltaX < -(renderRoomSize + renderConnSize)/2) { - deltaX += (renderRoomSize + renderConnSize); - } - if(deltaY > (renderRoomSize + renderConnSize)/2) { - deltaY -= (renderRoomSize + renderConnSize); - } else if(deltaY < -(renderRoomSize + renderConnSize)/2) { - deltaY += (renderRoomSize + renderConnSize); - }*/ + float deltaX = entityPos.getRenderX(9) - pos.getRenderX(0); + float deltaY = entityPos.getRenderY(9) - pos.getRenderY(0); x += deltaX; y += deltaY; @@ -689,8 +678,8 @@ public class DungeonMap { if (doInterp && playerMarkerMapPositionsLast.containsKey(name)) { MapPosition last = playerMarkerMapPositionsLast.get(name); - float xLast = last.getRenderX(); - float yLast = last.getRenderY(); + float xLast = last.getRenderX(0); + float yLast = last.getRenderY(0); float distSq = (x - xLast) * (x - xLast) + (y - yLast) * (y - yLast); if (distSq < renderRoomSize * renderRoomSize / 4f) { @@ -1087,12 +1076,12 @@ public class DungeonMap { this.connOffsetY = connOffsetY; } - public float getRenderX() { - return roomOffsetX * getRenderRoomSize() + connOffsetX * getRenderConnSize(); + public float getRenderX(int blockOffset) { + return (roomOffsetX + blockOffset) * getRenderRoomSize() + connOffsetX * getRenderConnSize(); } - public float getRenderY() { - return roomOffsetY * getRenderRoomSize() + connOffsetY * getRenderConnSize(); + public float getRenderY(int blockOffset) { + return (roomOffsetY + blockOffset) * getRenderRoomSize() + connOffsetY * getRenderConnSize(); } @Override @@ -1153,7 +1142,7 @@ public class DungeonMap { String line = ScorePlayerTeam.formatPlayerName(scoreplayerteam1, score.getPlayerName()); line = Utils.cleanColour(line); - if (line.contains("(F1)") || line.contains("(E0)") || line.contains("(M1)")) { + if (line.contains("(F1)") || line.contains("(E)") || line.contains("(M1)")) { isFloorOne = true; break; } @@ -1425,8 +1414,8 @@ public class DungeonMap { for (Map.Entry entry : playerMarkerMapPositionsLast.entrySet()) { HashMap deltaDists = new HashMap<>(); for (int i = 0; i < positions.size(); i++) { - float dx = entry.getValue().getRenderX() - positions.get(i).getRenderX(); - float dy = entry.getValue().getRenderY() - positions.get(i).getRenderY(); + float dx = entry.getValue().getRenderX(0) - positions.get(i).getRenderX(0); + float dy = entry.getValue().getRenderY(0) - positions.get(i).getRenderY(0); deltaDists.put(i, dx * dx + dy * dy); } distanceMap.put(entry.getKey(), deltaDists); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonWin.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonWin.java index 976dfcf8..66389beb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonWin.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonWin.java @@ -200,7 +200,12 @@ public class DungeonWin { displayWin(); } else { if (unformatted.trim().length() > 0) { - text.add(e.message.getFormattedText().substring(6).trim()); + if (unformatted.contains("The Catacombs") || unformatted.contains("Master Mode Catacombs") || unformatted.contains("Team Score") || unformatted.contains("Defeated") || unformatted.contains("Total Damage") + || unformatted.contains("Ally Healing") || unformatted.contains("Enemies Killed") || unformatted.contains("Deaths") || unformatted.contains("Secrets Found")) { + text.add(e.message.getFormattedText().substring(6).trim()); + } else { + System.out.println("These messages would of showed on neu dungeon overlay but didnt, They are either bugged or i missed them: \"" + e.message.getFormattedText().substring(6).trim() + "\""); + } } } } else { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java index c76a22b4..c7bcc0e1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/AuctionBINWarning.java @@ -37,6 +37,7 @@ public class AuctionBINWarning extends GuiElement { private String sellingName; private int sellingPrice; private int lowestPrice; + private int sellStackAmount; private boolean shouldPerformCheck() { if (!NotEnoughUpdates.INSTANCE.config.ahTweaks.enableBINWarning || @@ -83,6 +84,7 @@ public class AuctionBINWarning extends GuiElement { ItemStack sellStack = chest.inventorySlots.getSlot(13).getStack(); String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(sellStack); + sellStackAmount = sellStack.stackSize; if (internalname == null) { return false; @@ -105,13 +107,17 @@ public class AuctionBINWarning extends GuiElement { lowestPrice = (int) NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAvgBin(internalname); } - //TODO: Add option for warning if lowest price does not exist - - float factor = 1 - NotEnoughUpdates.INSTANCE.config.ahTweaks.warningThreshold / 100; - if (factor < 0) factor = 0; - if (factor > 1) factor = 1; - - if (sellingPrice > 0 && lowestPrice > 0 && sellingPrice < lowestPrice * factor) { + float undercutFactor = 1 - NotEnoughUpdates.INSTANCE.config.ahTweaks.warningThreshold / 100; + if (undercutFactor < 0) undercutFactor = 0; + if (undercutFactor > 1) undercutFactor = 1; + float overcutFactor = 1 + NotEnoughUpdates.INSTANCE.config.ahTweaks.overcutWarningThreshold / 100; + if (overcutFactor < 0) overcutFactor = 0; + + if ( + (sellingPrice > 0 && lowestPrice > 0 && + ((sellingPrice > sellStackAmount * lowestPrice * overcutFactor) || + sellingPrice < sellStackAmount * lowestPrice * undercutFactor)) + || lowestPrice == -1) { showWarning = true; return true; } else { @@ -155,10 +161,10 @@ public class AuctionBINWarning extends GuiElement { ); String lowestPriceStr; - if (lowestPrice > 999) { - lowestPriceStr = Utils.shortNumberFormat(lowestPrice, 0); + if (lowestPrice * sellStackAmount > 999) { + lowestPriceStr = Utils.shortNumberFormat(lowestPrice * sellStackAmount, 0); } else { - lowestPriceStr = "" + lowestPrice; + lowestPriceStr = "" + lowestPrice * sellStackAmount; } String sellingPriceStr; @@ -174,7 +180,9 @@ public class AuctionBINWarning extends GuiElement { width / 2, height / 2 - 45 + 25, false, 170, 0xffffffff ); TextRenderUtils.drawStringCenteredScaledMaxWidth( - "has a lowest BIN of \u00a76" + lowestPriceStr + "\u00a7r coins", + (lowestPrice > 0 + ? "has a lowest BIN of \u00a76" + lowestPriceStr + "\u00a7r coins" + : "\u00a7cWarning: No lowest BIN found!"), Minecraft.getMinecraft().fontRendererObj, width / 2, height / 2 - 45 + 34, @@ -183,8 +191,15 @@ public class AuctionBINWarning extends GuiElement { 0xffa0a0a0 ); - int buyPercentage = 100 - sellingPrice * 100 / lowestPrice; - if (buyPercentage <= 0) buyPercentage = 1; + boolean isALoss = false; + int buyPercentage = 0; + if (sellingPrice > lowestPrice * sellStackAmount) { + buyPercentage = sellingPrice * 100 / (lowestPrice * sellStackAmount) - 100; + isALoss = false; + } else if (sellingPrice < lowestPrice * sellStackAmount) { + buyPercentage = 100 - sellingPrice * 100 / (lowestPrice * sellStackAmount); + isALoss = true; + } TextRenderUtils.drawStringCenteredScaledMaxWidth( "Continue selling it for", @@ -196,7 +211,10 @@ public class AuctionBINWarning extends GuiElement { 0xffa0a0a0 ); TextRenderUtils.drawStringCenteredScaledMaxWidth( - "\u00a76" + sellingPriceStr + "\u00a7r coins? (\u00a7c-" + buyPercentage + "%\u00a7r)", + "\u00a76" + sellingPriceStr + "\u00a7r coins?" + + ((lowestPrice > 0 && buyPercentage > 0) + ? "(\u00a7" + (isALoss ? "c-" : "a+") + buyPercentage + "%\u00a7r)" + : ""), Minecraft.getMinecraft().fontRendererObj, width / 2, height / 2 - 45 + 59, @@ -218,7 +236,7 @@ public class AuctionBINWarning extends GuiElement { 0xff00ff00 ); TextRenderUtils.drawStringCenteredScaledMaxWidth( - EnumChatFormatting.RED + "[n]o", + EnumChatFormatting.RED + "[N]o", Minecraft.getMinecraft().fontRendererObj, width / 2 + 23, height / 2 + 31, 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 1d03a2d1..25c47fce 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/NEUConfig.java @@ -12,20 +12,20 @@ import io.github.moulberry.notenoughupdates.miscgui.GuiEnchantColour; import io.github.moulberry.notenoughupdates.miscgui.GuiInvButtonEditor; import io.github.moulberry.notenoughupdates.miscgui.NEUOverlayPlacements; import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag; -import io.github.moulberry.notenoughupdates.options.seperateSections.AccessoryBag; import io.github.moulberry.notenoughupdates.options.seperateSections.AHGraph; import io.github.moulberry.notenoughupdates.options.seperateSections.AHTweaks; +import io.github.moulberry.notenoughupdates.options.seperateSections.AccessoryBag; import io.github.moulberry.notenoughupdates.options.seperateSections.ApiKey; import io.github.moulberry.notenoughupdates.options.seperateSections.Calendar; import io.github.moulberry.notenoughupdates.options.seperateSections.CustomArmour; -import io.github.moulberry.notenoughupdates.options.seperateSections.Dungeons; import io.github.moulberry.notenoughupdates.options.seperateSections.DungeonMapConfig; +import io.github.moulberry.notenoughupdates.options.seperateSections.Dungeons; import io.github.moulberry.notenoughupdates.options.seperateSections.Enchanting; import io.github.moulberry.notenoughupdates.options.seperateSections.Fishing; import io.github.moulberry.notenoughupdates.options.seperateSections.ImprovedSBMenu; import io.github.moulberry.notenoughupdates.options.seperateSections.InventoryButtons; -import io.github.moulberry.notenoughupdates.options.seperateSections.Itemlist; import io.github.moulberry.notenoughupdates.options.seperateSections.ItemOverlays; +import io.github.moulberry.notenoughupdates.options.seperateSections.Itemlist; import io.github.moulberry.notenoughupdates.options.seperateSections.LocationEdit; import io.github.moulberry.notenoughupdates.options.seperateSections.Mining; import io.github.moulberry.notenoughupdates.options.seperateSections.Misc; @@ -33,9 +33,10 @@ import io.github.moulberry.notenoughupdates.options.seperateSections.MiscOverlay import io.github.moulberry.notenoughupdates.options.seperateSections.NeuAuctionHouse; import io.github.moulberry.notenoughupdates.options.seperateSections.Notifications; import io.github.moulberry.notenoughupdates.options.seperateSections.PetOverlay; +import io.github.moulberry.notenoughupdates.options.seperateSections.ProfileViewer; +import io.github.moulberry.notenoughupdates.options.seperateSections.SkillOverlays; import io.github.moulberry.notenoughupdates.options.seperateSections.SlayerOverlay; import io.github.moulberry.notenoughupdates.options.seperateSections.SlotLocking; -import io.github.moulberry.notenoughupdates.options.seperateSections.SkillOverlays; import io.github.moulberry.notenoughupdates.options.seperateSections.StorageGUI; import io.github.moulberry.notenoughupdates.options.seperateSections.Toolbar; import io.github.moulberry.notenoughupdates.options.seperateSections.TooltipTweaks; @@ -325,6 +326,13 @@ public class NEUConfig extends Config { ) public AccessoryBag accessoryBag = new AccessoryBag(); + @Expose + @Category( + name = "Profile Viewer", + desc = "Profile Viewer" + ) + public ProfileViewer profileViewer = new ProfileViewer(); + @Expose @Category( name = "Api Key", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHTweaks.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHTweaks.java index 0d21a96f..63c4fe8d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHTweaks.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/AHTweaks.java @@ -66,8 +66,8 @@ public class AHTweaks { @Expose @ConfigOption( - name = "Warning Threshold", - desc = "Threshold for BIN warning\nExample: 10% means warn if sell price is 10% lower than lowestbin" + name = "Undercut Warning Threshold", + desc = "Threshold for BIN warning\nExample: 10% means warn if sell price is 10% lower than lowest bin" ) @ConfigEditorSlider( minValue = 0.0f, @@ -77,6 +77,19 @@ public class AHTweaks { @ConfigAccordionId(id = 1) public float warningThreshold = 10f; + @Expose + @ConfigOption( + name = "Overcut Warning Threshold", + desc = "Threshold for BIN warning\nExample: 50% means warn if sell price is 50% higher than lowest bin" + ) + @ConfigEditorSlider( + minValue = 0.0f, + maxValue = 100.0f, + minStep = 5f + ) + @ConfigAccordionId(id = 1) + public float overcutWarningThreshold = 50f; + @ConfigOption( name = "Sort Warning", desc = "" diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java index 058b13d8..e872bfc0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Misc.java @@ -1,7 +1,13 @@ package io.github.moulberry.notenoughupdates.options.seperateSections; import com.google.gson.annotations.Expose; -import io.github.moulberry.notenoughupdates.core.config.annotations.*; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigAccordionId; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorAccordion; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorBoolean; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorButton; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDropdown; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorSlider; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; public class Misc { @Expose @@ -141,4 +147,4 @@ public class Misc { @ConfigEditorBoolean public boolean disableNPCRetexturing = false; -} \ No newline at end of file +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java new file mode 100644 index 00000000..2e1d0619 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java @@ -0,0 +1,63 @@ +package io.github.moulberry.notenoughupdates.options.seperateSections; + +import com.google.gson.annotations.Expose; +import io.github.moulberry.notenoughupdates.core.config.annotations.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ProfileViewer { + + @ConfigOption( + name = "Profile Viewer info", + desc = + "The Profile Viewer requires you to have an \u00A72api key\u00A77 set (if you don't have one set do \u00A72/api new\u00A77)\n" + ) + @ConfigEditorFSR( + runnableId = 12, + buttonText = "" + ) + public boolean pvInfo = false; + + @Expose + @ConfigOption( + name = "Open Profile Viewer", + desc = "Brings up the profile viewer (/pv)\n" + + "Shows stats and networth of players" + ) + @ConfigEditorButton( + runnableId = 13, + buttonText = "Open" + ) + public boolean openPV = true; + + @Expose + @ConfigOption( + name = "Page layout", + desc = "\u00a7rSelect the order of the pages at the top of the Profile Viewer\n" + + "\u00a7eDrag text to rearrange" + ) + @ConfigEditorDraggableList( + exampleText = { + "\u00a7eBasic Info", + "\u00a7eDungeons", + "\u00a7eExtra Info", + "\u00a7eInventories", + "\u00a7eCollections", + "\u00a7ePets", + "\u00a7eMining", + "\u00a7eBingo", + }, + allowRemovingElements = false + ) + public List pageLayout = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7)); + + @Expose + @ConfigOption( + name = "Always show bingo tab", + desc = "Always show bingo tab or only show it when the bingo profile is selected" + ) + @ConfigEditorBoolean + public boolean alwaysShowBingoTab = false; +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java index f2c7e396..bbab59cb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/FarmingOverlay.java @@ -175,18 +175,17 @@ public class FarmingOverlay extends TextOverlay { } if (!NotEnoughUpdates.INSTANCE.config.skillOverlays.useBZPrice || internalname != null && (internalname.equals( - "TREECAPITATOR_AXE")) - || internalname != null && (internalname.equals("JUNGLE_AXE"))) { - if (internalname != null && internalname.startsWith("THEORETICAL_HOE_WARTS") || - (internalname != null && internalname.equals("COCO_CHOPPER"))) { + "TREECAPITATOR_AXE")) || internalname != null && (internalname.equals("JUNGLE_AXE"))) { + if ((internalname != null && internalname.equals("COCO_CHOPPER"))) { Coins = 3; } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_POTATO") || - (internalname != null && internalname.startsWith("THEORETICAL_HOE_CARROT")) - || (internalname != null && internalname.equals("CACTUS_KNIFE")) || + (internalname != null && internalname.startsWith("THEORETICAL_HOE_CARROT")) || + (internalname != null && internalname.equals("CACTUS_KNIFE")) || (internalname != null && internalname.startsWith("THEORETICAL_HOE_WHEAT"))) { Coins = 1; - } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_CANE") || - (internalname != null && internalname.equals("TREECAPITATOR_AXE")) + } else if (internalname != null && internalname.startsWith("THEORETICAL_HOE_CANE") + || (internalname != null && internalname.equals("TREECAPITATOR_AXE")) + || (internalname != null && internalname.startsWith("THEORETICAL_HOE_WARTS")) || (internalname != null && internalname.equals("JUNGLE_AXE"))) { Coins = 2; } else if ((internalname != null && internalname.equals("PUMPKIN_DICER")) || diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java new file mode 100644 index 00000000..60d1e513 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BingoPage.java @@ -0,0 +1,309 @@ +package io.github.moulberry.notenoughupdates.profileviewer; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.ScaledResolution; +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.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class BingoPage { + private static final ResourceLocation BINGO_GUI_TEXTURE = new ResourceLocation("notenoughupdates:pv_bingo_tab.png"); + private static long lastResourceRequest; + private static List bingoGoals = null; + private static int currentEventId; + + public static void renderPage(int mouseX, int mouseY) { + processBingoResources(); + JsonObject bingoInfo = GuiProfileViewer.getProfile().getBingoInformation(); + + ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); + int width = scaledResolution.getScaledWidth(); + int height = scaledResolution.getScaledHeight(); + + int guiLeft = GuiProfileViewer.getGuiLeft(); + int guiTop = GuiProfileViewer.getGuiTop(); + //check if the player has created a bingo profile for the current event + if (bingoInfo == null) { + showMissingDataMessage(guiLeft, guiTop); + return; + } + + JsonArray events = bingoInfo.get("events").getAsJsonArray(); + JsonObject lastEvent = events.get(events.size() - 1).getAsJsonObject(); + int lastParticipatedId = lastEvent.get("key").getAsInt(); + if (currentEventId != lastParticipatedId) { + showMissingDataMessage(guiLeft, guiTop); + return; + } + + List completedGoals = jsonArrayToStringList(lastEvent.get("completed_goals").getAsJsonArray()); + Minecraft.getMinecraft().getTextureManager().bindTexture(BINGO_GUI_TEXTURE); + Utils.drawTexturedRect(guiLeft, guiTop, 431, 202, GL11.GL_NEAREST); + + GlStateManager.color(1, 1, 1, 1); + GlStateManager.disableLighting(); + + int row = 0; + int col = 0; + int initialY = guiTop + 46; + int initialX = guiLeft + 231; + int xAdjustment = 0; + int yAdjustment = 0; + for (JsonObject bingoGoal : bingoGoals) { + boolean dye = false; + boolean completed = false; + boolean communityGoal = false; + Item material; + if (bingoGoal.has("tiers")) { + if (isCommunityGoalFinished(bingoGoal)) { + material = Item.getItemFromBlock(Blocks.emerald_block); + } else { + material = Item.getItemFromBlock(Blocks.iron_block); + } + RenderHelper.enableGUIStandardItemLighting(); + completed = true; + communityGoal = true; + yAdjustment = -1; + xAdjustment = -1; + } else { + if (completedGoals.contains(bingoGoal.get("id").getAsString())) { + material = Items.dye; + xAdjustment = -1; + dye = true; + completed = true; + } else { + material = Items.paper; + } + } + + ItemStack itemStack = new ItemStack(material); + if (dye) { + itemStack.setItemDamage(10); + } + int x = col == 0 ? initialX + xAdjustment : initialX + (24 * col) + xAdjustment; + int y = row == 0 ? initialY + yAdjustment : initialY + (24 * row) + yAdjustment; + + Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI(itemStack, x, y); + if (mouseX >= x && mouseX < x + 24) { + if (mouseY >= y && mouseY <= y + 24) { + Utils.drawHoveringText( + getTooltip(bingoGoal, completed, communityGoal), + mouseX, + mouseY, + width, + height, + -1, + Minecraft.getMinecraft().fontRendererObj + ); + } + } + col++; + if (col == 5) { + col = 0; + row++; + } + } + + String totalPointsString = + EnumChatFormatting.AQUA + "Collected Points: " + EnumChatFormatting.WHITE + lastEvent.get("points").getAsInt(); + int totalGoals = completedGoals.size(); + String personalGoalsString; + if (totalGoals == 20) { + personalGoalsString = EnumChatFormatting.AQUA + "Personal Goals: " + EnumChatFormatting.GOLD + "20/20"; + } else { + personalGoalsString = + EnumChatFormatting.AQUA + "Personal Goals: " + EnumChatFormatting.WHITE + completedGoals.size() + + EnumChatFormatting.GOLD + "/" + EnumChatFormatting.WHITE + 20; + } + Utils.drawStringF(totalPointsString, Minecraft.getMinecraft().fontRendererObj, + guiLeft + 22, guiTop + 19, true, 0 + ); + Utils.drawStringF(personalGoalsString, Minecraft.getMinecraft().fontRendererObj, + guiLeft + 22, guiTop + 31, true, 0 + ); + + GlStateManager.enableLighting(); + } + + private static boolean isCommunityGoalFinished(JsonObject goal) { + JsonArray tiers = goal.get("tiers").getAsJsonArray(); + int totalTiers = tiers.size(); + long progress = goal.get("progress").getAsLong(); + int finalTier = 0; + for (JsonElement tier : tiers) { + long currentTier = tier.getAsLong(); + if (progress < currentTier) { + break; + } + finalTier++; + } + return finalTier == totalTiers; + } + + private static String generateProgressIndicator(double progress, double goal) { + int totalFields = 20; + int filled; + double percentage = progress / goal * 100; + if (percentage >= 100) { + filled = 20; + } else { + filled = (int) Math.round((percentage / 100) * 20); + } + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(EnumChatFormatting.DARK_GREEN); + for (int i = 0; i < totalFields; i++) { + stringBuilder.append("-"); + if (i > filled) { + stringBuilder.append(EnumChatFormatting.GRAY); + } + } + + return stringBuilder.toString(); + } + + private static List getTooltip(JsonObject goal, boolean completed, boolean communityGoal) { + List tooltip = new ArrayList<>(); + if (communityGoal) { + //get current tier + JsonArray tiers = goal.get("tiers").getAsJsonArray(); + int totalTiers = tiers.size(); + double progress = goal.get("progress").getAsLong(); + int finalTier = 0; + for (JsonElement tier : tiers) { + double currentTier = tier.getAsLong(); + if (progress < currentTier) { + break; + } + finalTier++; + } + double nextTier = finalTier < totalTiers ? tiers.get(totalTiers - 1).getAsLong() : tiers + .get(finalTier - 1) + .getAsLong(); + int progressToNextTier = (int) Math.round(progress / nextTier * 100); + if (progressToNextTier > 100) progressToNextTier = 100; + String progressBar = generateProgressIndicator(progress, nextTier); + String name = goal.get("name").getAsString(); + int nextTierNum = finalTier < totalTiers ? finalTier + 1 : totalTiers; + + String nextTierString = Utils.shortNumberFormat(nextTier, 0); + String progressString = Utils.shortNumberFormat(progress, 0); + tooltip.add(EnumChatFormatting.GREEN + name + " " + finalTier); + tooltip.add(EnumChatFormatting.DARK_GRAY + "Community Goal"); + tooltip.add(""); + tooltip.add( + EnumChatFormatting.GRAY + "Progress to " + name + " " + nextTierNum + ": " + EnumChatFormatting.YELLOW + + progressToNextTier + EnumChatFormatting.GOLD + "%"); + tooltip.add(progressBar + EnumChatFormatting.YELLOW + " " + progressString + EnumChatFormatting.GOLD + "/" + + EnumChatFormatting.YELLOW + nextTierString); + tooltip.add(""); + tooltip.add(EnumChatFormatting.GRAY + "Contribution Rewards"); + tooltip.add( + "Top " + EnumChatFormatting.YELLOW + "1%" + EnumChatFormatting.DARK_GRAY + " - " + EnumChatFormatting.GOLD + + "15 Bingo Points"); + tooltip.add( + "Top " + EnumChatFormatting.YELLOW + "5%" + EnumChatFormatting.DARK_GRAY + " - " + EnumChatFormatting.GOLD + + "12 Bingo Points"); + tooltip.add( + "Top " + EnumChatFormatting.YELLOW + "10%" + EnumChatFormatting.DARK_GRAY + " - " + EnumChatFormatting.GOLD + + "9 Bingo Points"); + tooltip.add( + "Top " + EnumChatFormatting.YELLOW + "25%" + EnumChatFormatting.DARK_GRAY + " - " + EnumChatFormatting.GOLD + + "7 Bingo Points"); + tooltip.add( + "All Contributors" + EnumChatFormatting.DARK_GRAY + " - " + EnumChatFormatting.GOLD + "4 Bingo Points"); + + tooltip.add(""); + tooltip.add(EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "Community Goals are"); + tooltip.add( + EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "collaborative - anyone with a"); + tooltip.add( + EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "Bingo profile can help to reach"); + tooltip.add(EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "the goal!"); + tooltip.add(""); + tooltip.add(EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "The more you contribute"); + tooltip.add(EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + + "towards the goal, the more you"); + tooltip.add(EnumChatFormatting.DARK_GRAY.toString() + EnumChatFormatting.ITALIC + "will be rewarded"); + + if (finalTier == totalTiers) { + tooltip.add(""); + tooltip.add(EnumChatFormatting.GREEN + "GOAL REACHED"); + } + } else { + tooltip.add(EnumChatFormatting.GREEN + goal.get("name").getAsString()); + tooltip.add(EnumChatFormatting.DARK_GRAY + "Personal Goal"); + tooltip.add(""); + tooltip.add(goal.get("lore").getAsString()); + tooltip.add(""); + tooltip.add(EnumChatFormatting.GRAY + "Reward"); + tooltip.add(EnumChatFormatting.GOLD + "1 Bingo Point"); + if (completed) { + tooltip.add(""); + tooltip.add(EnumChatFormatting.GREEN + "GOAL REACHED"); + } else { + tooltip.add(""); + tooltip.add(EnumChatFormatting.RED + "You have not reached this goal!"); + } + } + return tooltip; + } + + private static void showMissingDataMessage(int guiLeft, int guiTop) { + String message = EnumChatFormatting.RED + "No Bingo data for current event!"; + Utils.drawStringCentered(message, Minecraft.getMinecraft().fontRendererObj, + guiLeft + 431 / 2f, guiTop + 101, true, 0 + ); + } + + private static List jsonArrayToStringList(JsonArray completedGoals) { + List list = new ArrayList<>(); + for (JsonElement completedGoal : completedGoals) { + list.add(completedGoal.getAsString()); + } + return list; + } + + private static List jsonArrayToJsonObjectList(JsonArray goals) { + List list = new ArrayList<>(); + for (JsonElement goal : goals) { + list.add(goal.getAsJsonObject()); + } + + return list; + } + + private static void processBingoResources() { + long currentTime = System.currentTimeMillis(); + + //renew every 2 minutes + if (currentTime - lastResourceRequest < 120 * 1000 && bingoGoals != null) return; + lastResourceRequest = currentTime; + + HashMap args = new HashMap<>(); + NotEnoughUpdates.INSTANCE.manager.hypixelApi.getHypixelApiAsync( + NotEnoughUpdates.INSTANCE.config.apiKey.apiKey, + "resources/skyblock/bingo", + args + ).thenAccept(jsonObject -> { + if (jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) { + bingoGoals = jsonArrayToJsonObjectList(jsonObject.get("goals").getAsJsonArray()); + currentEventId = jsonObject.get("id").getAsInt(); + } + }); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java index 44ea686d..898f9e11 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -31,7 +31,12 @@ import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.*; +import net.minecraft.nbt.JsonToNBT; +import net.minecraft.nbt.NBTException; +import net.minecraft.nbt.NBTTagByteArray; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagString; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.Matrix4f; import net.minecraft.util.ResourceLocation; @@ -51,8 +56,21 @@ import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; -import java.util.*; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.TimeZone; +import java.util.TreeMap; +import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadPoolExecutor; @@ -61,8 +79,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class GuiProfileViewer extends GuiScreen { - private static final ResourceLocation CHEST_GUI_TEXTURE = - new ResourceLocation("textures/gui/container/generic_54.png"); public static final ResourceLocation pv_basic = new ResourceLocation("notenoughupdates:pv_basic.png"); public static final ResourceLocation pv_dung = new ResourceLocation("notenoughupdates:pv_dung.png"); public static final ResourceLocation pv_extra = new ResourceLocation("notenoughupdates:pv_extra.png"); @@ -80,45 +96,170 @@ public class GuiProfileViewer extends GuiScreen { public static final ResourceLocation resource_packs = new ResourceLocation("minecraft:textures/gui/resource_packs.png"); public static final ResourceLocation icons = new ResourceLocation("textures/gui/icons.png"); - + public static final HashMap> PET_STAT_BOOSTS = + new HashMap>() {{ + put("PET_ITEM_BIG_TEETH_COMMON", new HashMap() {{ + put("CRIT_CHANCE", 5f); + }}); + put("PET_ITEM_HARDENED_SCALES_UNCOMMON", new HashMap() {{ + put("DEFENCE", 25f); + }}); + put("PET_ITEM_LUCKY_CLOVER", new HashMap() {{ + put("MAGIC_FIND", 7f); + }}); + put("PET_ITEM_SHARPENED_CLAWS_UNCOMMON", new HashMap() {{ + put("CRIT_DAMAGE", 15f); + }}); + }}; + public static final HashMap> PET_STAT_BOOSTS_MULT = + new HashMap>() {{ + put("PET_ITEM_IRON_CLAWS_COMMON", new HashMap() {{ + put("CRIT_DAMAGE", 1.4f); + put("CRIT_CHANCE", 1.4f); + }}); + put("PET_ITEM_TEXTBOOK", new HashMap() {{ + put("INTELLIGENCE", 2f); + }}); + }}; + private static final ResourceLocation CHEST_GUI_TEXTURE = + new ResourceLocation("textures/gui/container/generic_54.png"); private static final NumberFormat numberFormat = NumberFormat.getInstance(Locale.US); - - private final ProfileViewer.Profile profile; + private static final ItemStack DEADBUSH = new ItemStack(Item.getItemFromBlock(Blocks.deadbush)); + private static final ItemStack iron_pick = new ItemStack(Items.iron_pickaxe); + private static final ItemStack[] BOSS_HEADS = new ItemStack[7]; + private static final String[] dungSkillsName = {"Healer", "Mage", "Berserk", "Archer", "Tank"}; + private static final ItemStack[] dungSkillsStack = { + new ItemStack(Items.potionitem, 1, 16389), + new ItemStack(Items.blaze_rod), + new ItemStack(Items.iron_sword), + new ItemStack(Items.bow), + new ItemStack(Items.leather_chestplate) + }; + private static final String[] bossFloorArr = {"Bonzo", "Scarf", "Professor", "Thorn", "Livid", "Sadan", "Necron"}; + private static final String[] bossFloorHeads = { + "12716ecbf5b8da00b05f316ec6af61e8bd02805b21eb8e440151468dc656549c", + "7de7bbbdf22bfe17980d4e20687e386f11d59ee1db6f8b4762391b79a5ac532d", + "9971cee8b833a62fc2a612f3503437fdf93cad692d216b8cf90bbb0538c47dd8", + "8b6a72138d69fbbd2fea3fa251cabd87152e4f1c97e5f986bf685571db3cc0", + "c1007c5b7114abec734206d4fc613da4f3a0e99f71ff949cedadc99079135a0b", + "fa06cb0c471c1c9bc169af270cd466ea701946776056e472ecdaeb49f0f4a4dc", + "a435164c05cea299a3f016bbbed05706ebb720dac912ce4351c2296626aecd9a" + }; + private static final LinkedHashMap dungeonsModeIcons = new LinkedHashMap() {{ + put( + "catacombs", + Utils.editItemStackInfo(NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager + .getItemInformation() + .get("DUNGEON_STONE")), EnumChatFormatting.GRAY + "Normal Mode", true) + ); + put( + "master_catacombs", + Utils.editItemStackInfo(NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager + .getItemInformation() + .get("MASTER_SKULL_TIER_7")), EnumChatFormatting.GRAY + "Master Mode", true) + ); + }}; + private static final LinkedHashMap invNameToDisplayMap = new LinkedHashMap() {{ + put( + "inv_contents", + Utils.createItemStack(Item.getItemFromBlock(Blocks.chest), EnumChatFormatting.GRAY + "Inventory") + ); + put( + "ender_chest_contents", + Utils.createItemStack(Item.getItemFromBlock(Blocks.ender_chest), EnumChatFormatting.GRAY + "Ender Chest") + ); + // put("backpack_contents", Utils.createItemStack(Item.getItemFromBlock(Blocks.dropper), EnumChatFormatting.GRAY+"Backpacks")); + put( + "backpack_contents", + Utils.editItemStackInfo(NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager + .getItemInformation() + .get("JUMBO_BACKPACK")), EnumChatFormatting.GRAY + "Backpacks", true) + ); + put( + "personal_vault_contents", + Utils.editItemStackInfo(NotEnoughUpdates.INSTANCE.manager.jsonToStack(NotEnoughUpdates.INSTANCE.manager + .getItemInformation() + .get("IRON_CHEST")), EnumChatFormatting.GRAY + "Personal vault", true) + ); + put("talisman_bag", Utils.createItemStack(Items.golden_apple, EnumChatFormatting.GRAY + "Accessory Bag")); + put("wardrobe_contents", Utils.createItemStack(Items.leather_chestplate, EnumChatFormatting.GRAY + "Wardrobe")); + put("fishing_bag", Utils.createItemStack(Items.fish, EnumChatFormatting.GRAY + "Fishing Bag")); + put("potion_bag", Utils.createItemStack(Items.potionitem, EnumChatFormatting.GRAY + "Potion Bag")); + }}; + private static final Pattern DAMAGE_PATTERN = Pattern.compile("^Damage: \\+([0-9]+)"); + private static final Pattern STRENGTH_PATTERN = Pattern.compile("^Strength: \\+([0-9]+)"); + private static final Pattern FISHSPEED_PATTERN = Pattern.compile("^Increases fishing speed by \\+([0-9]+)"); + private static final char[] c = new char[]{'k', 'm', 'b', 't'}; + private static final ExecutorService profileLoader = Executors.newFixedThreadPool(1); public static ProfileViewerPage currentPage = ProfileViewerPage.BASIC; + public static HashMap MINION_RARITY_TO_NUM = new HashMap() {{ + put("COMMON", "0"); + put("UNCOMMON", "1"); + put("RARE", "2"); + put("EPIC", "3"); + put("LEGENDARY", "4"); + put("MYTHIC", "5"); + }}; + private static int floorTime = 7; + private static int guiLeft; + private static int guiTop; + private static ProfileViewer.Profile profile = null; + private final GuiElementTextField playerNameTextField; + private final HashMap levelObjCatas = new HashMap<>(); + private final HashMap levelObjhotms = new HashMap<>(); + private final HashMap> levelObjClasseses = new HashMap<>(); + private final GuiElementTextField dungeonLevelTextField = new GuiElementTextField("", GuiElementTextField.SCALE_TEXT); + private final String[] romans = new String[]{ + "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", + "XII", "XIII", "XIV", "XV", "XVI", "XVII", "XIX", "XX" + }; + private final int COLLS_XCOUNT = 5; + private final int COLLS_YCOUNT = 4; + private final float COLLS_XPADDING = (190 - COLLS_XCOUNT * 20) / (float) (COLLS_XCOUNT + 1); + private final float COLLS_YPADDING = (202 - COLLS_YCOUNT * 20) / (float) (COLLS_YCOUNT + 1); + private final ItemStack fillerStack = new ItemStack(Item.getItemFromBlock(Blocks.stained_glass_pane), 1, 15); + private final GuiElementTextField inventoryTextField = new GuiElementTextField("", GuiElementTextField.SCALE_TEXT); + private final HashMap panoramasMap = new HashMap<>(); + Shader blurShaderHorz = null; + Framebuffer blurOutputHorz = null; + Shader blurShaderVert = null; + Framebuffer blurOutputVert = null; private int sizeX; private int sizeY; - private int guiLeft; - private int guiTop; - private float backgroundRotation = 0; - private long currentTime = 0; private long lastTime = 0; private long startTime = 0; - private List tooltipToDisplay = null; - private String profileId = null; private boolean profileDropdownSelected = false; - - public enum ProfileViewerPage { - LOADING(null), - INVALID_NAME(null), - NO_SKYBLOCK(null), - BASIC(new ItemStack(Items.paper)), - DUNG(new ItemStack(Item.getItemFromBlock(Blocks.deadbush))), - EXTRA(new ItemStack(Items.book)), - INVS(new ItemStack(Item.getItemFromBlock(Blocks.ender_chest))), - COLS(new ItemStack(Items.painting)), - PETS(new ItemStack(Items.bone)), - MINING(new ItemStack(Items.iron_pickaxe)); - - public final ItemStack stack; - - ProfileViewerPage(ItemStack stack) { - this.stack = stack; - } - } + private ItemStack selectedCollectionCategory = null; + private int floorLevelTo = -1; + private long floorLevelToXP = -1; + private boolean onMasterMode = false; + private int selectedPet = -1; + private int petsPage = 0; + private List sortedPets = null; + private List sortedPetsStack = null; + private ItemStack[] bestWeapons = null; + private ItemStack[] bestRods = null; + private ItemStack[] armorItems = null; + private HashMap inventoryItems = new HashMap<>(); + private String selectedInventory = "inv_contents"; + private int currentInventoryIndex = 0; + private int arrowCount = -1; + private int greenCandyCount = -1; + private int purpleCandyCount = -1; + private EntityOtherPlayerMP entityPlayer = null; + private ResourceLocation playerLocationSkin = null; + private ResourceLocation playerLocationCape = null; + private String skinType = null; + private TreeMap> topKills = null; + private TreeMap> topDeaths = null; + private int backgroundClickedX = -1; + private boolean loadingProfile = false; + private double lastBgBlurFactor = -1; + private boolean showBingoPage; public GuiProfileViewer(ProfileViewer.Profile profile) { this.profile = profile; @@ -137,7 +278,173 @@ public class GuiProfileViewer extends GuiScreen { } } - private final GuiElementTextField playerNameTextField; + private static JsonObject getPetInfo(String pet_name, String rarity) { + JsonObject petInfo = new JsonObject(); + + if (Constants.PETS.has("custom_pet_leveling") && + Constants.PETS.getAsJsonObject("custom_pet_leveling").has(pet_name)) { + JsonObject pet = Constants.PETS.getAsJsonObject("custom_pet_leveling").getAsJsonObject(pet_name); + if (pet.has("type") && pet.has("pet_levels")) { + int type = pet.get("type").getAsInt(); + switch (type) { + case 1: + JsonArray defaultLevels = Constants.PETS.getAsJsonArray("pet_levels"); + defaultLevels.addAll(pet.getAsJsonArray("pet_levels")); + petInfo.add("pet_levels", Constants.PETS.getAsJsonArray("pet_levels")); + break; + case 2: + petInfo.add("pet_levels", pet.getAsJsonArray("pet_levels")); + break; + default: + petInfo.add("pet_levels", Constants.PETS.getAsJsonArray("pet_levels")); + break; + } + } else { + petInfo.add("pet_levels", Constants.PETS.getAsJsonArray("pet_levels")); + } + if (pet.has("max_level")) { + petInfo.add("max_level", pet.get("max_level")); + } else { + petInfo.add("max_level", new JsonPrimitive(100)); + } + + if (pet.has("pet_rarity_offset")) { + petInfo.add("offset", pet.get("pet_rarity_offset")); + } else { + petInfo.add("offset", Constants.PETS.getAsJsonObject("pet_rarity_offset").get(rarity)); + } + + } else { + //System.out.println("Default Path"); + petInfo.add("offset", Constants.PETS.getAsJsonObject("pet_rarity_offset").get(rarity)); + petInfo.add("max_level", new JsonPrimitive(100)); + petInfo.add("pet_levels", Constants.PETS.getAsJsonArray("pet_levels")); + } + + return petInfo; + + } + + public static PetLevel getPetLevel(String pet_name, String rarity, float exp) { + JsonObject petInfo = getPetInfo(pet_name, rarity); + int offset = petInfo.get("offset").getAsInt(); + int maxPetLevel = petInfo.get("max_level").getAsInt(); + JsonArray levels = petInfo.getAsJsonArray("pet_levels"); + + float xpTotal = 0; + float level = 1; + float currentLevelRequirement = 0; + float currentLevelProgress = 0; + + boolean addLevel = true; + + for (int i = offset; i < offset + maxPetLevel - 1; i++) { + if (addLevel) { + currentLevelRequirement = levels.get(i).getAsFloat(); + xpTotal += currentLevelRequirement; + if (xpTotal > exp) { + currentLevelProgress = (exp - (xpTotal - currentLevelRequirement)); + addLevel = false; + } else { + level += 1; + } + } else { + + xpTotal += levels.get(i).getAsFloat(); + + } + } + + level += currentLevelProgress / currentLevelRequirement; + if (level <= 0) { + level = 1; + } else if (level > maxPetLevel) { + level = maxPetLevel; + } + PetLevel levelObj = new PetLevel(); + levelObj.level = level; + levelObj.currentLevelRequirement = currentLevelRequirement; + levelObj.maxXP = xpTotal; + levelObj.levelPercentage = currentLevelProgress / currentLevelRequirement; + levelObj.levelXp = currentLevelProgress; + levelObj.totalXp = exp; + return levelObj; + } + + public static String shortNumberFormat(double n, int iteration) { + if (n < 1000) { + if (n % 1 == 0) { + return Integer.toString((int) n); + } else { + return String.format("%.2f", n); + } + } + + double d = ((long) n / 100) / 10.0; + boolean isRound = (d * 10) % 10 == 0; + return (d < 1000 ? + ((d > 99.9 || isRound || (!isRound && d > 9.99) ? + (int) d * 10 / 10 : d + "" + ) + "" + c[iteration]) + : shortNumberFormat(d, iteration + 1)); + } + + public static void drawEntityOnScreen( + int posX, + int posY, + int scale, + float mouseX, + float mouseY, + EntityLivingBase ent + ) { + GlStateManager.enableColorMaterial(); + GlStateManager.pushMatrix(); + GlStateManager.translate((float) posX, (float) posY, 50.0F); + GlStateManager.scale((float) (-scale), (float) scale, (float) scale); + GlStateManager.rotate(180.0F, 0.0F, 0.0F, 1.0F); + float renderYawOffset = ent.renderYawOffset; + float f1 = ent.rotationYaw; + float f2 = ent.rotationPitch; + float f3 = ent.prevRotationYawHead; + float f4 = ent.rotationYawHead; + GlStateManager.rotate(135.0F, 0.0F, 1.0F, 0.0F); + RenderHelper.enableStandardItemLighting(); + GlStateManager.rotate(-135.0F, 0.0F, 1.0F, 0.0F); + GlStateManager.rotate(25, 1.0F, 0.0F, 0.0F); + ent.renderYawOffset = (float) Math.atan(mouseX / 40.0F) * 20.0F; + ent.rotationYaw = (float) Math.atan(mouseX / 40.0F) * 40.0F; + ent.rotationPitch = -((float) Math.atan(mouseY / 40.0F)) * 20.0F; + ent.rotationYawHead = ent.rotationYaw; + ent.prevRotationYawHead = ent.rotationYaw; + RenderManager rendermanager = Minecraft.getMinecraft().getRenderManager(); + rendermanager.setPlayerViewY(180.0F); + rendermanager.setRenderShadow(false); + rendermanager.renderEntityWithPosYaw(ent, 0.0D, 0.0D, 0.0D, 0.0F, 1.0F); + + ent.renderYawOffset = renderYawOffset; + ent.rotationYaw = f1; + ent.rotationPitch = f2; + ent.prevRotationYawHead = f3; + ent.rotationYawHead = f4; + GlStateManager.popMatrix(); + RenderHelper.disableStandardItemLighting(); + GlStateManager.disableRescaleNormal(); + GlStateManager.setActiveTexture(OpenGlHelper.lightmapTexUnit); + GlStateManager.disableTexture2D(); + GlStateManager.setActiveTexture(OpenGlHelper.defaultTexUnit); + } + + public static int getGuiLeft() { + return guiLeft; + } + + public static int getGuiTop() { + return guiTop; + } + + public static ProfileViewer.Profile getProfile() { + return profile; + } @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { @@ -159,7 +466,7 @@ public class GuiProfileViewer extends GuiScreen { { //this is just to cache the guild info if (profile != null) { - JsonObject guildinfo = profile.getGuildInfo(null); + profile.getGuildInfo(null); } } @@ -168,6 +475,22 @@ public class GuiProfileViewer extends GuiScreen { this.guiLeft = (this.width - this.sizeX) / 2; this.guiTop = (this.height - this.sizeY) / 2; + boolean bingo = false; + JsonObject currProfileInfo = profile.getProfileInformation(profileId); + if (NotEnoughUpdates.INSTANCE.config.profileViewer.alwaysShowBingoTab) { + showBingoPage = true; + } else { + if (currProfileInfo != null && currProfileInfo.has("game_mode") && + currProfileInfo.get("game_mode").getAsString().equals("bingo")) { + showBingoPage = true; + } else { + showBingoPage = false; + } + } + + if (!showBingoPage && currentPage == ProfileViewerPage.BINGO) + currentPage = ProfileViewerPage.BASIC; + super.drawScreen(mouseX, mouseY, partialTicks); drawDefaultBackground(); @@ -199,7 +522,6 @@ public class GuiProfileViewer extends GuiScreen { ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); if (profile != null) { - JsonObject currProfileInfo = profile.getProfileInformation(profileId); //Render Profile chooser button renderBlurredBackground(width, height, guiLeft + 2, guiTop + sizeY + 3 + 2, 100 - 4, 20 - 4); Minecraft.getMinecraft().getTextureManager().bindTexture(pv_dropdown); @@ -345,16 +667,16 @@ public class GuiProfileViewer extends GuiScreen { case BASIC: drawBasicPage(mouseX, mouseY, partialTicks); break; - case DUNG: + case DUNGEON: drawDungPage(mouseX, mouseY, partialTicks); break; case EXTRA: drawExtraPage(mouseX, mouseY, partialTicks); break; - case INVS: + case INVENTORIES: drawInvsPage(mouseX, mouseY, partialTicks); break; - case COLS: + case COLLECTIONS: drawColsPage(mouseX, mouseY, partialTicks); break; case PETS: @@ -363,6 +685,9 @@ public class GuiProfileViewer extends GuiScreen { case MINING: drawMiningPage(mouseX, mouseY, partialTicks); break; + case BINGO: + BingoPage.renderPage(mouseX, mouseY); + break; case LOADING: String str = EnumChatFormatting.YELLOW + "Loading player profiles."; long currentTimeMod = System.currentTimeMillis() % 1000; @@ -540,9 +865,11 @@ public class GuiProfileViewer extends GuiScreen { private void renderTabs(boolean renderPressed) { int ignoredTabs = 0; - for (int i = 0; i < ProfileViewerPage.values().length; i++) { - ProfileViewerPage page = ProfileViewerPage.values()[i]; - if (page.stack == null) { + List configList = NotEnoughUpdates.INSTANCE.config.profileViewer.pageLayout; + for (int i = 0; i < configList.size(); i++) { + ProfileViewerPage page = ProfileViewerPage.getById(configList.get(i)); + if (page == null) continue; + if (page.stack == null || (page == ProfileViewerPage.BINGO && !showBingoPage)) { ignoredTabs++; continue; } @@ -598,9 +925,10 @@ public class GuiProfileViewer extends GuiScreen { protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { if (currentPage != ProfileViewerPage.LOADING && currentPage != ProfileViewerPage.INVALID_NAME) { int ignoredTabs = 0; - for (int i = 0; i < ProfileViewerPage.values().length; i++) { - ProfileViewerPage page = ProfileViewerPage.values()[i]; - if (page.stack == null) { + List configList = NotEnoughUpdates.INSTANCE.config.profileViewer.pageLayout; + for (int i = 0; i < configList.size(); i++) { + ProfileViewerPage page = ProfileViewerPage.getById(configList.get(i)); + if (page.stack == null || (page == ProfileViewerPage.BINGO && !showBingoPage)) { ignoredTabs++; continue; } @@ -620,10 +948,10 @@ public class GuiProfileViewer extends GuiScreen { } } switch (currentPage) { - case DUNG: + case DUNGEON: mouseClickedDung(mouseX, mouseY, mouseButton); break; - case INVS: + case INVENTORIES: inventoryTextField.setSize(88, 20); if (mouseX > guiLeft + 19 && mouseX < guiLeft + 19 + 88) { if (mouseY > guiTop + sizeY - 26 - 20 && mouseY < guiTop + sizeY - 26) { @@ -729,14 +1057,14 @@ public class GuiProfileViewer extends GuiScreen { protected void keyTyped(char typedChar, int keyCode) throws IOException { super.keyTyped(typedChar, keyCode); switch (currentPage) { - case INVS: + case INVENTORIES: keyTypedInvs(typedChar, keyCode); inventoryTextField.keyTyped(typedChar, keyCode); break; - case COLS: + case COLLECTIONS: keyTypedCols(typedChar, keyCode); break; - case DUNG: + case DUNGEON: keyTypedDung(typedChar, keyCode); break; } @@ -757,10 +1085,10 @@ public class GuiProfileViewer extends GuiScreen { super.mouseReleased(mouseX, mouseY, mouseButton); switch (currentPage) { - case INVS: + case INVENTORIES: mouseReleasedInvs(mouseX, mouseY, mouseButton); break; - case COLS: + case COLLECTIONS: mouseReleasedCols(mouseX, mouseY, mouseButton); break; case PETS: @@ -799,10 +1127,8 @@ public class GuiProfileViewer extends GuiScreen { if (mouseX >= guiLeft - 29 && mouseX <= guiLeft) { if (mouseY >= guiTop && mouseY <= guiTop + 28) { onMasterMode = false; - return; } else if (mouseY + 28 >= guiTop && mouseY <= guiTop + 28 * 2) { onMasterMode = true; - return; } } } @@ -941,8 +1267,6 @@ public class GuiProfileViewer extends GuiScreen { } } - private ItemStack selectedCollectionCategory = null; - private void mouseReleasedCols(int mouseX, int mouseY, int mouseButton) { int collectionCatSize = ProfileViewer.getCollectionCatToCollectionMap().size(); int collectionCatYSize = (int) (162f / (collectionCatSize - 1 + 0.0000001f)); @@ -954,43 +1278,11 @@ public class GuiProfileViewer extends GuiScreen { selectedCollectionCategory = stack; Utils.playPressSound(); return; - } - } - yIndex++; - } - } - - private static final ItemStack DEADBUSH = new ItemStack(Item.getItemFromBlock(Blocks.deadbush)); - private static final ItemStack iron_pick = new ItemStack(Items.iron_pickaxe); - private static final ItemStack[] BOSS_HEADS = new ItemStack[7]; - - private final HashMap levelObjCatas = new HashMap<>(); - private final HashMap levelObjhotms = new HashMap<>(); - private final HashMap