diff options
author | Lulonaut <67191924+Lulonaut@users.noreply.github.com> | 2022-03-20 08:47:29 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-20 08:47:29 +0100 |
commit | f29ebcc6cdf202a69f267a4dbdbfc9239929fd8a (patch) | |
tree | 4e7699384cc5d400f1b3d101a5ed31448e3110d5 /src/main | |
parent | 0ef9d7e01ec6696444af53176ab955e0cb0701b0 (diff) | |
download | NotEnoughUpdates-f29ebcc6cdf202a69f267a4dbdbfc9239929fd8a.tar.gz NotEnoughUpdates-f29ebcc6cdf202a69f267a4dbdbfc9239929fd8a.tar.bz2 NotEnoughUpdates-f29ebcc6cdf202a69f267a4dbdbfc9239929fd8a.zip |
dungeons and pv bingo tab (#93)
Diffstat (limited to 'src/main')
20 files changed, 1470 insertions, 813 deletions
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<Integer> 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<Integer>) 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<String, MapPosition> 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<String, MapPosition> entry : playerMarkerMapPositionsLast.entrySet()) { HashMap<Integer, Float> 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; @@ -327,6 +328,13 @@ public class NEUConfig extends Config { @Expose @Category( + name = "Profile Viewer", + desc = "Profile Viewer" + ) + public ProfileViewer profileViewer = new ProfileViewer(); + + @Expose + @Category( name = "Api Key", desc = "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<Integer> 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<JsonObject> 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<String> 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<String> getTooltip(JsonObject goal, boolean completed, boolean communityGoal) { + List<String> 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<String> jsonArrayToStringList(JsonArray completedGoals) { + List<String> list = new ArrayList<>(); + for (JsonElement completedGoal : completedGoals) { + list.add(completedGoal.getAsString()); + } + return list; + } + + private static List<JsonObject> jsonArrayToJsonObjectList(JsonArray goals) { + List<JsonObject> 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<String, String> 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<String, HashMap<String, Float>> PET_STAT_BOOSTS = + new HashMap<String, HashMap<String, Float>>() {{ + put("PET_ITEM_BIG_TEETH_COMMON", new HashMap<String, Float>() {{ + put("CRIT_CHANCE", 5f); + }}); + put("PET_ITEM_HARDENED_SCALES_UNCOMMON", new HashMap<String, Float>() {{ + put("DEFENCE", 25f); + }}); + put("PET_ITEM_LUCKY_CLOVER", new HashMap<String, Float>() {{ + put("MAGIC_FIND", 7f); + }}); + put("PET_ITEM_SHARPENED_CLAWS_UNCOMMON", new HashMap<String, Float>() {{ + put("CRIT_DAMAGE", 15f); + }}); + }}; + public static final HashMap<String, HashMap<String, Float>> PET_STAT_BOOSTS_MULT = + new HashMap<String, HashMap<String, Float>>() {{ + put("PET_ITEM_IRON_CLAWS_COMMON", new HashMap<String, Float>() {{ + put("CRIT_DAMAGE", 1.4f); + put("CRIT_CHANCE", 1.4f); + }}); + put("PET_ITEM_TEXTBOOK", new HashMap<String, Float>() {{ + 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<String, ItemStack> dungeonsModeIcons = new LinkedHashMap<String, ItemStack>() {{ + 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<String, ItemStack> invNameToDisplayMap = new LinkedHashMap<String, ItemStack>() {{ + 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<String, String> MINION_RARITY_TO_NUM = new HashMap<String, String>() {{ + 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<String, ProfileViewer.Level> levelObjCatas = new HashMap<>(); + private final HashMap<String, ProfileViewer.Level> levelObjhotms = new HashMap<>(); + private final HashMap<String, HashMap<String, ProfileViewer.Level>> 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<String, ResourceLocation[]> 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<String> 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<JsonObject> sortedPets = null; + private List<ItemStack> sortedPetsStack = null; + private ItemStack[] bestWeapons = null; + private ItemStack[] bestRods = null; + private ItemStack[] armorItems = null; + private HashMap<String, ItemStack[][][]> 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<Integer, Set<String>> topKills = null; + private TreeMap<Integer, Set<String>> 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<Integer> 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<Integer> 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)); @@ -960,38 +1284,6 @@ public class GuiProfileViewer extends GuiScreen { } } - 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<String, ProfileViewer.Level> levelObjCatas = new HashMap<>(); - private final HashMap<String, ProfileViewer.Level> levelObjhotms = new HashMap<>(); - private final HashMap<String, HashMap<String, ProfileViewer.Level>> levelObjClasseses = new HashMap<>(); - - private final GuiElementTextField dungeonLevelTextField = new GuiElementTextField("", GuiElementTextField.SCALE_TEXT); - - 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 int floorTime = 7; - private int floorLevelTo = -1; - private int floorLevelToXP = -1; - private void calculateFloorLevelXP() { JsonObject leveling = Constants.LEVELING; if (leveling == null) return; @@ -1016,27 +1308,12 @@ public class GuiProfileViewer extends GuiScreen { if (remaining < 0) { remaining = 0; } - floorLevelToXP = (int) remaining; + floorLevelToXP = (long) remaining; } catch (Exception e) { dungeonLevelTextField.setCustomBorderColour(0xffff0000); } } - private static final LinkedHashMap<String, ItemStack> dungeonsModeIcons = new LinkedHashMap<String, ItemStack>() {{ - 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 void drawDungPage(int mouseX, int mouseY, float partialTicks) { Minecraft.getMinecraft().getTextureManager().bindTexture(pv_dung); Utils.drawTexturedRect(guiLeft, guiTop, sizeX, sizeY, GL11.GL_NEAREST); @@ -1067,7 +1344,7 @@ public class GuiProfileViewer extends GuiScreen { "dungeons.dungeon_types.catacombs.experience" ), 0); levelObjCata = ProfileViewer.getLevel(Utils.getElement(leveling, "catacombs").getAsJsonArray(), - cataXp, 50, false + cataXp, 99, false ); levelObjCata.totalXp = cataXp; levelObjCatas.put(profileId, levelObjCata); @@ -1570,8 +1847,6 @@ public class GuiProfileViewer extends GuiScreen { //drawSideButton(2, dungeonsModeIcons.get("catacombs"), false); } - private boolean onMasterMode = false; - //TODO: improve this shit private void drawSideButtons() { // GlStateManager.pushMatrix(); @@ -1688,150 +1963,14 @@ public class GuiProfileViewer extends GuiScreen { GL11.glTranslatef(-(x), -(y - 6f), 0); } - public static class PetLevel { - public float level; - public float currentLevelRequirement; - public float maxXP; - public float levelPercentage; - public float levelXp; - public float totalXp; - } - - private static JsonObject getPetInfo(String pet_name, String rarity) { - JsonObject petInfo = new JsonObject(); - //System.out.println(pet_name); - //System.out.println(rarity); - - 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; + private ItemStack getQuestionmarkSkull() { + return Utils.createSkull( + EnumChatFormatting.RED + "Unknown Pet", + "Unknown Pet", + "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYmM4ZWExZjUxZjI1M2ZmNTE0MmNhMTFhZTQ1MTkzYTRhZDhjM2FiNWU5YzZlZWM4YmE3YTRmY2I3YmFjNDAifX19" + ); } - public static final HashMap<String, HashMap<String, Float>> PET_STAT_BOOSTS = - new HashMap<String, HashMap<String, Float>>() {{ - put("PET_ITEM_BIG_TEETH_COMMON", new HashMap<String, Float>() {{ - put("CRIT_CHANCE", 5f); - }}); - put("PET_ITEM_HARDENED_SCALES_UNCOMMON", new HashMap<String, Float>() {{ - put("DEFENCE", 25f); - }}); - put("PET_ITEM_LUCKY_CLOVER", new HashMap<String, Float>() {{ - put("MAGIC_FIND", 7f); - }}); - put("PET_ITEM_SHARPENED_CLAWS_UNCOMMON", new HashMap<String, Float>() {{ - put("CRIT_DAMAGE", 15f); - }}); - }}; - - public static final HashMap<String, HashMap<String, Float>> PET_STAT_BOOSTS_MULT = - new HashMap<String, HashMap<String, Float>>() {{ - put("PET_ITEM_IRON_CLAWS_COMMON", new HashMap<String, Float>() {{ - put("CRIT_DAMAGE", 1.4f); - put("CRIT_CHANCE", 1.4f); - }}); - put("PET_ITEM_TEXTBOOK", new HashMap<String, Float>() {{ - put("INTELLIGENCE", 2f); - }}); - }}; - - private int selectedPet = -1; - private int petsPage = 0; - private List<JsonObject> sortedPets = null; - private List<ItemStack> sortedPetsStack = null; - public static HashMap<String, String> MINION_RARITY_TO_NUM = new HashMap<String, String>() {{ - put("COMMON", "0"); - put("UNCOMMON", "1"); - put("RARE", "2"); - put("EPIC", "3"); - put("LEGENDARY", "4"); - put("MYTHIC", "5"); - }}; - private void drawPetsPage(int mouseX, int mouseY, float partialTicks) { JsonObject petsInfo = profile.getPetsInfo(profileId); if (petsInfo == null) return; @@ -1908,121 +2047,148 @@ public class GuiProfileViewer extends GuiScreen { pet.addProperty("maxXP", maxXP); JsonObject petItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(petname + ";" + tierNum); - if (petItem == null) continue; - - ItemStack stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(petItem, false, false); - HashMap<String, String> replacements = - NotEnoughUpdates.INSTANCE.manager.getLoreReplacements(petname, tier, (int) Math.floor(level)); - - if (heldItem != null) { - HashMap<String, Float> petStatBoots = PET_STAT_BOOSTS.get(heldItem); - HashMap<String, Float> petStatBootsMult = PET_STAT_BOOSTS_MULT.get(heldItem); - if (petStatBoots != null) { - for (Map.Entry<String, Float> entryBoost : petStatBoots.entrySet()) { - try { - float value = Float.parseFloat(replacements.get(entryBoost.getKey())); - replacements.put(entryBoost.getKey(), String.valueOf((int) Math.floor(value + entryBoost.getValue()))); - } catch (Exception ignored) { + ItemStack stack; + if (petItem == null) { + stack = getQuestionmarkSkull(); + HashMap<String, String> replacements = new HashMap<>(); + NBTTagCompound display = new NBTTagCompound(); + if (stack.getTagCompound() != null && stack.getTagCompound().hasKey("display")) { + display = stack.getTagCompound().getCompoundTag("display"); + } + NBTTagList lore = new NBTTagList(); + lore.appendTag(new NBTTagString(EnumChatFormatting.RED + "This pet is not saved in the repository")); + lore.appendTag(new NBTTagString("")); + lore.appendTag(new NBTTagString( + EnumChatFormatting.RED + "If you expected it to be there please send a message in")); + lore.appendTag(new NBTTagString(EnumChatFormatting.RED.toString() + + EnumChatFormatting.BOLD + "#neu-support " + EnumChatFormatting.RESET + EnumChatFormatting.RED + "on " + + EnumChatFormatting.BOLD + "discord.gg/moulberry")); + + display.setTag("Lore", lore); + NBTTagCompound tag = stack.getTagCompound() != null ? stack.getTagCompound() : new NBTTagCompound(); + tag.setTag("display", display); + stack.setTagCompound(tag); + } else { + stack = NotEnoughUpdates.INSTANCE.manager.jsonToStack(petItem, false, false); + HashMap<String, String> replacements = + NotEnoughUpdates.INSTANCE.manager.getLoreReplacements(petname, tier, (int) Math.floor(level)); + + if (heldItem != null) { + HashMap<String, Float> petStatBoots = PET_STAT_BOOSTS.get(heldItem); + HashMap<String, Float> petStatBootsMult = PET_STAT_BOOSTS_MULT.get(heldItem); + if (petStatBoots != null) { + for (Map.Entry<String, Float> entryBoost : petStatBoots.entrySet()) { + try { + float value = Float.parseFloat(replacements.get(entryBoost.getKey())); + replacements.put( + entryBoost.getKey(), + String.valueOf((int) Math.floor(value + entryBoost.getValue())) + ); + } catch (Exception ignored) { + } } - } - } - if (petStatBootsMult != null) { - for (Map.Entry<String, Float> entryBoost : petStatBootsMult.entrySet()) { - try { - float value = Float.parseFloat(replacements.get(entryBoost.getKey())); - replacements.put(entryBoost.getKey(), String.valueOf((int) Math.floor(value * entryBoost.getValue()))); - } catch (Exception ignored) { + } + if (petStatBootsMult != null) { + for (Map.Entry<String, Float> entryBoost : petStatBootsMult.entrySet()) { + try { + float value = Float.parseFloat(replacements.get(entryBoost.getKey())); + replacements.put( + entryBoost.getKey(), + String.valueOf((int) Math.floor(value * entryBoost.getValue())) + ); + } catch (Exception ignored) { + } } } } - } - NBTTagCompound tag = stack.getTagCompound() == null ? new NBTTagCompound() : stack.getTagCompound(); - if (tag.hasKey("display", 10)) { - NBTTagCompound display = tag.getCompoundTag("display"); - if (display.hasKey("Lore", 9)) { - NBTTagList newLore = new NBTTagList(); - NBTTagList lore = display.getTagList("Lore", 8); - HashMap<Integer, Integer> blankLocations = new HashMap<>(); - for (int j = 0; j < lore.tagCount(); j++) { - String line = lore.getStringTagAt(j); - if (line.trim().isEmpty()) { - blankLocations.put(blankLocations.size(), j); - } - for (Map.Entry<String, String> replacement : replacements.entrySet()) { - line = line.replace("{" + replacement.getKey() + "}", replacement.getValue()); + NBTTagCompound tag = stack.getTagCompound() == null ? new NBTTagCompound() : stack.getTagCompound(); + if (tag.hasKey("display", 10)) { + NBTTagCompound display = tag.getCompoundTag("display"); + if (display.hasKey("Lore", 9)) { + NBTTagList newLore = new NBTTagList(); + NBTTagList lore = display.getTagList("Lore", 8); + HashMap<Integer, Integer> blankLocations = new HashMap<>(); + for (int j = 0; j < lore.tagCount(); j++) { + String line = lore.getStringTagAt(j); + if (line.trim().isEmpty()) { + blankLocations.put(blankLocations.size(), j); + } + for (Map.Entry<String, String> replacement : replacements.entrySet()) { + line = line.replace("{" + replacement.getKey() + "}", replacement.getValue()); + } + newLore.appendTag(new NBTTagString(line)); } - newLore.appendTag(new NBTTagString(line)); - } - Integer secondLastBlank = blankLocations.get(blankLocations.size() - 2); - if (skin != null) { - JsonObject petSkin = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("PET_SKIN_" + skin); - if (petSkin != null) { - try { - NBTTagCompound nbt = JsonToNBT.getTagFromJson(petSkin.get("nbttag").getAsString()); - tag.setTag("SkullOwner", nbt.getTag("SkullOwner")); - String name = petSkin.get("displayname").getAsString(); - if (name != null) { - name = Utils.cleanColour(name); - newLore.set(0, new NBTTagString(newLore.get(0).toString().replace("\"", "") + ", " + name)); + Integer secondLastBlank = blankLocations.get(blankLocations.size() - 2); + if (skin != null) { + JsonObject petSkin = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("PET_SKIN_" + skin); + if (petSkin != null) { + try { + NBTTagCompound nbt = JsonToNBT.getTagFromJson(petSkin.get("nbttag").getAsString()); + tag.setTag("SkullOwner", nbt.getTag("SkullOwner")); + String name = petSkin.get("displayname").getAsString(); + if (name != null) { + name = Utils.cleanColour(name); + newLore.set(0, new NBTTagString(newLore.get(0).toString().replace("\"", "") + ", " + name)); + } + } catch (NBTException e) { + e.printStackTrace(); } - } catch (NBTException e) { - e.printStackTrace(); } } - } - for (int i = 0; i < newLore.tagCount(); i++) { - String cleaned = Utils.cleanColour(newLore.get(i).toString()); - if (cleaned.equals("\"Right-click to add this pet to\"")) { - newLore.removeTag(i + 1); - newLore.removeTag(i); - secondLastBlank = i - 1; - break; + for (int i = 0; i < newLore.tagCount(); i++) { + String cleaned = Utils.cleanColour(newLore.get(i).toString()); + if (cleaned.equals("\"Right-click to add this pet to\"")) { + newLore.removeTag(i + 1); + newLore.removeTag(i); + secondLastBlank = i - 1; + break; + } } - } - NBTTagList temp = new NBTTagList(); - for (int i = 0; i < newLore.tagCount(); i++) { - temp.appendTag(newLore.get(i)); - if (secondLastBlank != null && i == secondLastBlank) { - if (heldItem != null) { - temp.appendTag(new NBTTagString( - EnumChatFormatting.GOLD + "Held Item: " + heldItemJson.get("displayname").getAsString())); - int blanks = 0; - JsonArray heldItemLore = heldItemJson.get("lore").getAsJsonArray(); - for (int k = 0; k < heldItemLore.size(); k++) { - String heldItemLine = heldItemLore.get(k).getAsString(); - if (heldItemLine.trim().isEmpty()) { - blanks++; - } else if (blanks == 2) { - temp.appendTag(new NBTTagString(heldItemLine)); - } else if (blanks > 2) { - break; + NBTTagList temp = new NBTTagList(); + for (int i = 0; i < newLore.tagCount(); i++) { + temp.appendTag(newLore.get(i)); + if (secondLastBlank != null && i == secondLastBlank) { + if (heldItem != null) { + temp.appendTag(new NBTTagString( + EnumChatFormatting.GOLD + "Held Item: " + heldItemJson.get("displayname").getAsString())); + int blanks = 0; + JsonArray heldItemLore = heldItemJson.get("lore").getAsJsonArray(); + for (int k = 0; k < heldItemLore.size(); k++) { + String heldItemLine = heldItemLore.get(k).getAsString(); + if (heldItemLine.trim().isEmpty()) { + blanks++; + } else if (blanks == 2) { + temp.appendTag(new NBTTagString(heldItemLine)); + } else if (blanks > 2) { + break; + } } + temp.appendTag(new NBTTagString()); } - temp.appendTag(new NBTTagString()); - } - if (candy != 0) { - temp.appendTag(new NBTTagString(EnumChatFormatting.GREEN + "(" + candy + "/10) Pet Candy Used")); - temp.appendTag(new NBTTagString()); + if (candy != 0) { + temp.appendTag(new NBTTagString(EnumChatFormatting.GREEN + "(" + candy + "/10) Pet Candy Used")); + temp.appendTag(new NBTTagString()); + } + temp.removeTag(temp.tagCount() - 1); } - temp.removeTag(temp.tagCount() - 1); } + newLore = temp; + display.setTag("Lore", newLore); } - newLore = temp; - display.setTag("Lore", newLore); - } - if (display.hasKey("Name", 8)) { - String displayName = display.getString("Name"); - for (Map.Entry<String, String> replacement : replacements.entrySet()) { - displayName = displayName.replace("{" + replacement.getKey() + "}", replacement.getValue()); + if (display.hasKey("Name", 8)) { + String displayName = display.getString("Name"); + for (Map.Entry<String, String> replacement : replacements.entrySet()) { + displayName = displayName.replace("{" + replacement.getKey() + "}", replacement.getValue()); + } + display.setTag("Name", new NBTTagString(displayName)); } - display.setTag("Name", new NBTTagString(displayName)); + tag.setTag("display", display); } - tag.setTag("display", display); - } - stack.setTagCompound(tag); + stack.setTagCompound(tag); + } sortedPetsStack.add(stack); } } @@ -2113,7 +2279,12 @@ public class GuiProfileViewer extends GuiScreen { } if (selectedPet >= 0) { - ItemStack petStack = sortedPetsStack.get(selectedPet); + ItemStack petStack; + if (sortedPetsStack.size() <= selectedPet) { + petStack = getQuestionmarkSkull(); + } else { + petStack = sortedPetsStack.get(selectedPet); + } String display = petStack.getDisplayName(); JsonObject pet = sortedPets.get(selectedPet); @@ -2198,16 +2369,6 @@ public class GuiProfileViewer extends GuiScreen { } } - 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 void drawColsPage(int mouseX, int mouseY, float partialTicks) { Minecraft.getMinecraft().getTextureManager().bindTexture(pv_cols); Utils.drawTexturedRect(guiLeft, guiTop, sizeX, sizeY, GL11.GL_NEAREST); @@ -2434,34 +2595,6 @@ public class GuiProfileViewer extends GuiScreen { //190 } - private static final LinkedHashMap<String, ItemStack> invNameToDisplayMap = new LinkedHashMap<String, ItemStack>() {{ - 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")); - }}; - public int countItemsInInventory( String internalname, JsonObject inventoryInfo, @@ -2487,10 +2620,6 @@ public class GuiProfileViewer extends GuiScreen { return count; } - 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 ItemStack[] findBestItems( JsonObject inventoryInfo, int numItems, @@ -2568,8 +2697,6 @@ public class GuiProfileViewer extends GuiScreen { return 0; } - private final ItemStack fillerStack = new ItemStack(Item.getItemFromBlock(Blocks.stained_glass_pane), 1, 15); - public ItemStack[][][] getItemsForInventory(JsonObject inventoryInfo, String invName) { if (inventoryItems.containsKey(invName)) return inventoryItems.get(invName); @@ -2681,20 +2808,6 @@ public class GuiProfileViewer extends GuiScreen { return inventories; } - private ItemStack[] bestWeapons = null; - private ItemStack[] bestRods = null; - private ItemStack[] armorItems = null; - private HashMap<String, ItemStack[][][]> 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 final GuiElementTextField inventoryTextField = new GuiElementTextField("", GuiElementTextField.SCALE_TEXT); - private ItemStack lastBackpack; - private int lastBackpackX; - private int lastBackpackY; - private void drawInvsPage(int mouseX, int mouseY, float partialTicks) { Minecraft.getMinecraft().getTextureManager().bindTexture(pv_invs); Utils.drawTexturedRect(guiLeft, guiTop, sizeX, sizeY, GL11.GL_NEAREST); @@ -2973,13 +3086,6 @@ public class GuiProfileViewer extends GuiScreen { return entityPlayer; } - private EntityOtherPlayerMP entityPlayer = null; - private ResourceLocation playerLocationSkin = null; - private ResourceLocation playerLocationCape = null; - private String skinType = null; - - private final HashMap<String, ResourceLocation[]> panoramasMap = new HashMap<>(); - public ResourceLocation[] getPanoramasForLocation(String location, String identifier) { if (panoramasMap.containsKey(location + identifier)) return panoramasMap.get(location + identifier); try { @@ -3012,9 +3118,6 @@ public class GuiProfileViewer extends GuiScreen { } } - private TreeMap<Integer, Set<String>> topKills = null; - private TreeMap<Integer, Set<String>> topDeaths = null; - private void drawExtraPage(int mouseX, int mouseY, float partialTicks) { FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; @@ -3686,7 +3789,17 @@ public class GuiProfileViewer extends GuiScreen { (int) (guiTop + yStartTop + 138), mouseX, mouseY, - () -> Lists.newArrayList( + () -> miningSpeed != 50 && miningSpeed != 0 ? Lists.newArrayList( + "Mining Speed", + EnumChatFormatting.GRAY + "Level " + miningSpeed + EnumChatFormatting.DARK_GRAY + "/50", + "", + EnumChatFormatting.GRAY + "Grants " + EnumChatFormatting.GREEN + "+" + miningSpeedStat + + EnumChatFormatting.GOLD + " ⸕ Mining", + EnumChatFormatting.GOLD + "Speed" + EnumChatFormatting.GRAY + ".", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + (int) Math.pow(miningSpeed + 2, 3) + " Mithril Powder" + ) : Lists.newArrayList( "Mining Speed", EnumChatFormatting.GRAY + "Level " + miningSpeed + EnumChatFormatting.DARK_GRAY + "/50", "", @@ -3701,7 +3814,17 @@ public class GuiProfileViewer extends GuiScreen { miningFortune, (int) (guiLeft + xStart + 255), (int) (guiTop + yStartTop + 114), mouseX, mouseY, - () -> Lists.newArrayList( + () -> miningFortune != 0 && miningFortune != 50 ? Lists.newArrayList( + "Mining Fortune", + EnumChatFormatting.GRAY + "Level " + miningFortune + EnumChatFormatting.DARK_GRAY + "/50", + "", + EnumChatFormatting.GRAY + "Grants " + EnumChatFormatting.GREEN + "+" + miningFortuneStat + + EnumChatFormatting.GOLD + " ☘ Mining", + EnumChatFormatting.GOLD + "Fortune" + EnumChatFormatting.GRAY + ".", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + (int) Math.pow(miningFortune + 2, 3.05) + " Mithril Powder" + ) : Lists.newArrayList( "Mining Fortune", EnumChatFormatting.GRAY + "Level " + miningFortune + EnumChatFormatting.DARK_GRAY + "/50", "", @@ -3716,7 +3839,19 @@ public class GuiProfileViewer extends GuiScreen { tittyInsane, (int) (guiLeft + xStart + 231), (int) (guiTop + yStartTop + 114), mouseX, mouseY, - () -> Lists.newArrayList( + () -> tittyInsane != 0 && tittyInsane != 50 ? Lists.newArrayList( + "Titanium Insanium", + EnumChatFormatting.GRAY + "Level " + tittyInsane + EnumChatFormatting.DARK_GRAY + "/50", + "", + EnumChatFormatting.GRAY + "When mining Mithril Ore, you", + EnumChatFormatting.GRAY + "have a " + EnumChatFormatting.GREEN + tittyInsaneStat + "% " + + EnumChatFormatting.GRAY + "chance to", + EnumChatFormatting.GRAY + "convert the block into Titanium", + EnumChatFormatting.GRAY + "Ore.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + (int) Math.pow(tittyInsane + 2, 3.1) + " Mithril Powder" + ) : Lists.newArrayList( "Titanium Insanium", EnumChatFormatting.GRAY + "Level " + tittyInsane + EnumChatFormatting.DARK_GRAY + "/50", "", @@ -3771,7 +3906,17 @@ public class GuiProfileViewer extends GuiScreen { luckofcave, (int) (guiLeft + xStart + 207), (int) (guiTop + yStartTop + 90), mouseX, mouseY, - () -> Lists.newArrayList( + () -> luckofcave != 0 && luckofcave != 45 ? Lists.newArrayList( + "Luck of the Cave", + "§7Level " + luckofcave + EnumChatFormatting.DARK_GRAY + "/45", + "", + "§7Increases the chance for you to", + "§7trigger rare occurrences im", + "§2Dwarven Mines " + EnumChatFormatting.GRAY + "by " + EnumChatFormatting.GREEN + luckofcaveStat + "%§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + (int) Math.pow(luckofcave + 2, 3.07) + " Mithril Powder" + ) : Lists.newArrayList( "Luck of the Cave", "§7Level " + luckofcave + EnumChatFormatting.DARK_GRAY + "/45", "", @@ -3786,7 +3931,18 @@ public class GuiProfileViewer extends GuiScreen { dailyPowder, (int) (guiLeft + xStart + 255), (int) (guiTop + yStartTop + 90), mouseX, mouseY, - () -> Lists.newArrayList( + () -> dailyPowder != 0 && dailyPowder != 100 ? Lists.newArrayList( + "Daily Powder", + EnumChatFormatting.GRAY + "Level " + dailyPowder + EnumChatFormatting.DARK_GRAY + "/100", + "", + EnumChatFormatting.GRAY + "Gains " + EnumChatFormatting.GREEN + dailyPowderStat + " Powder" + + EnumChatFormatting.GRAY + " from the", + EnumChatFormatting.GRAY + "first ore you mine every day.", + EnumChatFormatting.GRAY + "Works for all Powder types.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + (200 + ((dailyPowder) * 18)) + " Mithril Powder" + ) : Lists.newArrayList( "Daily Powder", EnumChatFormatting.GRAY + "Level " + dailyPowder + EnumChatFormatting.DARK_GRAY + "/100", "", @@ -3803,7 +3959,18 @@ public class GuiProfileViewer extends GuiScreen { effMiner, (int) (guiLeft + xStart + 255), (int) (guiTop + yStartTop + 66), mouseX, mouseY, - () -> Lists.newArrayList( + () -> effMiner != 0 && effMiner != 100 ? Lists.newArrayList( + "Efficient Miner", + EnumChatFormatting.GRAY + "Level " + effMiner + EnumChatFormatting.DARK_GRAY + "/100", + "", + EnumChatFormatting.GRAY + "When mining ores, you have a", + EnumChatFormatting.GREEN + "" + effMinerStat + "%" + EnumChatFormatting.GRAY + " chance to mine " + + EnumChatFormatting.GREEN + Math.round(finalEffMinerStat2), + EnumChatFormatting.GRAY + "adjacent ores.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + (int) Math.pow(effMiner + 2, 2.6) + " Mithril Powder" + ) : Lists.newArrayList( "Efficient Miner", EnumChatFormatting.GRAY + "Level " + effMiner + EnumChatFormatting.DARK_GRAY + "/100", "", @@ -3824,7 +3991,10 @@ public class GuiProfileViewer extends GuiScreen { case 0: return Lists.newArrayList( EnumChatFormatting.RED + "Peak of the Mountain", - EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/5" + EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/5", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "50000 Mithril Powder" ); case 1: return Lists.newArrayList( @@ -3832,7 +4002,10 @@ public class GuiProfileViewer extends GuiScreen { EnumChatFormatting.GRAY + "Level " + potm + EnumChatFormatting.DARK_GRAY + "/5", "", "§7§8+§c1 Pickaxe Ability Level", - "§7§8+§51 Token of the Mountain" + "§7§8+§51 Token of the Mountain", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "50000 Mithril Powder" ); case 2: return Lists.newArrayList( @@ -3841,7 +4014,10 @@ public class GuiProfileViewer extends GuiScreen { "", "§7§8+§c1 Pickaxe Ability Level", "§7§8+§51 Token of the Mountain", - "§7§8+§a1 Forge Slot" + "§7§8+§a1 Forge Slot", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "75000 Mithril Powder" ); case 3: return Lists.newArrayList( @@ -3851,7 +4027,10 @@ public class GuiProfileViewer extends GuiScreen { "§7§8+§c1 Pickaxe Ability Level", "§7§8+§51 Token of the Mountain", "§7§8+§a1 Forge Slot", - "§7§8+§a1 Commission Slot" + "§7§8+§a1 Commission Slot", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "100000 Mithril Powder" ); case 4: return Lists.newArrayList( @@ -3863,7 +4042,10 @@ public class GuiProfileViewer extends GuiScreen { "§7§8+§a1 Forge Slot", "§7§8+§a1 Commission Slot", "§7§8+§21 Mithril Powder §7when", - "§7mining §fMithril" + "§7mining §fMithril", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "125000 Mithril Powder" ); case 5: return Lists.newArrayList( @@ -3890,7 +4072,19 @@ public class GuiProfileViewer extends GuiScreen { mole, (int) (guiLeft + xStart + 255), (int) (guiTop + yStartTop + 18), mouseX, mouseY, - () -> Lists.newArrayList( + () -> mole != 0 && mole != 190 ? Lists.newArrayList( + "Mole", + EnumChatFormatting.GRAY + "Level " + mole + EnumChatFormatting.DARK_GRAY + "/190", + "", + EnumChatFormatting.GRAY + "When mining hard stone, you have", + EnumChatFormatting.GRAY + "a " + EnumChatFormatting.GREEN + finalOutput + "% " + EnumChatFormatting.GRAY + + "chance to mine " + EnumChatFormatting.GREEN, + EnumChatFormatting.GREEN + "" + Math.round(moleStat) + EnumChatFormatting.GRAY + " adjacent hard stone block" + + (moleStat == 1.0 ? "." : "s."), + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + (int) Math.pow(mole + 2, 2.2) + " Gemstone Powder" + ) : Lists.newArrayList( "Mole", EnumChatFormatting.GRAY + "Level " + mole + EnumChatFormatting.DARK_GRAY + "/190", "", @@ -3907,7 +4101,17 @@ public class GuiProfileViewer extends GuiScreen { powderBuff, (int) (guiLeft + xStart + 255), (int) (guiTop + yStartTop - 6), mouseX, mouseY, - () -> Lists.newArrayList( + () -> powderBuff != 0 && powderBuff != 50 ? Lists.newArrayList( + "Powder Buff", + EnumChatFormatting.GRAY + "Level " + powderBuff + EnumChatFormatting.DARK_GRAY + "/50", + "", + EnumChatFormatting.GRAY + "Gain " + EnumChatFormatting.GREEN + powderBuff + "% " + EnumChatFormatting.GRAY + + "more Mithril", + EnumChatFormatting.GRAY + "Powder and Gemstone Powder§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + (int) Math.pow(powderBuff + 2, 3.2) + " Gemstone Powder" + ) : Lists.newArrayList( "Powder Buff", EnumChatFormatting.GRAY + "Level " + powderBuff + EnumChatFormatting.DARK_GRAY + "/50", "", @@ -3960,7 +4164,16 @@ public class GuiProfileViewer extends GuiScreen { seasonMine, (int) (guiLeft + xStart + 231), (int) (guiTop + yStartTop + 66), mouseX, mouseY, - () -> Lists.newArrayList( + () -> seasonMine != 0 && seasonMine != 100 ? Lists.newArrayList( + "Seasoned Mineman", + "§7Level " + seasonMine + "§8/100", + "", + "§7Increases your Mining", + "§7experience gain by " + EnumChatFormatting.GREEN + seasonMineStat + "%§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + (int) Math.pow(seasonMine + 2, 2.3) + " Mithril Powder" + ) : Lists.newArrayList( "Seasoned Mineman", "§7Level " + seasonMine + "§8/100", "", @@ -3986,7 +4199,7 @@ public class GuiProfileViewer extends GuiScreen { lonesomeMiner, (int) (guiLeft + xStart + 207), (int) (guiTop + yStartTop + 18), mouseX, mouseY, - () -> Lists.newArrayList( + () -> lonesomeMiner != 0 && lonesomeMiner != 45 ? Lists.newArrayList( "Lonesome Miner", "§7Level " + lonesomeMiner + EnumChatFormatting.DARK_GRAY + "/45", "", @@ -3994,7 +4207,18 @@ public class GuiProfileViewer extends GuiScreen { "§9Chance, §9☠ Crit Damage, §a❈", "§aDefense, and §c❤ Health", "§c§7statistics gain by " + EnumChatFormatting.GREEN + lonesomeMinerStat + "%§7", - "§7while in the Crystal Hollows." + "§7while in the Crystal Hollows.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + (int) Math.pow(lonesomeMiner + 2, 3.07) + " Gemstone Powder" + ) : Lists.newArrayList( + "Lonesome Miner", + "§7Level " + lonesomeMiner + EnumChatFormatting.DARK_GRAY + "/45", + "", + "§7Increases §c❁ Strength, §9☣ Crit", + "§9Chance, §9☠ Crit Damage, §a❈", + "§aDefense, and §c❤ Health", + "§c§7statistics gain by " + EnumChatFormatting.GREEN + lonesomeMinerStat + "%§7" ), 45 ); @@ -4003,7 +4227,16 @@ public class GuiProfileViewer extends GuiScreen { professional, (int) (guiLeft + xStart + 231), (int) (guiTop + yStartTop + 18), mouseX, mouseY, - () -> Lists.newArrayList( + () -> professional != 0 && professional != 140 ? Lists.newArrayList( + "Professional", + "§7Level " + professional + EnumChatFormatting.DARK_GRAY + "/140", + "", + "§7Gain §a+" + professionalStat + "§6 ⸕ Mining", + "§6Speed§7 when mining Gemstones.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + (int) Math.pow(professional + 2, 2.3) + " Gemstone Powder" + ) : Lists.newArrayList( "Professional", "§7Level " + professional + EnumChatFormatting.DARK_GRAY + "/140", "", @@ -4017,7 +4250,16 @@ public class GuiProfileViewer extends GuiScreen { miningSpeed2, (int) (guiLeft + xStart + 207), (int) (guiTop + yStartTop - 6), mouseX, mouseY, - () -> Lists.newArrayList( + () -> miningSpeed2 != 0 && miningSpeed2 != 50 ? Lists.newArrayList( + "Mining Speed 2", + "§7Level " + miningSpeed2 + EnumChatFormatting.DARK_GRAY + "/50", + "", + "§7Grants " + EnumChatFormatting.GREEN + "+" + miningSpeed2Stat + EnumChatFormatting.GOLD + " ⸕ Mining", + "§6Speed§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + (int) Math.pow(miningSpeed2 + 2, 3.2) + " Gemstone Powder" + ) : Lists.newArrayList( "Mining Speed 2", "§7Level " + miningSpeed2 + EnumChatFormatting.DARK_GRAY + "/50", "", @@ -4031,7 +4273,16 @@ public class GuiProfileViewer extends GuiScreen { quickForge, (int) (guiLeft + xStart + 279), (int) (guiTop + yStartTop + 114), mouseX, mouseY, - () -> Lists.newArrayList( + () -> quickForge != 0 && quickForge != 20 ? Lists.newArrayList( + "Quick Forge", + "§7Level " + quickForge + EnumChatFormatting.DARK_GRAY + "/20", + "", + "§7Decreases the time it takes to", + "§7forge by §a" + (quickForgeStat < 20 ? quickForgeStat : 30) + "%§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + (int) Math.pow(quickForge + 2, 4) + " Mithril Powder" + ) : Lists.newArrayList( "Quick Forge", "§7Level " + quickForge + EnumChatFormatting.DARK_GRAY + "/20", "", @@ -4045,7 +4296,16 @@ public class GuiProfileViewer extends GuiScreen { fortunate, (int) (guiLeft + xStart + 279), (int) (guiTop + yStartTop + 18), mouseX, mouseY, - () -> Lists.newArrayList( + () -> fortunate != 0 && fortunate != 20 ? Lists.newArrayList( + "Fortunate", + "§7Level " + fortunate + EnumChatFormatting.DARK_GRAY + "/20", + "", + "§7Gain " + EnumChatFormatting.GREEN + "+" + fortunateStat + " §6☘ Mining", + "§6Fortune§7 when mining Gemstone.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + (int) Math.pow(fortunate + 2, 3.05) + " Mithril Powder" + ) : Lists.newArrayList( "Fortunate", "§7Level " + fortunate + EnumChatFormatting.DARK_GRAY + "/20", "", @@ -4059,7 +4319,16 @@ public class GuiProfileViewer extends GuiScreen { greatExplorer, (int) (guiLeft + xStart + 303), (int) (guiTop + yStartTop + 18), mouseX, mouseY, - () -> Lists.newArrayList( + () -> greatExplorer != 0 && greatExplorer != 20 ? Lists.newArrayList( + "Great Explorer", + "§7Level " + greatExplorer + EnumChatFormatting.DARK_GRAY + "/20", + "", + "§7Grants " + EnumChatFormatting.GREEN + "+" + greatExplorerStat + "% " + EnumChatFormatting.GRAY + "chance to", + "§7find treasure.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + (int) Math.pow(greatExplorer + 2, 4) + " Gemstone Powder" + ) : Lists.newArrayList( "Great Explorer", "§7Level " + greatExplorer + EnumChatFormatting.DARK_GRAY + "/20", "", @@ -4073,7 +4342,15 @@ public class GuiProfileViewer extends GuiScreen { miningFortune2, (int) (guiLeft + xStart + 303), (int) (guiTop + yStartTop - 6), mouseX, mouseY, - () -> Lists.newArrayList( + () -> miningFortune2 != 0 && miningFortune2 != 50 ? Lists.newArrayList( + "Mining Fortune 2", + "§7Level " + miningFortune2 + EnumChatFormatting.DARK_GRAY + "/50", + "", + "§7Grants §a+§a" + miningFortune2Stat + "§7 §6☘ Mining", "§6Fortune§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.LIGHT_PURPLE + "" + (int) Math.pow(miningFortune2 + 2, 3.2) + " Gemstone Powder" + ) : Lists.newArrayList( "Mining Fortune 2", "§7Level " + miningFortune2 + EnumChatFormatting.DARK_GRAY + "/50", "", @@ -4086,7 +4363,17 @@ public class GuiProfileViewer extends GuiScreen { orbit, (int) (guiLeft + xStart + 279), (int) (guiTop + yStartTop + 66), mouseX, mouseY, - () -> Lists.newArrayList( + () -> orbit != 0 && orbit != 80 ? Lists.newArrayList( + "Orbiter", + "§7Level " + orbit + EnumChatFormatting.DARK_GRAY + "/80", + "", + "§7When mining ores, you have a", + EnumChatFormatting.GREEN + "" + orbitStat + "%" + EnumChatFormatting.GRAY + " chance to get a random", + "§7amount of experience orbs.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + (int) ((orbit + 1) * 70) + " Mithril Powder" + ) : Lists.newArrayList( "Orbiter", "§7Level " + orbit + EnumChatFormatting.DARK_GRAY + "/80", "", @@ -4142,7 +4429,18 @@ public class GuiProfileViewer extends GuiScreen { crystallized, (int) (guiLeft + xStart + 303), (int) (guiTop + yStartTop + 90), mouseX, mouseY, - () -> Lists.newArrayList( + () -> crystallized != 0 && crystallized != 30 ? Lists.newArrayList( + "Crystallized", + "§7Level " + crystallized + EnumChatFormatting.DARK_GRAY + "/30", + "", + "§7Grants §a+§a" + crystallizedStat + "§7 §6⸕ Mining", + "§6Speed §7and a §a" + crystallizedStat + "%§7 §7chance", + "§7to deal §a+1 §7extra damage near", + "§7§5Fallen Stars§7.", + "", + EnumChatFormatting.GRAY + "Cost", + EnumChatFormatting.DARK_GREEN + "" + (int) Math.pow(crystallized + 2, 2.4) + " Mithril Powder" + ) : Lists.newArrayList( "Crystallized", "§7Level " + crystallized + EnumChatFormatting.DARK_GRAY + "/30", "", @@ -4351,31 +4649,6 @@ public class GuiProfileViewer extends GuiScreen { return null; } - private int backgroundClickedX = -1; - - private static final char[] c = new char[]{'k', 'm', 'b', 't'}; - - 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)); - } - - private boolean loadingProfile = false; - private static final ExecutorService profileLoader = Executors.newFixedThreadPool(1); - private void drawBasicPage(int mouseX, int mouseY, float partialTicks) { FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; @@ -4909,89 +5182,6 @@ public class GuiProfileViewer extends GuiScreen { } } - private static final ResourceLocation shadowTextures = new ResourceLocation("textures/misc/shadow.png"); - - 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); - - /*{ - GlStateManager.enableBlend(); - GlStateManager.blendFunc(770, 771); - rendermanager.renderEngine.bindTexture(shadowTextures); - GlStateManager.depthMask(false); - float f = 0.5f; - - if (ent instanceof EntityLiving) { - EntityLiving entityliving = (EntityLiving)ent; - f *= entityliving.getRenderSizeModifier(); - - if (entityliving.isChild()) - { - f *= 0.5F; - } - } - - /*Tessellator tessellator = Tessellator.getInstance(); - WorldRenderer worldrenderer = tessellator.getWorldRenderer(); - worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); - - GlStateManager.color(1, 1, 1, 0.5f); - Utils.drawTexturedRect(-0.5f*tl.x, -0.5f*tl.x, 1*tl.x, 1*tl.x); - - /*for (BlockPos blockpos : BlockPos.getAllInBoxMutable(new BlockPos(i, k, i1), new BlockPos(j, l, j1))) { - Block block = world.getBlockState(blockpos.down()).getBlock(); - - if (block.getRenderType() != -1 && world.getLightFromNeighbors(blockpos) > 3) { - this.func_180549_a(block, x, y, z, blockpos, shadowAlpha, f, d2, d3, d4); - } - } - - GlStateManager.disableBlend(); - GlStateManager.depthMask(true); - }*/ - - 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 void resetCache() { bestWeapons = null; bestRods = null; @@ -5011,11 +5201,6 @@ public class GuiProfileViewer extends GuiScreen { selectedPet = -1; } - Shader blurShaderHorz = null; - Framebuffer blurOutputHorz = null; - Shader blurShaderVert = null; - Framebuffer blurOutputVert = null; - /** * Creates a projection matrix that projects from our coordinate space [0->width; 0->height] to OpenGL coordinate * space [-1 -> 1; 1 -> -1] (Note: flipped y-axis). @@ -5036,14 +5221,6 @@ public class GuiProfileViewer extends GuiScreen { return projMatrix; } - /** - * Renders whatever is currently in the Minecraft framebuffer to our two framebuffers, applying a horizontal - * and vertical blur separately in order to significantly save computation time. - * This is only possible if framebuffers are supported by the system, so this method will exit prematurely - * if framebuffers are not available. (Apple machines, for example, have poor framebuffer support). - */ - private double lastBgBlurFactor = -1; - private void blurBackground() { if (!OpenGlHelper.isFramebufferEnabled()) return; @@ -5124,4 +5301,44 @@ public class GuiProfileViewer extends GuiScreen { //Utils.setScreen(width, height, f); blurOutputVert.unbindFramebufferTexture(); } + + public enum ProfileViewerPage { + LOADING(-1, null), + INVALID_NAME(-1, null), + NO_SKYBLOCK(-1, null), + BASIC(0, new ItemStack(Items.paper)), + DUNGEON(1, new ItemStack(Item.getItemFromBlock(Blocks.deadbush))), + EXTRA(2, new ItemStack(Items.book)), + INVENTORIES(3, new ItemStack(Item.getItemFromBlock(Blocks.ender_chest))), + COLLECTIONS(4, new ItemStack(Items.painting)), + PETS(5, new ItemStack(Items.bone)), + MINING(6, new ItemStack(Items.iron_pickaxe)), + BINGO(7, new ItemStack(Items.filled_map)); + + public final ItemStack stack; + public final int id; + + ProfileViewerPage(int id, ItemStack stack) { + this.id = id; + this.stack = stack; + } + + public static ProfileViewerPage getById(int id) { + for (ProfileViewerPage page : values()) { + if (page.id == id) { + return page; + } + } + return null; + } + } + + public static class PetLevel { + public float level; + public float currentLevelRequirement; + public float maxXP; + public float levelPercentage; + public float levelXp; + public float totalXp; + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java index 674f08af..b8f8554e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java @@ -27,12 +27,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class ProfileViewer { - private final NEUManager manager; - - public ProfileViewer(NEUManager manager) { - this.manager = manager; - } - private static final HashMap<String, String> petRarityToNumMap = new HashMap<String, String>() {{ put("COMMON", "0"); put("UNCOMMON", "1"); @@ -41,7 +35,6 @@ public class ProfileViewer { put("LEGENDARY", "4"); put("MYTHIC", "5"); }}; - private static final LinkedHashMap<String, ItemStack> skillToSkillDisplayMap = new LinkedHashMap<String, ItemStack>() {{ put("skill_taming", Utils.createItemStack(Items.spawn_egg, EnumChatFormatting.LIGHT_PURPLE + "Taming")); @@ -72,7 +65,6 @@ public class ProfileViewer { put("slayer_wolf", Utils.createItemStack(Items.bone, EnumChatFormatting.GOLD + "Sven Slayer")); put("slayer_enderman", Utils.createItemStack(Items.ender_pearl, EnumChatFormatting.GOLD + "Ender Slayer")); }}; - private static final ItemStack CAT_FARMING = Utils.createItemStack(Items.golden_hoe, EnumChatFormatting.YELLOW + "Farming"); private static final ItemStack CAT_MINING = @@ -83,7 +75,6 @@ public class ProfileViewer { Utils.createItemStack(Item.getItemFromBlock(Blocks.sapling), EnumChatFormatting.DARK_GREEN + "Foraging"); private static final ItemStack CAT_FISHING = Utils.createItemStack(Items.fishing_rod, EnumChatFormatting.AQUA + "Fishing"); - private static final LinkedHashMap<ItemStack, List<String>> collectionCatToCollectionMap = new LinkedHashMap<ItemStack, List<String>>() {{ put(CAT_FARMING, Utils.createList("WHEAT", "CARROT_ITEM", "POTATO_ITEM", "PUMPKIN", "MELON", "SEEDS", @@ -103,7 +94,6 @@ public class ProfileViewer { )); }}; - private static final LinkedHashMap<ItemStack, List<String>> collectionCatToMinionMap = new LinkedHashMap<ItemStack, List<String>>() {{ put(CAT_FARMING, Utils.createList("WHEAT", "CARROT", "POTATO", "PUMPKIN", "MELON", null, "MUSHROOM", @@ -120,7 +110,6 @@ public class ProfileViewer { put(CAT_FISHING, Utils.createList("FISHING", null, null, null, null, null, "CLAY", null, null, null)); }}; - private static final LinkedHashMap<String, ItemStack> collectionToCollectionDisplayMap = new LinkedHashMap<String, ItemStack>() {{ /* FARMING COLLECTIONS */ @@ -244,6 +233,17 @@ public class ProfileViewer { put("INK_SACK", Utils.createItemStack(Items.dye, EnumChatFormatting.AQUA + "Ink Sack")); put("SPONGE", Utils.createItemStack(Item.getItemFromBlock(Blocks.sponge), EnumChatFormatting.AQUA + "Sponge")); }}; + private static final AtomicBoolean updatingResourceCollection = new AtomicBoolean(false); + private static JsonObject resourceCollection = null; + private final NEUManager manager; + private final HashMap<String, JsonObject> nameToHypixelProfile = new HashMap<>(); + private final HashMap<String, JsonObject> uuidToHypixelProfile = new HashMap<>(); + private final HashMap<String, Profile> uuidToProfileMap = new HashMap<>(); + private final HashMap<String, String> nameToUuid = new HashMap<>(); + + public ProfileViewer(NEUManager manager) { + this.manager = manager; + } public static LinkedHashMap<ItemStack, List<String>> getCollectionCatToMinionMap() { return collectionCatToMinionMap; @@ -261,13 +261,6 @@ public class ProfileViewer { return Collections.unmodifiableMap(skillToSkillDisplayMap); } - public static class Level { - public float level = 0; - public float maxXpForLevel = 0; - public boolean maxed = false; - public double totalXp; - } - public static Level getLevel(JsonArray levelingArray, float xp, int levelCap, boolean cumulative) { Level levelObj = new Level(); for (int level = 0; level < levelingArray.size(); level++) { @@ -299,14 +292,135 @@ public class ProfileViewer { return levelObj; } - public class Profile { - private final String uuid; - private String latestProfile = null; + public static JsonObject getResourceCollectionInformation() { + if (resourceCollection != null) return resourceCollection; + if (updatingResourceCollection.get()) return null; - private JsonArray playerInformation = null; - private JsonObject guildInformation = null; - private JsonObject basicInfo = null; + updatingResourceCollection.set(true); + + HashMap<String, String> args = new HashMap<>(); + NotEnoughUpdates.INSTANCE.manager.hypixelApi.getHypixelApiAsync( + NotEnoughUpdates.INSTANCE.config.apiKey.apiKey, + "resources/skyblock/collections", + args, + jsonObject -> { + updatingResourceCollection.set(false); + if (jsonObject != null && jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) { + resourceCollection = jsonObject.get("collections").getAsJsonObject(); + } + }, + () -> updatingResourceCollection.set(false) + ); + + return null; + } + + public void getHypixelProfile(String name, Consumer<JsonObject> callback) { + String nameF = name.toLowerCase(); + HashMap<String, String> args = new HashMap<>(); + args.put("name", "" + nameF); + manager.hypixelApi.getHypixelApiAsync(NotEnoughUpdates.INSTANCE.config.apiKey.apiKey, "player", + args, jsonObject -> { + if (jsonObject != null && jsonObject.has("success") && jsonObject.get("success").getAsBoolean() + && jsonObject.get("player").isJsonObject()) { + nameToUuid.put(nameF, jsonObject.get("player").getAsJsonObject().get("uuid").getAsString()); + uuidToHypixelProfile.put( + jsonObject.get("player").getAsJsonObject().get("uuid").getAsString(), + jsonObject.get("player").getAsJsonObject() + ); + if (callback != null) callback.accept(jsonObject); + } else { + if (callback != null) callback.accept(null); + } + } + ); + } + + public void putNameUuid(String name, String uuid) { + nameToUuid.put(name, uuid); + } + + public void getPlayerUUID(String name, Consumer<String> uuidCallback) { + String nameF = name.toLowerCase(); + if (nameToUuid.containsKey(nameF)) { + uuidCallback.accept(nameToUuid.get(nameF)); + return; + } + + manager.hypixelApi.getApiAsync("https://api.mojang.com/users/profiles/minecraft/" + nameF, + (jsonObject) -> { + if (jsonObject.has("id") && jsonObject.get("id").isJsonPrimitive() && + ((JsonPrimitive) jsonObject.get("id")).isString()) { + String uuid = jsonObject.get("id").getAsString(); + nameToUuid.put(nameF, uuid); + uuidCallback.accept(uuid); + return; + } + uuidCallback.accept(null); + }, () -> uuidCallback.accept(null) + ); + } + + public void getProfileByName(String name, Consumer<Profile> callback) { + String nameF = name.toLowerCase(); + + if (nameToUuid.containsKey(nameF) && nameToUuid.get(nameF) == null) { + callback.accept(null); + return; + } + + getPlayerUUID(nameF, (uuid) -> { + if (uuid == null) { + getHypixelProfile(nameF, jsonObject -> { + if (jsonObject != null) { + callback.accept(getProfileReset(nameToUuid.get(nameF), ignored -> { + })); + } else { + callback.accept(null); + nameToUuid.put(nameF, null); + } + }); + } else { + if (!uuidToHypixelProfile.containsKey(uuid)) { + getHypixelProfile(nameF, jsonObject -> { + }); + } + callback.accept(getProfileReset(uuid, ignored -> { + })); + } + }); + + return; + } + + public Profile getProfileRaw(String uuid) { + return uuidToProfileMap.get(uuid); + } + + public Profile getProfile(String uuid, Consumer<Profile> callback) { + Profile profile = uuidToProfileMap.computeIfAbsent(uuid, k -> new Profile(uuid)); + if (profile.playerInformation != null) { + callback.accept(profile); + } else { + profile.getPlayerInformation(() -> callback.accept(profile)); + } + return profile; + } + + public Profile getProfileReset(String uuid, Consumer<Profile> callback) { + if (uuidToProfileMap.containsKey(uuid)) uuidToProfileMap.get(uuid).resetCache(); + return getProfile(uuid, callback); + } + public static class Level { + public float level = 0; + public float maxXpForLevel = 0; + public boolean maxed = false; + public double totalXp; + } + + public class Profile { + private final String uuid; private final HashMap<String, JsonObject> profileMap = new HashMap<>(); private final HashMap<String, JsonObject> petsInfoMap = new HashMap<>(); private final HashMap<String, List<JsonObject>> coopProfileMap = new HashMap<>(); @@ -314,27 +428,37 @@ public class ProfileViewer { private final HashMap<String, JsonObject> inventoryInfoMap = new HashMap<>(); private final HashMap<String, JsonObject> collectionInfoMap = new HashMap<>(); private final List<String> profileIds = new ArrayList<>(); - private JsonObject playerStatus = null; private final HashMap<String, PlayerStats.Stats> stats = new HashMap<>(); private final HashMap<String, PlayerStats.Stats> passiveStats = new HashMap<>(); private final HashMap<String, Long> networth = new HashMap<>(); - - public Profile(String uuid) { - this.uuid = uuid; - } - private final AtomicBoolean updatingPlayerInfoState = new AtomicBoolean(false); - private long lastPlayerInfoState = 0; private final AtomicBoolean updatingPlayerStatusState = new AtomicBoolean(false); private final AtomicBoolean updatingGuildInfoState = new AtomicBoolean(false); - private long lastGuildInfoState = 0; private final AtomicBoolean updatingGuildStatusState = new AtomicBoolean(false); + private final AtomicBoolean updatingBingoInfo = new AtomicBoolean(false); + private final Pattern COLL_TIER_PATTERN = Pattern.compile("_(-?[0-9]+)"); + private String latestProfile = null; + private JsonArray playerInformation = null; + private JsonObject guildInformation = null; + private JsonObject basicInfo = null; + private JsonObject playerStatus = null; + private JsonObject bingoInformation = null; + private long lastPlayerInfoState = 0; + private long lastStatusInfoState = 0; + private long lastGuildInfoState = 0; + private long lastBingoInfoState = 0; + + public Profile(String uuid) { + this.uuid = uuid; + } public JsonObject getPlayerStatus() { if (playerStatus != null) return playerStatus; if (updatingPlayerStatusState.get()) return null; - updatingPlayerStatusState.set(true); + long currentTime = System.currentTimeMillis(); + if (currentTime - lastStatusInfoState < 15 * 1000) return null; + lastStatusInfoState = currentTime; HashMap<String, String> args = new HashMap<>(); args.put("uuid", "" + uuid); @@ -352,6 +476,33 @@ public class ProfileViewer { return null; } + public JsonObject getBingoInformation() { + if (bingoInformation != null) return bingoInformation; + if (updatingBingoInfo.get()) return null; + + long currentTime = System.currentTimeMillis(); + if (currentTime - lastBingoInfoState < 15 * 1000) return null; + lastBingoInfoState = currentTime; + + HashMap<String, String> args = new HashMap<>(); + args.put("uuid", "" + uuid); + NotEnoughUpdates.INSTANCE.manager.hypixelApi.getHypixelApiAsync( + NotEnoughUpdates.INSTANCE.config.apiKey.apiKey, + "skyblock/bingo", + args, + jsonObject -> { + if (jsonObject == null) return; + updatingBingoInfo.set(false); + if (jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) { + bingoInformation = jsonObject; + } else { + bingoInformation = null; + } + }, () -> updatingBingoInfo.set(false) + ); + return null; + } + public long getNetWorth(String profileId) { if (profileId == null) profileId = latestProfile; if (networth.get(profileId) != null) return networth.get(profileId); @@ -442,11 +593,6 @@ public class ProfileViewer { } if (networth == 0) return -1; - //System.out.println(profileId); - //for (Map.Entry<String, Long> entry : mostExpensiveInternal.entrySet()) { - //System.out.println(entry.getKey() + ":" + entry.getValue()); - //} - networth = (int) (networth * 1.3f); JsonObject petsInfo = getPetsInfo(profileId); @@ -554,9 +700,9 @@ public class ProfileViewer { long currentTime = System.currentTimeMillis(); - if (currentTime - lastGuildInfoState < 15 * 1000 && updatingGuildInfoState.get()) return null; - + if (currentTime - lastGuildInfoState < 15 * 1000) return null; lastGuildInfoState = currentTime; + updatingGuildInfoState.set(true); HashMap<String, String> args = new HashMap<>(); @@ -1054,8 +1200,6 @@ public class ProfileViewer { return null; } - private final Pattern COLL_TIER_PATTERN = Pattern.compile("_(-?[0-9]+)"); - public JsonObject getCollectionInfo(String profileId) { JsonObject profileInfo = getProfileInformation(profileId); if (profileInfo == null) return null; @@ -1064,8 +1208,12 @@ public class ProfileViewer { if (profileId == null) profileId = latestProfile; if (collectionInfoMap.containsKey(profileId)) return collectionInfoMap.get(profileId); + List<JsonObject> coopMembers = getCoopProfileInformation(profileId); JsonElement unlocked_coll_tiers_element = Utils.getElement(profileInfo, "unlocked_coll_tiers"); JsonElement crafted_generators_element = Utils.getElement(profileInfo, "crafted_generators"); + JsonObject fakeMember = new JsonObject(); + fakeMember.add("crafted_generators", crafted_generators_element); + coopMembers.add(coopMembers.size(), fakeMember); JsonElement collectionInfoElement = Utils.getElement(profileInfo, "collection"); if (unlocked_coll_tiers_element == null || collectionInfoElement == null) { @@ -1116,17 +1264,15 @@ public class ProfileViewer { } } } - - if (crafted_generators_element != null && crafted_generators_element.isJsonArray()) { - JsonArray crafted_generators = crafted_generators_element.getAsJsonArray(); - for (int i = 0; i < crafted_generators.size(); i++) { - String unlocked = crafted_generators.get(i).getAsString(); - + for (JsonObject current_member_info : coopMembers) { + if (!current_member_info.has("crafted_generators") || !current_member_info.get("crafted_generators").isJsonArray()) continue; + JsonArray crafted_generators = Utils.getElement(current_member_info, "crafted_generators").getAsJsonArray(); + for (int j = 0; j < crafted_generators.size(); j++) { + String unlocked = crafted_generators.get(j).getAsString(); Matcher matcher = COLL_TIER_PATTERN.matcher(unlocked); - if (matcher.find()) { - String tier_str = matcher.group(1); - int tier = Integer.parseInt(tier_str); + String tierString = matcher.group(1); + int tier = Integer.parseInt(tierString); String coll = unlocked.substring(0, unlocked.length() - (matcher.group().length())); if (!minionTiers.has(coll) || minionTiers.get(coll).getAsInt() < tier) { minionTiers.addProperty(coll, tier); @@ -1221,133 +1367,4 @@ public class ProfileViewer { return null; } } - - private final HashMap<String, JsonObject> nameToHypixelProfile = new HashMap<>(); - private final HashMap<String, JsonObject> uuidToHypixelProfile = new HashMap<>(); - private final HashMap<String, Profile> uuidToProfileMap = new HashMap<>(); - - public void getHypixelProfile(String name, Consumer<JsonObject> callback) { - String nameF = name.toLowerCase(); - HashMap<String, String> args = new HashMap<>(); - args.put("name", "" + nameF); - manager.hypixelApi.getHypixelApiAsync(NotEnoughUpdates.INSTANCE.config.apiKey.apiKey, "player", - args, jsonObject -> { - if (jsonObject != null && jsonObject.has("success") && jsonObject.get("success").getAsBoolean() - && jsonObject.get("player").isJsonObject()) { - nameToUuid.put(nameF, jsonObject.get("player").getAsJsonObject().get("uuid").getAsString()); - uuidToHypixelProfile.put( - jsonObject.get("player").getAsJsonObject().get("uuid").getAsString(), - jsonObject.get("player").getAsJsonObject() - ); - if (callback != null) callback.accept(jsonObject); - } else { - if (callback != null) callback.accept(null); - } - } - ); - } - - private final HashMap<String, String> nameToUuid = new HashMap<>(); - - public void putNameUuid(String name, String uuid) { - nameToUuid.put(name, uuid); - } - - public void getPlayerUUID(String name, Consumer<String> uuidCallback) { - String nameF = name.toLowerCase(); - if (nameToUuid.containsKey(nameF)) { - uuidCallback.accept(nameToUuid.get(nameF)); - return; - } - - manager.hypixelApi.getApiAsync("https://api.mojang.com/users/profiles/minecraft/" + nameF, - (jsonObject) -> { - if (jsonObject.has("id") && jsonObject.get("id").isJsonPrimitive() && - ((JsonPrimitive) jsonObject.get("id")).isString()) { - String uuid = jsonObject.get("id").getAsString(); - nameToUuid.put(nameF, uuid); - uuidCallback.accept(uuid); - return; - } - uuidCallback.accept(null); - }, () -> uuidCallback.accept(null) - ); - } - - public void getProfileByName(String name, Consumer<Profile> callback) { - String nameF = name.toLowerCase(); - - if (nameToUuid.containsKey(nameF) && nameToUuid.get(nameF) == null) { - callback.accept(null); - return; - } - - getPlayerUUID(nameF, (uuid) -> { - if (uuid == null) { - getHypixelProfile(nameF, jsonObject -> { - if (jsonObject != null) { - callback.accept(getProfileReset(nameToUuid.get(nameF), ignored -> { - })); - } else { - callback.accept(null); - nameToUuid.put(nameF, null); - } - }); - } else { - if (!uuidToHypixelProfile.containsKey(uuid)) { - getHypixelProfile(nameF, jsonObject -> { - }); - } - callback.accept(getProfileReset(uuid, ignored -> { - })); - } - }); - - return; - } - - public Profile getProfileRaw(String uuid) { - return uuidToProfileMap.get(uuid); - } - - public Profile getProfile(String uuid, Consumer<Profile> callback) { - Profile profile = uuidToProfileMap.computeIfAbsent(uuid, k -> new Profile(uuid)); - if (profile.playerInformation != null) { - callback.accept(profile); - } else { - profile.getPlayerInformation(() -> callback.accept(profile)); - } - return profile; - } - - public Profile getProfileReset(String uuid, Consumer<Profile> callback) { - if (uuidToProfileMap.containsKey(uuid)) uuidToProfileMap.get(uuid).resetCache(); - return getProfile(uuid, callback); - } - - private static JsonObject resourceCollection = null; - private static final AtomicBoolean updatingResourceCollection = new AtomicBoolean(false); - - public static JsonObject getResourceCollectionInformation() { - if (resourceCollection != null) return resourceCollection; - if (updatingResourceCollection.get()) return null; - - updatingResourceCollection.set(true); - - HashMap<String, String> args = new HashMap<>(); - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getHypixelApiAsync( - NotEnoughUpdates.INSTANCE.config.apiKey.apiKey, - "resources/skyblock/collections", - args, - jsonObject -> { - updatingResourceCollection.set(false); - if (jsonObject != null && jsonObject.has("success") && jsonObject.get("success").getAsBoolean()) { - resourceCollection = jsonObject.get("collections").getAsJsonObject(); - } - }, - () -> updatingResourceCollection.set(false) - ); - - return null; - } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java index 2628eb7d..37de9ed8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/HypixelApi.java @@ -21,15 +21,14 @@ import java.util.function.Consumer; import java.util.zip.GZIPInputStream; public class HypixelApi { + private static final int FAILS_BEFORE_SWITCH = 3; private final Gson gson = new Gson(); private final ExecutorService es = Executors.newFixedThreadPool(3); - - private static final int FAILS_BEFORE_SWITCH = 3; - private int currentUrl = 0; - private long lastPrimaryUrl = 0; private final String[] myApiURLs = {"https://moulberry.codes/"}; //, "http://moulberry.codes/", "http://51.79.51.21/"};//, "http://51.75.78.252/" }; private final Integer[] myApiSuccesses = {0, 0, 0, 0}; + private int currentUrl = 0; + private long lastPrimaryUrl = 0; public CompletableFuture<JsonObject> getHypixelApiAsync(String apiKey, String method, HashMap<String, String> args) { return getApiAsync(generateApiUrl(apiKey, method, args)); @@ -167,7 +166,7 @@ public class HypixelApi { public String generateApiUrl(String apiKey, String method, HashMap<String, String> args) { if (apiKey != null) - args.put("key", apiKey.trim().replace("-", "")); + args.put("key", apiKey.trim()); StringBuilder url = new StringBuilder("https://api.hypixel.net/" + method); boolean first = true; for (Map.Entry<String, String> entry : args.entrySet()) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java index 4bf1d6aa..5b7bd055 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/SBInfo.java @@ -293,7 +293,7 @@ public class SBInfo { String cleanLine = Utils.cleanColour(line); - if (cleanLine.contains("Dungeon") && cleanLine.contains("Cleared:") && cleanLine.contains("%")) { + if (cleanLine.contains("Cleared:") && cleanLine.contains("%")) { tempIsInDungeon = true; } diff --git a/src/main/resources/assets/notenoughupdates/invbuttons/presets.json b/src/main/resources/assets/notenoughupdates/invbuttons/presets.json index 4184e6d4..e36f8021 100644 --- a/src/main/resources/assets/notenoughupdates/invbuttons/presets.json +++ b/src/main/resources/assets/notenoughupdates/invbuttons/presets.json @@ -2569,7 +2569,8 @@ "anchorRight": false, "anchorBottom": false, "backgroundIndex": 0, - "command": "" + "command": "joindungeon master_catacombs 7", + "icon": "DIAMOND_NECRON_HEAD" }, { "x": 151, diff --git a/src/main/resources/assets/notenoughupdates/pv_bingo_tab.png b/src/main/resources/assets/notenoughupdates/pv_bingo_tab.png Binary files differnew file mode 100644 index 00000000..135035cf --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/pv_bingo_tab.png |