/* * Copyright (C) 2022-2024 NotEnoughUpdates contributors * * This file is part of NotEnoughUpdates. * * NotEnoughUpdates is free software: you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * NotEnoughUpdates is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with NotEnoughUpdates. If not, see . */ package io.github.moulberry.notenoughupdates.profileviewer.trophy; 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.core.util.StringUtils; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewerPage; import io.github.moulberry.notenoughupdates.profileviewer.SkyblockProfiles; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.init.Items; import net.minecraft.item.ItemStack; import net.minecraft.util.EnumChatFormatting; import net.minecraft.util.ResourceLocation; import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.tuple.Pair; import org.lwjgl.opengl.GL11; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Optional; import static io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer.pv_elements; public class TrophyFishPage extends GuiProfileViewerPage { private static final Map internalTrophyFish = new HashMap() { { put("gusher", EnumChatFormatting.WHITE); put("flyfish", EnumChatFormatting.GREEN); put("moldfin", EnumChatFormatting.DARK_PURPLE); put("vanille", EnumChatFormatting.BLUE); put("blobfish", EnumChatFormatting.WHITE); put("mana_ray", EnumChatFormatting.BLUE); put("slugfish", EnumChatFormatting.GREEN); put("soul_fish", EnumChatFormatting.DARK_PURPLE); put("lava_horse", EnumChatFormatting.BLUE); put("golden_fish", EnumChatFormatting.GOLD); put("karate_fish", EnumChatFormatting.DARK_PURPLE); put("skeleton_fish", EnumChatFormatting.DARK_PURPLE); put("sulphur_skitter", EnumChatFormatting.WHITE); put("obfuscated_fish_1", EnumChatFormatting.WHITE); put("obfuscated_fish_2", EnumChatFormatting.GREEN); put("obfuscated_fish_3", EnumChatFormatting.BLUE); put("volcanic_stonefish", EnumChatFormatting.BLUE); put("steaming_hot_flounder", EnumChatFormatting.WHITE); } }; private static final LinkedHashMap> armorHelmets = new LinkedHashMap>() { { put( NotEnoughUpdates.INSTANCE.manager.jsonToStack( NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("BRONZE_HUNTER_HELMET") ), Pair.of(EnumChatFormatting.GREEN + "Novice Fisher", 1) ); put( NotEnoughUpdates.INSTANCE.manager.jsonToStack( NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("SILVER_HUNTER_HELMET") ), Pair.of(EnumChatFormatting.BLUE + "Adept Fisher", 2) ); put( NotEnoughUpdates.INSTANCE.manager.jsonToStack( NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("GOLD_HUNTER_HELMET") ), Pair.of(EnumChatFormatting.DARK_PURPLE + "Expert Fisher", 3) ); put( NotEnoughUpdates.INSTANCE.manager.jsonToStack( NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("DIAMOND_HUNTER_HELMET") ), Pair.of(EnumChatFormatting.GOLD + "Master Fisher", 4) ); } }; private static final Map> slotLocations = new HashMap>() { { put(0, Pair.of(277, 46)); put(1, Pair.of(253, 58)); put(2, Pair.of(301, 58)); put(3, Pair.of(229, 70)); put(4, Pair.of(325, 70)); put(5, Pair.of(277, 70)); put(6, Pair.of(253, 82)); put(7, Pair.of(301, 82)); put(8, Pair.of(229, 94)); put(9, Pair.of(325, 94)); put(10, Pair.of(253, 106)); put(11, Pair.of(301, 106)); put(12, Pair.of(277, 118)); put(13, Pair.of(229, 118)); put(14, Pair.of(325, 118)); put(15, Pair.of(253, 130)); put(16, Pair.of(301, 130)); put(17, Pair.of(277, 142)); } }; private static final ResourceLocation TROPHY_FISH_TEXTURE = new ResourceLocation("notenoughupdates:pv_trophy_fish_tab.png"); private static final String checkX = "§c✖"; private static final String check = "§a✔"; private final Map total = new HashMap<>(); private final Map trophyFishList = new HashMap<>(); private long totalCount = 0; private static List tooltipToDisplay = null; public TrophyFishPage(GuiProfileViewer instance) { super(instance); } @Override public void drawPage(int mouseX, int mouseY, float partialTicks) { int guiLeft = GuiProfileViewer.getGuiLeft(); int guiTop = GuiProfileViewer.getGuiTop(); trophyFishList.clear(); SkyblockProfiles.SkyblockProfile selectedProfile = getSelectedProfile(); if (selectedProfile == null) { return; } JsonObject profileInformation = selectedProfile.getProfileJson(); if (profileInformation == null || !profileInformation.has("trophy_fish")) { Utils.drawStringCentered(EnumChatFormatting.RED + "No data found", guiLeft + 431 / 2f, guiTop + 101, true, 0); return; } JsonObject trophyObject = profileInformation.getAsJsonObject("trophy_fish"); loadTrophyInformation(trophyObject); Minecraft.getMinecraft().getTextureManager().bindTexture(TROPHY_FISH_TEXTURE); Utils.drawTexturedRect(guiLeft, guiTop, 431, 202, GL11.GL_NEAREST); GlStateManager.color(1, 1, 1, 1); GlStateManager.disableLighting(); RenderHelper.enableGUIStandardItemLighting(); int thunderKills = Utils.getElementAsInt(Utils.getElement( selectedProfile.getProfileJson(), "bestiary.kills.thunder_400" ), 0); ItemStack thunder_sc = NotEnoughUpdates.INSTANCE.manager.jsonToStack( NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("THUNDER_SC") ); Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI(thunder_sc, guiLeft + 16, guiTop + 108); Utils.drawStringF( EnumChatFormatting.AQUA + "Thunder Kills: §f" + thunderKills, guiLeft + 36, guiTop + 112, true, 0 ); ItemStack lord_jawbus_sc = NotEnoughUpdates.INSTANCE.manager.jsonToStack( NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("LORD_JAWBUS_SC") ); Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI(lord_jawbus_sc, guiLeft + 16, guiTop + 120); int jawbusKills = Utils.getElementAsInt(Utils.getElement( selectedProfile.getProfileJson(), "bestiary.kills.lord_jawbus_600" ), 0); Utils.drawStringF( EnumChatFormatting.AQUA + "Lord Jawbus Kills: §f" + jawbusKills, guiLeft + 36, guiTop + 124, true, 0 ); ItemStack fishing_rod = NotEnoughUpdates.INSTANCE.manager.jsonToStack( NotEnoughUpdates.INSTANCE.manager.getItemInformation().get("FISHING_ROD") ); Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI(fishing_rod, guiLeft + 20, guiTop + 21); Utils.drawStringF(EnumChatFormatting.AQUA + "Total Caught: §f" + totalCount, guiLeft + 38, guiTop + 25, true, 0); ArrayList arrayList = new ArrayList<>(trophyFishList.values()); arrayList.sort((c1, c2) -> Integer.compare(c2.getTotal(), c1.getTotal())); int x; int y; for (TrophyFish value : arrayList) { x = guiLeft + slotLocations.get(arrayList.indexOf(value)).getLeft(); y = guiTop + slotLocations.get(arrayList.indexOf(value)).getRight(); RenderHelper.enableGUIStandardItemLighting(); Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements); Map trophyFishRarityIntegerMap = value.getTrophyFishRarityIntegerMap(); TrophyFish.TrophyFishRarity highestRarity = getHighestRarity(trophyFishRarityIntegerMap).orElse(null); if (highestRarity == TrophyFish.TrophyFishRarity.BRONZE) { GlStateManager.color(255 / 255f, 130 / 255f, 0 / 255f, 1); } if (highestRarity == TrophyFish.TrophyFishRarity.SILVER) { GlStateManager.color(192 / 255f, 192 / 255f, 192 / 255f, 1); } if (highestRarity == TrophyFish.TrophyFishRarity.GOLD) { GlStateManager.color(1, 0.82F, 0, 1); } if (highestRarity == TrophyFish.TrophyFishRarity.DIAMOND) { GlStateManager.color(31 / 255f, 216 / 255f, 241 / 255f, 1); } Utils.drawTexturedRect(x - 2, y - 2, 20, 20, 0, 20 / 256f, 0, 20 / 256f, GL11.GL_NEAREST); GlStateManager.color(1, 1, 1, 1); Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI(getItem(value.getName(), highestRarity), x, y); if (mouseX >= x && mouseX < x + 24) { if (mouseY >= y && mouseY <= y + 24) { tooltipToDisplay = new ArrayList<>(); tooltipToDisplay.addAll(getTooltip(value.getName(), value.getTrophyFishRarityIntegerMap())); } } } if (arrayList.size() != internalTrophyFish.size()) { List clonedList = new ArrayList<>(internalTrophyFish.size()); clonedList.addAll(internalTrophyFish.keySet()); clonedList.removeAll(fixStringName(new ArrayList<>(trophyFishList.keySet()))); for (String difference : clonedList) { RenderHelper.enableGUIStandardItemLighting(); x = guiLeft + slotLocations.get(clonedList.indexOf(difference) + (trophyFishList.keySet().size())).getLeft(); y = guiTop + slotLocations.get(clonedList.indexOf(difference) + (trophyFishList.keySet().size())).getRight(); ItemStack itemStack = new ItemStack(Items.dye, 1, 8); Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI(itemStack, x, y); if (mouseX >= x && mouseX < x + 24) { if (mouseY >= y && mouseY <= y + 24) { tooltipToDisplay = new ArrayList<>(); tooltipToDisplay.addAll(getTooltip(difference, null)); GlStateManager.color(1, 1, 1, 1); } } Minecraft.getMinecraft().getTextureManager().bindTexture(pv_elements); Utils.drawTexturedRect(x - 2, y - 2, 20, 20, 0, 20 / 256f, 0, 20 / 256f, GL11.GL_NEAREST); } } int[] trophiesPerTier = getTrophiesPerTier(trophyObject); JsonArray rewards = Utils.getElementOrDefault(selectedProfile.getProfileJson(), "trophy_fish.rewards", new JsonArray()).getAsJsonArray(); int i = 0; for (ItemStack itemStack : armorHelmets.keySet()) { RenderHelper.enableGUIStandardItemLighting(); int integer = armorHelmets.get(itemStack).getRight(); x = guiLeft + 15; y = guiTop + 50 + i; Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI(itemStack, x, y); Utils.drawStringF(armorHelmets.get(itemStack).getLeft(), x + 20, y + 4, true, 0); int hasValue = trophiesPerTier[integer - 1]; int neededValue = integer == 1 ? 15 : 18; String neededText = (hasValue == neededValue ? "§a" : "§c") + hasValue + "/" + neededValue; try { JsonElement jsonElement = rewards.get(integer - 1); if (!jsonElement.isJsonNull()) { Utils.drawStringF(check, x + 100, y + 2, true, 0); } else { Utils.drawStringF(neededText, x + 100, y + 4, true, 0); } } catch (IndexOutOfBoundsException exception) { Utils.drawStringF(neededText, x + 100, y + 4, true, 0); } i += 10; } if (tooltipToDisplay != null) { Utils.drawHoveringText( tooltipToDisplay, mouseX, mouseY, getInstance().width, getInstance().height, -1, Minecraft.getMinecraft().fontRendererObj ); tooltipToDisplay = null; } GlStateManager.enableLighting(); } private int[] getTrophiesPerTier(JsonObject trophyFish) { int[] trophiesPerTier = new int[]{0, 0, 0, 0}; for (String fishType : internalTrophyFish.keySet()) { int highestTier = 0; if (trophyFish.has((fishType + "_bronze"))) highestTier = 1; if (trophyFish.has((fishType + "_silver"))) highestTier = 2; if (trophyFish.has((fishType + "_gold"))) highestTier = 3; if (trophyFish.has((fishType + "_diamond"))) highestTier = 4; if (highestTier >= 1) trophiesPerTier[0]++; if (highestTier >= 2) trophiesPerTier[1]++; if (highestTier >= 3) trophiesPerTier[2]++; if (highestTier >= 4) trophiesPerTier[3]++; } return trophiesPerTier; } private List getTooltip(String name, Map trophyFishRarityIntegerMap) { List tooltip = new ArrayList<>(); tooltip.add(internalTrophyFish.get(name.toLowerCase(Locale.US).replace(" ", "_")) + WordUtils.capitalize(name.replace("_", " "))); List lore = readLoreFromRepo(name.toUpperCase(Locale.US)); List description = readDescriptionFromLore(lore); tooltip.addAll(description); tooltip.add(" "); if (trophyFishRarityIntegerMap == null) { tooltip.add(EnumChatFormatting.RED + checkX + " Not Discovered"); tooltip.add(" "); } tooltip.add(display(trophyFishRarityIntegerMap, TrophyFish.TrophyFishRarity.DIAMOND, EnumChatFormatting.AQUA)); tooltip.add(display(trophyFishRarityIntegerMap, TrophyFish.TrophyFishRarity.GOLD, EnumChatFormatting.GOLD)); tooltip.add(display(trophyFishRarityIntegerMap, TrophyFish.TrophyFishRarity.SILVER, EnumChatFormatting.GRAY)); tooltip.add(display(trophyFishRarityIntegerMap, TrophyFish.TrophyFishRarity.BRONZE, EnumChatFormatting.DARK_GRAY)); if (trophyFishList.get(name) != null) { tooltip.add(" "); tooltip.add(EnumChatFormatting.GRAY + "Total: " + EnumChatFormatting.GOLD + StringUtils.formatNumber(trophyFishList.get(name).getTotal())); } return tooltip; } private String display( Map trophyFishRarityIntegerMap, TrophyFish.TrophyFishRarity rarity, EnumChatFormatting color ) { String name = WordUtils.capitalize(rarity.name().toLowerCase(Locale.US)); if (trophyFishRarityIntegerMap == null) { return color + name + ": " + checkX; } if (trophyFishRarityIntegerMap.containsKey(rarity)) { return color + name + ": " + EnumChatFormatting.GOLD + StringUtils.formatNumber(trophyFishRarityIntegerMap.get( rarity)); } else { return color + name + ": " + checkX; } } private Optional getHighestRarity(Map trophyFishRarityMap) { if (trophyFishRarityMap == null) return Optional.empty(); return trophyFishRarityMap.keySet().stream().max(Comparator.comparing(Enum::ordinal)); } private ItemStack getItem(String name, TrophyFish.TrophyFishRarity highestCaughtRarity) { String repoName = name.toUpperCase(Locale.US).replace(" ", "_") + "_" + (highestCaughtRarity == null ? "BRONZE" : highestCaughtRarity.name()); JsonObject jsonItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(repoName); return NotEnoughUpdates.INSTANCE.manager.jsonToStack(jsonItem); } private void loadTrophyInformation(JsonObject trophyObject) { Map>> trophyFishRarityIntegerMap = new HashMap<>(); totalCount = 0; for (Map.Entry stringJsonElementEntry : trophyObject.entrySet()) { String key = stringJsonElementEntry.getKey(); if (key.equalsIgnoreCase("rewards") || key.equalsIgnoreCase("total_caught") || key.equalsIgnoreCase("last_caught")) { if (key.equalsIgnoreCase("total_caught")) { totalCount = stringJsonElementEntry.getValue().getAsInt(); } continue; } String[] s = key.split("_"); String type = s[s.length - 1]; TrophyFish.TrophyFishRarity trophyFishRarity; int value = 0; try { value = stringJsonElementEntry.getValue().getAsInt(); } catch (NumberFormatException e) { value = -1; } if (key.startsWith("golden_fish_")) { type = s[2]; } try { trophyFishRarity = TrophyFish.TrophyFishRarity.valueOf(type.toUpperCase(Locale.US)); } catch (IllegalArgumentException ignored) { total.put(WordUtils.capitalize(key), value); continue; } String replace = key.replace("_" + type, ""); String name = WordUtils.capitalize(replace); List> pairs; if (trophyFishRarityIntegerMap.containsKey(name)) { pairs = trophyFishRarityIntegerMap.get(name); } else { pairs = new ArrayList<>(); } pairs.add(Pair.of(trophyFishRarity, value)); trophyFishRarityIntegerMap.put(name, pairs); } trophyFishRarityIntegerMap.forEach((name, pair) -> { if (!trophyFishList.containsKey(name)) { TrophyFish trophyFish = new TrophyFish(name, new HashMap<>()); trophyFish.addTotal(total.get(name)); for (Pair pair1 : pair) { trophyFish.add(pair1.getKey(), pair1.getValue()); } trophyFishList.put(name, trophyFish); } else { TrophyFish trophyFish = trophyFishList.get(name); for (Pair pair1 : pair) { trophyFish.add(pair1.getKey(), pair1.getValue()); } } }); } private List fixStringName(List list) { List fixedList = new ArrayList<>(); for (String s : list) { fixedList.add(s.toLowerCase(Locale.US).replace(" ", "_")); } return fixedList; } private List readDescriptionFromLore(List lore) { List description = new ArrayList<>(); boolean found = false; for (String line : lore) { if (!found && line.startsWith("§7")) found = true; if (found && line.isEmpty()) break; if (found) { description.add(line); } } return description; } private List readLoreFromRepo(String name) { String repoName = name.toUpperCase(Locale.US).replace(" ", "_") + "_BRONZE"; JsonObject jsonItem = NotEnoughUpdates.INSTANCE.manager.getItemInformation().get(repoName); List list = new ArrayList<>(); if (jsonItem != null && jsonItem.has("lore")) { for (JsonElement line : jsonItem.getAsJsonArray("lore")) { list.add(line.getAsString()); } } return list; } }