diff options
17 files changed, 485 insertions, 306 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4d6c2b23..639d3965 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,6 +9,7 @@ on: - "COPYING" - "COPYING.LESSER" - ".gitignore" + - "Update Notes" pull_request: branches: - "*" @@ -17,6 +18,7 @@ on: - "COPYING" - "COPYING.LESSER" - ".gitignore" + - "Update Notes" workflow_dispatch: jobs: build: diff --git a/Update Notes/2.1.md b/Update Notes/2.1.md index 99b2eef0..89f56293 100644 --- a/Update Notes/2.1.md +++ b/Update Notes/2.1.md @@ -42,6 +42,7 @@ - Added carpentry skill to skill average - hannibal2 - Fixed sort order of fishing rods in profile viewer page - hannibal2 - Changing sort logic from strength plus damage to bin price for best weapons in pv inventory page - hannibal2 + - Added pronouns to /pv - nea89 ### **Minor Changes:** @@ -157,6 +158,7 @@ - Fixed skill average calculation to include carpentry in /peek - whalker - Fixed middle clicking on pets not registering pet swap - nopo - Fixed middle clicking on an item with no id searching for it - nopo +- Fixed pets with decimal stats not showing in pv - nopo ### **Other:** diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index d0ff431a..85993307 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -1265,7 +1265,7 @@ public class NEUManager { } } - public HashMap<String, String> getLoreReplacements(String petname, String tier, int level) { + public HashMap<String, String> getPetLoreReplacements(String petname, String tier, int level) { JsonObject petnums = null; if (petname != null && tier != null) { petnums = Constants.PETNUMS; @@ -1378,7 +1378,7 @@ public class NEUManager { float statMax = entry.getValue().getAsFloat(); float statMin = min.get("statNums").getAsJsonObject().get(entry.getKey()).getAsFloat(); float val = statMin * minMix + statMax * maxMix; - String statStr = (statMin > 0 ? "+" : "") + (int) Math.floor(val); + String statStr = (statMin > 0 ? "+" : "") + removeUnusedDecimal(Math.floor(val * 10) / 10); replacements.put(entry.getKey(), statStr); } } @@ -1390,7 +1390,7 @@ public class NEUManager { return replacements; } - public HashMap<String, String> getLoreReplacements(NBTTagCompound tag, int level) { + public HashMap<String, String> getPetLoreReplacements(NBTTagCompound tag, int level) { String petname = null; String tier = null; if (tag != null && tag.hasKey("ExtraAttributes")) { @@ -1424,7 +1424,7 @@ public class NEUManager { } } } - return getLoreReplacements(petname, tier, level); + return getPetLoreReplacements(petname, tier, level); } public NBTTagList processLore(JsonArray lore, HashMap<String, String> replacements) { @@ -1455,6 +1455,7 @@ public class NEUManager { } public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useReplacements, boolean copyStack) { + if (useReplacements) useCache = false; if (json == null) return new ItemStack(Items.painting, 1, 10); String internalname = json.get("internalname").getAsString(); @@ -1494,7 +1495,7 @@ public class NEUManager { HashMap<String, String> replacements = new HashMap<>(); if (useReplacements) { - replacements = getLoreReplacements(stack.getTagCompound(), -1); + replacements = getPetLoreReplacements(stack.getTagCompound(), -1); String displayName = json.get("displayname").getAsString(); for (Map.Entry<String, String> entry : replacements.entrySet()) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index dbff2be2..14078069 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -1460,7 +1460,7 @@ public class NEUOverlay extends Gui { if (index < getSlotsXSize() * getSlotsYSize()) { int actualIndex = index + getSlotsXSize() * getSlotsYSize() * page; List<JsonObject> searchedItems = getSearchedItems(); - if (actualIndex < searchedItems.size()) { + if (0 <= actualIndex && actualIndex < searchedItems.size()) { return searchedItems.get(actualIndex); } else { return null; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java index c522e70a..d89e886f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java @@ -55,7 +55,6 @@ import java.awt.datatransfer.StringSelection; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -67,7 +66,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class ItemTooltipListener { - private static final String petToolTipRegex = + public static final String petToolTipRegex = "((Farming)|(Combat)|(Fishing)|(Mining)|(Foraging)|(Enchanting)|(Alchemy)) ((Mount)|(Pet)|(Morph)).*"; private final NotEnoughUpdates neu; private final Pattern xpLevelPattern = Pattern.compile("(.*) (\\xA7e(.*)\\xA76/\\xA7e(.*))"); @@ -711,45 +710,44 @@ public class ItemTooltipListener { } private void petToolTipXPExtendPetMenu(ItemTooltipEvent event) { - if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.petExtendExp) { - //7 is just a random number i chose, prob no pets with less lines than 7 - if (event.toolTip.size() > 7) { - if (Utils.cleanColour(event.toolTip.get(1)).matches(petToolTipRegex)) { - GuiProfileViewer.PetLevel petLevel; - - int xpLine = -1; - for (int i = event.toolTip.size() - 1; i >= 0; i--) { - Matcher matcher = xpLevelPattern.matcher(event.toolTip.get(i)); - if (matcher.matches()) { - xpLine = i; - event.toolTip.set(xpLine, matcher.group(1)); - break; - } else if (event.toolTip.get(i).matches("MAX LEVEL")) { - return; - } - } + if (!NotEnoughUpdates.INSTANCE.config.tooltipTweaks.petExtendExp) return; + //7 is just a random number i chose, prob no pets with less lines than 7 + if (event.toolTip.size() < 7) return; + if (event.itemStack.getTagCompound().hasKey("NEUHIDEPETTOOLTIP")) return; + if (Utils.cleanColour(event.toolTip.get(1)).matches(petToolTipRegex)) { + GuiProfileViewer.PetLevel petLevel; + + int xpLine = -1; + for (int i = event.toolTip.size() - 1; i >= 0; i--) { + Matcher matcher = xpLevelPattern.matcher(event.toolTip.get(i)); + if (matcher.matches()) { + xpLine = i; + event.toolTip.set(xpLine, matcher.group(1)); + break; + } else if (event.toolTip.get(i).matches("MAX LEVEL")) { + return; + } + } - PetInfoOverlay.Pet pet = PetInfoOverlay.getPetFromStack( - event.itemStack.getTagCompound() - ); - if (pet == null) { - return; - } - petLevel = pet.petLevel; + PetInfoOverlay.Pet pet = PetInfoOverlay.getPetFromStack( + event.itemStack.getTagCompound() + ); + if (pet == null) { + return; + } + petLevel = pet.petLevel; - if (petLevel == null || xpLine == -1) { - return; - } + if (petLevel == null || xpLine == -1) { + return; + } - event.toolTip.add( - xpLine + 1, - EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + myFormatter.format(petLevel.levelXp) + - EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW + - myFormatter.format(petLevel.currentLevelRequirement) - ); + event.toolTip.add( + xpLine + 1, + EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + myFormatter.format(petLevel.levelXp) + + EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW + + myFormatter.format(petLevel.currentLevelRequirement) + ); - } - } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java index bbbb9049..fdae53ea 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipRngListener.java @@ -27,6 +27,8 @@ import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import io.github.moulberry.notenoughupdates.util.Calculator; import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.ItemResolutionQuery; +import io.github.moulberry.notenoughupdates.util.ItemUtils; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.item.ItemStack; import net.minecraftforge.event.entity.player.ItemTooltipEvent; @@ -135,14 +137,18 @@ public class ItemTooltipRngListener { event.toolTip.addAll(newToolTip); } - private String getFormatCoinsPer(ItemStack stack, int needed, int multiplier, String name) { - String internalName = neu.manager.getInternalNameForItem(stack); - double bin = neu.manager.auctionManager.getBazaarOrBin(internalName); - if (bin <= 0) return null; + private String getFormatCoinsPer(ItemStack stack, int needed, int multiplier, String label) { + String internalName = neu.manager.createItemResolutionQuery().withItemStack(stack).resolveInternalName(); + double profit = neu.manager.auctionManager.getBazaarOrBin(internalName); + if (profit <= 0) return null; - double coinsPer = (bin / needed) * multiplier; + //ask hypixel nicely to release a 'chest price api' with 4 dimensions for us. the 4 dimensions needed are: item name, floor, normal/mm, s/s+ +// double chestPrice = grabChestPrice(stack, internalName); +// profit -= chestPrice; + + double coinsPer = (profit / needed) * multiplier; String format = StringUtils.shortNumberFormat(coinsPer); - return "§7Coins per " + name + ": §6" + format + " coins"; + return "§7Coins per " + label + ": §6" + format + " coins"; } private void fractionDisplay(List<String> newToolTip, String line) { @@ -256,10 +262,12 @@ public class ItemTooltipRngListener { Map<String, Integer> runsData; String labelPlural; String labelSingular; + String repoCategory; if (openChestName.contains("Catacombs")) { runsData = dungeonData; labelPlural = "Runs"; labelSingular = "Run"; + repoCategory = "catacombs"; } else { // Slayer Matcher matcher = SLAYER_INVENTORY_TITLE_PATTERN.matcher(openChestName); if (!matcher.matches()) { @@ -271,6 +279,12 @@ public class ItemTooltipRngListener { runsData = slayerData.get(slayerName); labelPlural = "Bosses"; labelSingular = "Boss"; + repoCategory = "slayer"; + } + + int repoScore = getRepoScore(stack, repoCategory); + if (repoScore != -1) { + needed = repoScore; } handleArrowKeys(runsData); @@ -282,7 +296,7 @@ public class ItemTooltipRngListener { String name = (String) runsData.keySet().toArray()[currentSelected]; int gainPerRun = runsData.get(name); - int runsNeeded = needed / gainPerRun; + int runsNeeded = (int) Math.floor((double) needed / (double) gainPerRun); int runsHaving = having / gainPerRun; String runsNeededFormat = GuiProfileViewer.numberFormat.format(runsNeeded); String runsHavingFormat = GuiProfileViewer.numberFormat.format(runsHaving); @@ -309,6 +323,49 @@ public class ItemTooltipRngListener { } } + private int getRepoScore(ItemStack stack, String repoCategory) { + ItemResolutionQuery query = + NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery().withItemStack(stack).withCurrentGuiContext(); + String internalName = query.resolveInternalName(); + + JsonObject jsonObject = Constants.RNGSCORE; + if (jsonObject == null) { + Utils.showOutdatedRepoNotification(); + return -1; + } + + String repoType = grabRepoType(stack); + if (!jsonObject.has(repoCategory)) return -1; + + JsonObject category = jsonObject.get(repoCategory).getAsJsonObject(); + if (!category.has(repoType)) return -1; + + JsonObject typeObject = category.get(repoType).getAsJsonObject(); + if (!typeObject.has(internalName)) return -1; + + return typeObject.get(internalName).getAsInt(); + } + + // Determines the floor or the slayer type from where the item can be obtained. E.g. F7, M3, Revenant Horror or Sven Packmaster + private String grabRepoType(ItemStack stack) { + String openChestName = Utils.getOpenChestName(); + if (openChestName.contains("Catacombs")) { + if (openChestName.equals("Catacombs RNG Meter")) { + List<String> list = ItemUtils.getLore(stack); + String line = list.get(4); + return line.substring(26, 28); + } else { + // supporting more pages (f7/m7) + if (openChestName.contains("(")) { + return openChestName.substring(17, 19); + } + return openChestName.substring(11, 13); + } + } else { + return openChestName.substring(0, openChestName.length() - 9); + } + } + private void handleArrowKeys(Map<String, Integer> runsData) { boolean left = Keyboard.isKeyDown(Keyboard.KEY_LEFT); boolean right = Keyboard.isKeyDown(Keyboard.KEY_RIGHT); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java index 6706fe5c..db29c851 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java @@ -132,10 +132,11 @@ public class PetInfoOverlay extends TextOverlay { public String petXpType; public String petItem; public String skin; + public int candyUsed; public String getPetId(boolean withoutBoost) { - return petType + ";" + (withoutBoost ? rarity.petId - 1 : rarity.petId); - + boolean shouldDecreaseRarity = withoutBoost && "PET_ITEM_TIER_BOOST".equals(petItem); + return petType + ";" + (shouldDecreaseRarity ? rarity.petId - 1 : rarity.petId); } } @@ -465,10 +466,10 @@ public class PetInfoOverlay extends TextOverlay { float remainingMax = currentPet.petLevel.maxXP - currentPet.petLevel.totalXp; if (remaining > 0) { if (xpGain < 1000) { - etaMaxStr = EnumChatFormatting.AQUA + "Until L" + currentPet.petLevel.maxLevel + ": " + + etaMaxStr = EnumChatFormatting.AQUA + "Until L" + (int) currentPet.petLevel.maxLevel + ": " + EnumChatFormatting.YELLOW + "N/A"; } else { - etaMaxStr = EnumChatFormatting.AQUA + "Until L" + currentPet.petLevel.maxLevel + ": " + + etaMaxStr = EnumChatFormatting.AQUA + "Until L" + (int) currentPet.petLevel.maxLevel + ": " + EnumChatFormatting.YELLOW + Utils.prettyTime((long) (remainingMax) * 1000 * 60 * 60 / (long) xpGain); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/CustomArmour.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/CustomArmour.java index 6c47b7a6..d7f82a66 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/CustomArmour.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/CustomArmour.java @@ -29,7 +29,8 @@ public class CustomArmour { @Expose @ConfigOption( name = "Enable Equipment Hud", - desc = "Shows an overlay in your inventory showing your 4 extra armour slots" + desc = "Shows an overlay in your inventory showing your 4 extra armour slots" + + "\u00A7cRequires Hide Potion Effects to be enabled" ) @ConfigEditorBoolean public boolean enableArmourHud = true; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Enchanting.java b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Enchanting.java index 2990498f..b596d180 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Enchanting.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/Enchanting.java @@ -132,7 +132,7 @@ public class Enchanting { @Expose @ConfigOption( name = "Ultrasequencer Numbers", - desc = "Replace the items in the supersequencer with only numbers" + desc = "Replace the items in the Ultrasequencer with only numbers" ) @ConfigEditorBoolean @ConfigAccordionId(id = 0) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java index bf106eed..d73b5eb2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/CombatSkillOverlay.java @@ -82,6 +82,7 @@ public class CombatSkillOverlay public void update() { if (!NotEnoughUpdates.INSTANCE.config.skillOverlays.combatSkillOverlay) { kill = -1; + championXp = -1; overlayStrings = null; return; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/EquipmentOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/EquipmentOverlay.java index 2d3175b5..e6e8cb3b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/EquipmentOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/EquipmentOverlay.java @@ -106,7 +106,7 @@ public class EquipmentOverlay { case 2: return ARMOR_DISPLAY_DARK; case 3: - return isPetRendering ? ARMOR_DISPLAY_TRANSPARENT_PET : ARMOR_DISPLAY_TRANSPARENT; + return NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3 && isPetRendering ? ARMOR_DISPLAY_TRANSPARENT_PET : ARMOR_DISPLAY_TRANSPARENT; case 4: return ARMOR_DISPLAY_FSR; } @@ -191,7 +191,7 @@ public class EquipmentOverlay { int overlayLeft = container.getGuiLeft() - ARMOR_OVERLAY_OVERHAND_WIDTH; int overlayTop = container.getGuiTop(); - ResourceLocation equipmentTexture = getCustomEquipmentTexture(isRenderingPet); + ResourceLocation equipmentTexture = getCustomEquipmentTexture(shouldRenderPets); Minecraft.getMinecraft().getTextureManager().bindTexture(equipmentTexture); Utils.drawTexturedRect(overlayLeft, overlayTop, ARMOR_OVERLAY_WIDTH, ARMOR_OVERLAY_HEIGHT, GL11.GL_NEAREST); @@ -243,7 +243,10 @@ public class EquipmentOverlay { NEUManager manager = NotEnoughUpdates.INSTANCE.manager; PetInfoOverlay.Pet currentPet = PetInfoOverlay.getCurrentPet(); if (currentPet == null) return null; - ItemStack item = manager.createItem(currentPet.getPetId(false)); + + ItemStack item = ItemUtils.createPetItemstackFromPetInfo(currentPet); + item = ItemUtils.petToolTipXPExtendPetOverlay(item); + if (item != null) { return item; } @@ -259,7 +262,7 @@ public class EquipmentOverlay { slot4 = getWardrobeSlot(37); } - if (screen instanceof GuiChest) { + if ((screen instanceof GuiChest || screen instanceof GuiInventory) && NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay){ petStack = getRepoPetStack(); } if ((!(screen instanceof GuiInventory) && !(screen instanceof GuiInvButtonEditor)) diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextTabOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextTabOverlay.java index 03578c95..fa263db7 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextTabOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TextTabOverlay.java @@ -49,8 +49,13 @@ public abstract class TextTabOverlay extends TextOverlay { public void realTick() { shouldUpdateOverlay = shouldUpdate(); if (shouldUpdateOverlay) { - boolean currentTabState = - Keyboard.isKeyDown(Minecraft.getMinecraft().gameSettings.keyBindPlayerList.getKeyCode()); + int keycode = Minecraft.getMinecraft().gameSettings.keyBindPlayerList.getKeyCode(); + boolean currentTabState; + if (keycode > 0) { + currentTabState = Keyboard.isKeyDown(keycode); + } else { + currentTabState = false; + } if (lastTabState != currentTabState) { lastTabState = currentTabState; update(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java index c32310b7..94dbdc1e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/MiningPage.java @@ -868,8 +868,7 @@ public class MiningPage extends GuiProfileViewerPage { "Seasoned Mineman", "§7Level " + seasonMine + "§8/100", "", - "§7Increases your Mining", - "§7experience gain by " + EnumChatFormatting.GREEN + seasonMineStat + "%§7.", + "§7Grants §3+" + EnumChatFormatting.DARK_AQUA + seasonMineStat + "☯ Mining Wisdom§7.", "", EnumChatFormatting.GRAY + "Cost", EnumChatFormatting.DARK_GREEN + @@ -881,8 +880,7 @@ public class MiningPage extends GuiProfileViewerPage { "Seasoned Mineman", "§7Level " + seasonMine + "§8/100", "", - "§7Increases your Mining", - "§7experience gain by " + EnumChatFormatting.GREEN + seasonMineStat + "%§7." + "§7Grants §3+" + EnumChatFormatting.DARK_AQUA + seasonMineStat + "☯ Mining Wisdom§7." ), 100 ); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java index 25751ab8..cb85bf79 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java @@ -22,22 +22,17 @@ package io.github.moulberry.notenoughupdates.profileviewer; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.core.util.StringUtils; +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.ItemUtils; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.init.Items; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.JsonToNBT; -import net.minecraft.nbt.NBTException; import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.nbt.NBTTagString; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; import org.lwjgl.input.Mouse; @@ -46,11 +41,7 @@ import org.lwjgl.opengl.GL11; import java.awt.*; import java.io.IOException; import java.util.ArrayList; -import java.util.Base64; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.UUID; public class PetsPage extends GuiProfileViewerPage { @@ -91,7 +82,8 @@ public class PetsPage extends GuiProfileViewerPage { String panoramaIdentifier = "day"; if (SBInfo.getInstance().currentTimeDate != null) { - if (SBInfo.getInstance().currentTimeDate.getHours() <= 6 || SBInfo.getInstance().currentTimeDate.getHours() >= 20) { + if (SBInfo.getInstance().currentTimeDate.getHours() <= 6 || + SBInfo.getInstance().currentTimeDate.getHours() >= 20) { panoramaIdentifier = "night"; } } @@ -123,201 +115,22 @@ public class PetsPage extends GuiProfileViewerPage { } }); for (JsonObject pet : sortedPets) { - String petname = pet.get("type").getAsString(); - String tier = pet.get("tier").getAsString(); - String heldItem = Utils.getElementAsString(pet.get("heldItem"), null); - String skin = Utils.getElementAsString(pet.get("skin"), null); - int candy = pet.get("candyUsed").getAsInt(); - JsonObject heldItemJson = heldItem == null ? null : NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(heldItem); - String tierNum = GuiProfileViewer.MINION_RARITY_TO_NUM.get(tier); - float exp = pet.get("exp").getAsFloat(); - if (tierNum == null) continue; - - if ( - pet.has("heldItem") && - !pet.get("heldItem").isJsonNull() && - pet.get("heldItem").getAsString().equals("PET_ITEM_TIER_BOOST") - ) { - tierNum = "" + (Integer.parseInt(tierNum) + 1); - } - - GuiProfileViewer.PetLevel levelObj = GuiProfileViewer.getPetLevel(petname, tier, exp); - - float level = levelObj.level; - float currentLevelRequirement = levelObj.currentLevelRequirement; - float maxXP = levelObj.maxXP; - pet.addProperty("level", level); - pet.addProperty("currentLevelRequirement", currentLevelRequirement); - pet.addProperty("maxXP", maxXP); - - JsonObject petItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(petname + ";" + tierNum); - ItemStack stack; - if (petItem == null) { - stack = getQuestionmarkSkull(); - 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 = GuiProfileViewer.PET_STAT_BOOSTS.get(heldItem); - HashMap<String, Float> petStatBootsMult = GuiProfileViewer.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) {} - } - } - } - - 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)); - } - 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(); - } - } - } - 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; - } - } - 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); - } - } - 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()); - } - display.setTag("Name", new NBTTagString(displayName)); - } - tag.setTag("display", display); - } - - // Adds the missing pet fields to the tag - NBTTagCompound extraAttributes = new NBTTagCompound(); - JsonObject petInfo = new JsonObject(); - if(tag.hasKey("ExtraAttributes", 10)) { - extraAttributes = tag.getCompoundTag("ExtraAttributes"); - if (extraAttributes.hasKey("petInfo", 8)) { - petInfo = new JsonParser().parse(extraAttributes.getString("petInfo")).getAsJsonObject(); - } - } - petInfo.addProperty("exp", exp); - petInfo.addProperty("tier", tier); - petInfo.addProperty("type", petname); - if (heldItem != null) { - petInfo.addProperty("heldItem", heldItem); - } - if (skin != null) { - petInfo.addProperty("skin", skin); - } - extraAttributes.setString("petInfo", petInfo.toString()); - tag.setTag("ExtraAttributes", extraAttributes); - stack.setTagCompound(tag); - } - sortedPetsStack.add(stack); + PetInfoOverlay.Pet parsedPet = new PetInfoOverlay.Pet(); + parsedPet.petType = pet.get("type").getAsString(); + parsedPet.rarity = PetInfoOverlay.Rarity.valueOf(pet.get("tier").getAsString()); + parsedPet.petLevel = GuiProfileViewer.getPetLevel( + parsedPet.petType, + parsedPet.rarity.name(), + pet.get("exp").getAsFloat() + ); + parsedPet.petXpType = "unknown"; + parsedPet.petItem = Utils.getElementAsString(pet.get("heldItem"), null); + parsedPet.skin = Utils.getElementAsString(pet.get("skin"), null); + parsedPet.candyUsed = pet.get("candyUsed").getAsInt(); + sortedPetsStack.add(ItemUtils.createPetItemstackFromPetInfo(parsedPet)); + pet.addProperty("level", parsedPet.petLevel.level); + pet.addProperty("currentLevelRequirement", parsedPet.petLevel.currentLevelRequirement); + pet.addProperty("maxXP", parsedPet.petLevel.maxXP); } } @@ -396,7 +209,11 @@ public class PetsPage extends GuiProfileViewerPage { ); } - for (int i = petsPage * 20; i < Math.min(petsPage * 20 + 20, Math.min(sortedPetsStack.size(), sortedPets.size())); i++) { + for ( + int i = petsPage * 20; + i < Math.min(petsPage * 20 + 20, Math.min(sortedPetsStack.size(), sortedPets.size())); + i++ + ) { JsonObject pet = sortedPets.get(i); ItemStack stack = sortedPetsStack.get(i); @@ -433,7 +250,7 @@ public class PetsPage extends GuiProfileViewerPage { if (selectedPet >= 0) { ItemStack petStack; if (sortedPetsStack.size() <= selectedPet) { - petStack = getQuestionmarkSkull(); + petStack = ItemUtils.createQuestionMarkSkull("§cInvalid pet selection"); } else { petStack = sortedPetsStack.get(selectedPet); } @@ -441,7 +258,8 @@ public class PetsPage extends GuiProfileViewerPage { JsonObject pet = sortedPets.get(selectedPet); int x = guiLeft + 280; - float y = guiTop + 67 + 15 * (float) Math.sin(((getInstance().currentTime - getInstance().startTime) / 800f) % (2 * Math.PI)); + float y = guiTop + 67 + 15 * (float) Math.sin( + ((getInstance().currentTime - getInstance().startTime) / 800f) % (2 * Math.PI)); int displayLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth(display); int halfDisplayLen = displayLen / 2; @@ -568,32 +386,4 @@ public class PetsPage extends GuiProfileViewerPage { sortedPetsStack = null; selectedPet = -1; } - - private ItemStack getQuestionmarkSkull() { - String textureLink = "bc8ea1f51f253ff5142ca11ae45193a4ad8c3ab5e9c6eec8ba7a4fcb7bac40"; - - String b64Decoded = "{\"textures\":{\"SKIN\":{\"url\":\"http://textures.minecraft.net/texture/" + textureLink + "\"}}}"; - String b64Encoded = new String(Base64.getEncoder().encode(b64Decoded.getBytes())); - - ItemStack stack = new ItemStack(Items.skull, 1, 3); - NBTTagCompound nbt = new NBTTagCompound(); - NBTTagCompound skullOwner = new NBTTagCompound(); - NBTTagCompound properties = new NBTTagCompound(); - NBTTagList textures = new NBTTagList(); - NBTTagCompound textures_0 = new NBTTagCompound(); - - String uuid = UUID.nameUUIDFromBytes(b64Encoded.getBytes()).toString(); - skullOwner.setString("Id", uuid); - skullOwner.setString("Name", uuid); - - textures_0.setString("Value", b64Encoded); - textures.appendTag(textures_0); - - properties.setTag("textures", textures); - skullOwner.setTag("Properties", properties); - nbt.setTag("SkullOwner", skullOwner); - stack.setTagCompound(nbt); - stack.setStackDisplayName(EnumChatFormatting.RED + "Unknown Pet"); - return stack; - } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java index 1d226dc8..ef030367 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java @@ -71,6 +71,7 @@ public class Constants { public static JsonObject REFORGESTONES; public static JsonObject TROPHYFISH; public static JsonObject WEIGHT; + public static JsonObject RNGSCORE; private static final ReentrantLock lock = new ReentrantLock(); @@ -92,6 +93,7 @@ public class Constants { REFORGESTONES = Utils.getConstant("reforgestones", gson); TROPHYFISH = Utils.getConstant("trophyfish", gson); WEIGHT = Utils.getConstant("weight", gson); + RNGSCORE = Utils.getConstant("rngscore", gson); } catch (Exception ex) { ex.printStackTrace(); } finally { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java index 48eb6fad..4d3b4645 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemResolutionQuery.java @@ -19,10 +19,11 @@ package io.github.moulberry.notenoughupdates.util; -import com.google.common.collect.Iterables; import com.google.gson.JsonObject; import com.google.gson.JsonParseException; import io.github.moulberry.notenoughupdates.NEUManager; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.core.util.StringUtils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.inventory.GuiChest; @@ -37,6 +38,7 @@ import javax.annotation.Nullable; import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -136,6 +138,13 @@ public class ItemResolutionQuery { return manager.jsonToStack(jsonObject); } + @Nullable + public ItemStack resolveToItemStack(boolean useReplacements) { + JsonObject jsonObject = resolveToItemListJson(); + if (jsonObject == null) return null; + return manager.jsonToStack(jsonObject, false, useReplacements); + } + // <editor-fold desc="Resolution Helpers"> private boolean isBazaar(IInventory chest) { if (chest.getDisplayName().getFormattedText().startsWith("Bazaar ➜ ")) { @@ -170,6 +179,40 @@ public class ItemResolutionQuery { } return null; } + if (guiName.equals("Catacombs RNG Meter")) { + return resolveItemInCatacombsRngMeter(); + } + return null; + } + + private String resolveItemInCatacombsRngMeter() { + List<String> lore = ItemUtils.getLore(compound); + if (lore.size() > 16) { + String s = lore.get(15); + if (s.equals("§7Selected Drop")) { + String displayName = lore.get(16); + return getInternalNameByDisplayName(displayName); + } + } + + return null; + } + + private String getInternalNameByDisplayName(String displayName) { + String cleanDisplayName = StringUtils.cleanColour(displayName); + for (Map.Entry<String, JsonObject> entry : NotEnoughUpdates.INSTANCE.manager + .getItemInformation() + .entrySet()) { + + JsonObject object = entry.getValue(); + if (object.has("displayname")) { + String name = object.get("displayname").getAsString(); + if (StringUtils.cleanColour(name).equals(cleanDisplayName)) { + return entry.getKey(); + } + } + } + return null; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java index c7c7d4b6..c6bc7538 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java @@ -20,16 +20,31 @@ package io.github.moulberry.notenoughupdates.util; import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.listener.ItemTooltipListener; +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; +import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import net.minecraft.item.ItemStack; +import net.minecraft.nbt.JsonToNBT; +import net.minecraft.nbt.NBTException; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.nbt.NBTTagString; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.MathHelper; +import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Map; +import java.util.function.BiFunction; public class ItemUtils { @@ -58,6 +73,14 @@ public class ItemUtils { return skull; } + public static ItemStack createQuestionMarkSkull(String label) { + return Utils.createSkull( + label, + "00000000-0000-0000-0000-000000000000", + "bc8ea1f51f253ff5142ca11ae45193a4ad8c3ab5e9c6eec8ba7a4fcb7bac40" + ); + } + public static NBTTagCompound getOrCreateTag(ItemStack is) { if (is.hasTagCompound()) return is.getTagCompound(); NBTTagCompound nbtTagCompound = new NBTTagCompound(); @@ -120,8 +143,260 @@ public class ItemUtils { return enchId; } + /** + * Mutates baseValues + */ + public static <T> void modifyReplacement( + Map<String, String> baseValues, + Map<String, T> modifiers, + BiFunction<String, T, String> mapper + ) { + if (modifiers == null || baseValues == null) return; + for (Map.Entry<String, T> modifier : modifiers.entrySet()) { + String baseValue = baseValues.get(modifier.getKey()); + if (baseValue == null) continue; + try { + baseValues.put(modifier.getKey(), mapper.apply(baseValue, modifier.getValue())); + } catch (Exception e) { + System.out.println("Exception during replacement mapping: "); + e.printStackTrace(); + } + } + } + + public static String applyReplacements(Map<String, String> replacements, String text) { + for (Map.Entry<String, String> replacement : replacements.entrySet()) { + String search = "{" + replacement.getKey() + "}"; + text = text.replace(search, replacement.getValue()); + } + return text; + } + + public static ItemStack createPetItemstackFromPetInfo(PetInfoOverlay.Pet currentPet) { + String petname = currentPet.petType; + String tier = Utils.getRarityFromInt(currentPet.rarity.petId).toUpperCase(); + String heldItem = currentPet.petItem; + String skin = currentPet.skin; + JsonObject heldItemJson = heldItem == null ? null : NotEnoughUpdates.INSTANCE.manager.getItemInformation().get( + heldItem); + String petId = currentPet.getPetId(false); + float exp = currentPet.petLevel.totalXp; + + GuiProfileViewer.PetLevel levelObj = GuiProfileViewer.getPetLevel(petname, tier, exp); + + float level = levelObj.level; + + ItemStack petItemstack = NotEnoughUpdates.INSTANCE.manager + .createItemResolutionQuery() + .withKnownInternalName(petId) + .resolveToItemStack(false); + if (petItemstack == null) { + petItemstack = ItemUtils.createQuestionMarkSkull(EnumChatFormatting.RED + "Unknown Pet"); + appendLore(petItemstack, Arrays.asList( + "§cThis pet is not saved in the repository", + "", + "§cIf you expected it to be there please send a message in", + "§c§l#neu-support §r§con §ldiscord.gg/moulberry" + )); + } + Map<String, String> replacements = NotEnoughUpdates.INSTANCE.manager.getPetLoreReplacements( + petname, + tier, + MathHelper.floor_float(level) + ); + + if (heldItem != null) { + modifyReplacement(replacements, GuiProfileViewer.PET_STAT_BOOSTS.get(heldItem), (original, modifier) -> + "" + MathHelper.floor_float(Float.parseFloat(original) + modifier)); + modifyReplacement(replacements, GuiProfileViewer.PET_STAT_BOOSTS_MULT.get(heldItem), (original, modifier) -> + "" + MathHelper.floor_float(Float.parseFloat(original) * modifier)); + } + + NBTTagCompound tag = getOrCreateTag(petItemstack); + if (tag.hasKey("display", 10)) { + NBTTagCompound displayTag = tag.getCompoundTag("display"); + if (displayTag.hasKey("Lore", 9)) { + List<String> newLore = new ArrayList<>(); + NBTTagList lore = displayTag.getTagList("Lore", 8); + int secondLastBlankLine = -1, lastBlankLine = -1; + for (int j = 0; j < lore.tagCount(); j++) { + String line = lore.getStringTagAt(j); + if (line.trim().isEmpty()) { + secondLastBlankLine = lastBlankLine; + lastBlankLine = j; + } + line = applyReplacements(replacements, line); + newLore.add(line); + } + if (skin != null) { + JsonObject petSkin = NotEnoughUpdates.INSTANCE.manager + .createItemResolutionQuery() + .withKnownInternalName("PET_SKIN_" + skin) + .resolveToItemListJson(); + 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, newLore.get(0) + ", " + name); + } + } catch (NBTException e) { + e.printStackTrace(); + } + } + } + for (int i = 0; i < newLore.size(); i++) { + String cleaned = Utils.cleanColour(newLore.get(i)); + if (cleaned.equals("Right-click to add this pet to")) { + newLore.remove(i + 1); + newLore.remove(i); + secondLastBlankLine = i - 1; + break; + } + } + if (secondLastBlankLine != -1) { + List<String> petItemLore = new ArrayList<>(); + if (heldItem != null) { + petItemLore.add(EnumChatFormatting.GOLD + "Held Item: " + heldItemJson.get("displayname").getAsString()); + List<String> heldItemLore = JsonUtils.getJsonArrayOrEmpty(heldItemJson, "lore", JsonElement::getAsString); + int blanks = 0; + for (String heldItemLoreLine : heldItemLore) { + if (heldItemLoreLine.trim().isEmpty()) { + blanks++; + } else if (blanks == 2) { + petItemLore.add(heldItemLoreLine); + } else if (blanks > 2) { + break; + } + } + } + if (currentPet.candyUsed > 0) { + if (petItemLore.size() > 0) { + petItemLore.add(""); + } + petItemLore.add("§a(" + currentPet.candyUsed + "/10) Pet Candy Used"); + } + newLore.addAll(secondLastBlankLine + 1, petItemLore); + } + NBTTagList temp = new NBTTagList(); + for (String loreLine : newLore) { + temp.appendTag(new NBTTagString(loreLine)); + } + displayTag.setTag("Lore", temp); + } + + if (displayTag.hasKey("Name", 8)) { + String displayName = displayTag.getString("Name"); + displayName = applyReplacements(replacements, displayName); + displayTag.setTag("Name", new NBTTagString(displayName)); + } + tag.setTag("display", displayTag); + } + + // Adds the missing pet fields to the tag + NBTTagCompound extraAttributes = new NBTTagCompound(); + JsonObject petInfo = new JsonObject(); + if (tag.hasKey("ExtraAttributes", 10)) { + extraAttributes = tag.getCompoundTag("ExtraAttributes"); + if (extraAttributes.hasKey("petInfo", 8)) { + petInfo = new JsonParser().parse(extraAttributes.getString("petInfo")).getAsJsonObject(); + } + } + petInfo.addProperty("exp", exp); + petInfo.addProperty("tier", tier); + petInfo.addProperty("type", petname); + if (heldItem != null) { + petInfo.addProperty("heldItem", heldItem); + } + if (skin != null) { + petInfo.addProperty("skin", skin); + } + extraAttributes.setString("petInfo", petInfo.toString()); + tag.setTag("ExtraAttributes", extraAttributes); + petItemstack.setTagCompound(tag); + return petItemstack; + } + + private static final DecimalFormat decimalFormatter = new DecimalFormat("#,###,###.###"); + + public static ItemStack petToolTipXPExtendPetOverlay(ItemStack stack) { + 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 lore = display.getTagList("Lore", 8); + if (Utils.cleanColour(lore.getStringTagAt(0)).matches(ItemTooltipListener.petToolTipRegex) && + lore.tagCount() > 7) { + + GuiProfileViewer.PetLevel petLevel; + + PetInfoOverlay.Pet pet = PetInfoOverlay.getPetFromStack( + stack.getTagCompound() + ); + if (pet == null) return stack; + petLevel = pet.petLevel; + if (petLevel == null) return stack; + + NBTTagList newLore = new NBTTagList(); + int maxLvl = 100; + if (Constants.PETS != null && Constants.PETS.has("custom_pet_leveling") && + Constants.PETS.getAsJsonObject("custom_pet_leveling").has(pet.petType.toUpperCase()) && + Constants.PETS.getAsJsonObject("custom_pet_leveling").getAsJsonObject(pet.petType.toUpperCase()).has( + "max_level")) { + maxLvl = + Constants.PETS + .getAsJsonObject("custom_pet_leveling") + .getAsJsonObject(pet.petType.toUpperCase()) + .get("max_level") + .getAsInt(); + } + for (int i = 0; i < lore.tagCount(); i++) { + if (i == lore.tagCount() - 2) { + newLore.appendTag(new NBTTagString("")); + if (petLevel.level >= maxLvl) { + newLore.appendTag(new NBTTagString( + EnumChatFormatting.AQUA + "" + EnumChatFormatting.BOLD + "MAX LEVEL")); + } else { + double levelPercent = (Math.round(petLevel.levelPercentage * 1000) / 10.0); + newLore.appendTag(new NBTTagString( + EnumChatFormatting.GRAY + "Progress to Level " + (int) (petLevel.level + 1) + ": " + + EnumChatFormatting.YELLOW + levelPercent + "%")); + StringBuilder sb = new StringBuilder(); + + for (int j = 0; j < 20; j++) { + if (j < (levelPercent / 5)) { + sb.append(EnumChatFormatting.DARK_GREEN); + } else { + sb.append(EnumChatFormatting.GRAY); + } + sb.append("-"); + } + newLore.appendTag(new NBTTagString(sb.toString())); + newLore.appendTag(new NBTTagString( + EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + + decimalFormatter.format(petLevel.levelXp) + + EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW + + decimalFormatter.format(petLevel.currentLevelRequirement) + )); + } + } + newLore.appendTag(lore.get(i)); + } + display.setTag("Lore", newLore); + tag.setTag("display", display); + } + } + } + stack.setTagCompound(tag); + return stack; + } + public static boolean isSoulbound(ItemStack item) { return ItemUtils.getLore(item).stream() - .anyMatch(line -> line.equals("§8§l* §8Co-op Soulbound §8§l*") || line.equals("§8§l* Soulbound §8§l*")); + .anyMatch(line -> line.equals("§8§l* §8Co-op Soulbound §8§l*") || + line.equals("§8§l* Soulbound §8§l*")); } + } |