diff options
6 files changed, 413 insertions, 2 deletions
diff --git a/Update Notes/2.1.1.md b/Update Notes/2.1.1.md index 988913cc..3bf0b5a6 100644 --- a/Update Notes/2.1.1.md +++ b/Update Notes/2.1.1.md @@ -18,8 +18,10 @@ - Add exponent and percentage to calculator - u9g - Add total trophy fish count to /pv - Vixid - Allow hiding messages below a set skyblock level - nopo + - Add crimson isle page to /pv - Vixid - Add crimson isle quests to todo overlay - Vixid - Add replace chat social options to both party and guild chat - Vixid - Add class average to dungeons page in /pv - Vixid - Add recipe history and fairy soul waypoint distance - Vixid - Fix buggy cape on player model in /pv - Vixid + diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index 6c6c7169..948b2550 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -266,6 +266,9 @@ public class NotEnoughUpdates { if (config.profileViewer.pageLayout.size() == 9) { config.profileViewer.pageLayout.add(9); } + if (config.profileViewer.pageLayout.size() == 10) { + config.profileViewer.pageLayout.add(10); + } // Remove after 2.1 ig if ("dangerous".equals(config.apiData.repoBranch)) { 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 index 951438fb..30915daa 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/options/seperateSections/ProfileViewer.java @@ -74,10 +74,11 @@ public class ProfileViewer { "\u00a7eBingo", "\u00a7eTrophy Fish", "\u00a7eBestiary", + "\u00a7eCrimson Isle", }, allowDeleting = false ) - public List<Integer> pageLayout = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); + public List<Integer> pageLayout = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); @Expose @ConfigOption( diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java new file mode 100644 index 00000000..f9d91935 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2022 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 <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.profileviewer; + +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.renderer.RenderHelper; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; +import org.lwjgl.opengl.GL11; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +public class CrimsonIslePage extends GuiProfileViewerPage { + + private static final ResourceLocation CRIMSON_ISLE = + new ResourceLocation("notenoughupdates:pv_crimson_isle_page.png"); + + private static final DateFormat dateFormat = new SimpleDateFormat("EEE d MMM yyyy"); + private static final DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss"); + private static final String[] dojoGrades = {"F", "D", "C", "B", "A", "S"}; + + private static final ItemStack[] KUUDRA_KEYS = { + NotEnoughUpdates.INSTANCE.manager.createItem("KUUDRA_TIER_KEY"), + NotEnoughUpdates.INSTANCE.manager.createItem("KUUDRA_HOT_TIER_KEY"), + NotEnoughUpdates.INSTANCE.manager.createItem("KUUDRA_BURNING_TIER_KEY"), + NotEnoughUpdates.INSTANCE.manager.createItem("KUUDRA_FIERY_TIER_KEY"), + NotEnoughUpdates.INSTANCE.manager.createItem("KUUDRA_INFERNAL_TIER_KEY"), + }; + + public static final String[] KUUDRA_TIERS = { + "Basic", + "Hot", + "Burning", + "Fiery", + "Infernal" + }; + + private static final LinkedHashMap<String, String> apiDojoTestNames = new LinkedHashMap<String, String>() {{ + put("mob_kb", EnumChatFormatting.GOLD + "Test of Force"); + put("wall_jump", EnumChatFormatting.LIGHT_PURPLE + "Test of Stamina"); + put("archer", EnumChatFormatting.YELLOW + "Test of Mastery"); + put("sword_swap", EnumChatFormatting.RED + "Test of Discipline"); + put("snake", EnumChatFormatting.GREEN + "Test of Swiftness"); + put("lock_head", EnumChatFormatting.BLUE + "Test of Control"); + put("fireball", EnumChatFormatting.GOLD + "Test of Tenacity"); + }}; + + private static final LinkedHashMap<Integer, String> dojoPointsToRank = new LinkedHashMap<Integer, String>() {{ + put(0, EnumChatFormatting.GRAY + "None"); + put(1000, EnumChatFormatting.YELLOW + "Yellow"); + put(2000, EnumChatFormatting.GREEN + "Green"); + put(4000, EnumChatFormatting.BLUE + "Blue"); + put(6000, EnumChatFormatting.GOLD + "Brown"); + put(7000, EnumChatFormatting.DARK_GRAY + "Black"); + }}; + + private static final HashMap<String, String> factions = new HashMap<String, String>() {{ + put("mages", EnumChatFormatting.DARK_PURPLE + "Mages"); + put("barbarians", EnumChatFormatting.RED + "Barbarians"); + put("N/A", EnumChatFormatting.GRAY + "N/A"); + }}; + + private static final LinkedHashMap<Integer, String> factionThresholds = new LinkedHashMap<Integer, String>() {{ + put(-3000, "Hostile"); + put(-1000, "Unfriendly"); + put(0, "Neutral"); + put(1000, "Friendly"); + put(3000, "Trusted"); + put(6000, "Honored"); + put(12000, "Hero"); + }}; + + public CrimsonIslePage(GuiProfileViewer instance) { + super(instance); + } + + @Override + public void drawPage(int mouseX, int mouseY, float partialTicks) { + int guiLeft = GuiProfileViewer.getGuiLeft(); + int guiTop = GuiProfileViewer.getGuiTop(); + + JsonObject profileInfo = GuiProfileViewer.getProfile().getProfileInformation(GuiProfileViewer.getProfileId()); + + if (profileInfo == null || !profileInfo.has("nether_island_player_data")) { + Utils.drawStringCentered( + EnumChatFormatting.RED + "No data found for the Crimson Isles", + Minecraft.getMinecraft().fontRendererObj, + guiLeft + 431 / 2f, + guiTop + 101, + true, + 0 + ); + return; + } + + Minecraft.getMinecraft().getTextureManager().bindTexture(CRIMSON_ISLE); + Utils.drawTexturedRect(guiLeft, guiTop, 431, 202, GL11.GL_NEAREST); + + JsonObject netherIslandPlayerData = profileInfo.getAsJsonObject("nether_island_player_data"); + + // Dojo stats + drawDojoStats(netherIslandPlayerData, guiLeft, guiTop); + + // Kuudra stats + drawKuudraStats(netherIslandPlayerData, guiLeft, guiTop); + + // Last matriarch attempt + drawLastMatriarchAttempt(netherIslandPlayerData, guiLeft, guiTop); + + // Faction reputation + drawFactionReputation(netherIslandPlayerData, guiLeft, guiTop); + } + + public void drawKuudraStats(JsonObject data, int guiLeft, int guiTop) { + Utils.drawStringCentered( + EnumChatFormatting.RED + "Kuudra Stats", + Minecraft.getMinecraft().fontRendererObj, + guiLeft + (431 * 0.18f), + guiTop + 14, + true, + 0 + ); + + JsonObject kuudraCompletedTiers = data.getAsJsonObject("kuudra_completed_tiers"); + + // This is different to the one initialised at the start of the class as these refer to the names of the tiers in the API + String[] kuudraTiers = {"none", "hot", "burning", "fiery", "infernal"}; + + RenderHelper.enableGUIStandardItemLighting(); + + for (int i = 0; i < 5; i++) { + // Checking the player has completions for each tier + // and get the number of completions if they do + int completions = + kuudraCompletedTiers.has(kuudraTiers[i]) ? kuudraCompletedTiers.get(kuudraTiers[i]).getAsInt() : 0; + + Minecraft.getMinecraft().getRenderItem().renderItemIntoGUI( + KUUDRA_KEYS[i], + guiLeft + 8, + guiTop + 25 + (i * 12) + ); + + Utils.renderAlignedString( + EnumChatFormatting.RED + KUUDRA_TIERS[i] + ": ", + EnumChatFormatting.WHITE + String.valueOf(completions), + guiLeft + 23, + guiTop + 30 + (i * 12), + 110 + ); + } + + Utils.renderAlignedString( + EnumChatFormatting.RED + "Total: ", + EnumChatFormatting.WHITE + String.valueOf(getTotalKuudraRuns(kuudraCompletedTiers)), + guiLeft + 23, + guiTop + 40 + (5 * 12), + 110 + ); + } + + public int getTotalKuudraRuns(JsonObject completedRuns) { + int totalRuns = 0; + for (Map.Entry<String, JsonElement> runs : completedRuns.entrySet()) { + totalRuns += runs.getValue().getAsInt(); + } + return totalRuns; + } + + public void drawDojoStats(JsonObject data, int guiLeft, int guiTop) { + Utils.drawStringCentered( + EnumChatFormatting.YELLOW + "Dojo Stats", + Minecraft.getMinecraft().fontRendererObj, + guiLeft + (431 * 0.49f), + guiTop + 14, + true, + 0 + ); + + JsonObject dojoStats = data.getAsJsonObject("dojo"); + int[] dojoScores = {0, 0, 0, 0, 0, 0, 0}; + int pointsTotal = 0; + + for (int i = 0; i < apiDojoTestNames.size(); i++) { + for (Map.Entry<String, JsonElement> dojoData : dojoStats.entrySet()) { + if (dojoData.getKey().equals("dojo_points_" + apiDojoTestNames.keySet().toArray()[i])) { + dojoScores[i] = dojoData.getValue().getAsInt(); + pointsTotal += dojoData.getValue().getAsInt(); + } + } + } + + for (int i = 0; i < apiDojoTestNames.size(); i++) { + Utils.renderAlignedString( + apiDojoTestNames.get(apiDojoTestNames.keySet().toArray()[i]) + ": ", + EnumChatFormatting.WHITE + String.valueOf(dojoScores[i]) + " (" + + dojoGrades[(dojoScores[i] / 200) >= 6 ? 5 : (dojoScores[i] / 200)] + ")", + guiLeft + (431 * 0.49f) - 65, + guiTop + 30 + (i * 12), + 130 + ); + } + + Utils.renderAlignedString( + EnumChatFormatting.GRAY + "Points: ", + EnumChatFormatting.GOLD + String.valueOf(pointsTotal), + guiLeft + (431 * 0.49f) - 65, + guiTop + 40 + (apiDojoTestNames.size() * 12), + 130 + ); + + Utils.renderAlignedString( + EnumChatFormatting.GRAY + "Rank: ", + getRank(pointsTotal), + guiLeft + (431 * 0.49f) - 65, + guiTop + 52 + (apiDojoTestNames.size() * 12), + 130 + ); + + Utils.renderAlignedString( + EnumChatFormatting.GRAY + "Points to next: ", + getPointsToNextRank(pointsTotal) == 0 + ? EnumChatFormatting.GOLD + "MAXED!" + : String.valueOf(getPointsToNextRank(pointsTotal)), + guiLeft + (431 * 0.49f) - 65, + guiTop + 64 + (apiDojoTestNames.size() * 12), + 130 + ); + } + + public String getRank(int points) { + int lastRank = 0; + for (Map.Entry<Integer, String> rank : dojoPointsToRank.entrySet()) { + if (points < rank.getKey()) { + return dojoPointsToRank.get(lastRank); + } + lastRank = rank.getKey(); + } + return dojoPointsToRank.get(dojoPointsToRank.keySet().toArray()[dojoPointsToRank.size() - 1]); + } + + public int getPointsToNextRank(int pointsTotal) { + int pointsToNextRank = 0; + for (Map.Entry<Integer, String> dojoRank : dojoPointsToRank.entrySet()) { + if (dojoRank.getKey() > pointsTotal) { + pointsToNextRank = dojoRank.getKey(); + break; + } + } + return pointsToNextRank == 0 ? 0 : pointsToNextRank - pointsTotal; + } + + public void drawLastMatriarchAttempt(JsonObject data, int guiLeft, int guiTop) { + Utils.drawStringCentered( + EnumChatFormatting.GOLD + "Last Matriarch Attempt", + Minecraft.getMinecraft().fontRendererObj, + guiLeft + (431 * 0.82f), + guiTop + 104, + true, + 0 + ); + + JsonObject lastMatriarchAttempt = data.getAsJsonObject("matriarch"); + + if (!lastMatriarchAttempt.entrySet().isEmpty()) { + Utils.renderAlignedString( + EnumChatFormatting.GOLD + "Heavy Pearls Acquired: ", + EnumChatFormatting.WHITE + lastMatriarchAttempt.get("pearls_collected").getAsString(), + guiLeft + 290, + guiTop + 119, + 130 + ); + + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(lastMatriarchAttempt.get("last_attempt").getAsLong()); + String date = dateFormat.format(calendar.getTime()); + String time = timeFormat.format(calendar.getTime()); + + Utils.renderAlignedString( + EnumChatFormatting.GOLD + "Last Attempt: ", + EnumChatFormatting.WHITE + date, + guiLeft + 290, + guiTop + 131, + 130 + ); + + Utils.renderAlignedString( + EnumChatFormatting.GOLD + " ", + EnumChatFormatting.WHITE + time, + guiLeft + 290, + guiTop + 143, + 130 + ); + return; + } + + Utils.renderAlignedString( + EnumChatFormatting.RED + "No attempts found!", + " ", + guiLeft + 290, + guiTop + 119, + 130 + ); + } + + public void drawFactionReputation(JsonObject data, int guiLeft, int guiTop) { + Utils.drawStringCentered( + EnumChatFormatting.DARK_PURPLE + "Faction Reputation", + Minecraft.getMinecraft().fontRendererObj, + guiLeft + (431 * 0.82f), + guiTop + 14, + true, + 0 + ); + + String selectedFaction = data.has("selected_faction") ? data.get("selected_faction").getAsString() : "N/A"; + + Utils.renderAlignedString( + EnumChatFormatting.GREEN + "Faction: ", + factions.get(selectedFaction), + guiLeft + 290, + guiTop + 30, + 130 + ); + + int mageReputation = data.has("mages_reputation") ? data.get("mages_reputation").getAsInt() : 0; + int barbarianReputation = data.has("barbarians_reputation") ? data.get("barbarians_reputation").getAsInt() : 0; + + // Mage reputation + int mageReputationThreshold = 0; + for (Map.Entry<Integer, String> factionThreshold : factionThresholds.entrySet()) { + if (mageReputation >= factionThreshold.getKey()) { + mageReputationThreshold = factionThreshold.getKey(); + } + } + + Utils.renderAlignedString( + EnumChatFormatting.DARK_PURPLE + "Mage Reputation: ", + EnumChatFormatting.WHITE + String.valueOf(mageReputation), + guiLeft + 290, + guiTop + 42 + (selectedFaction.equals("mages") || selectedFaction.equals("N/A") ? 0 : 24), + 130 + ); + + Utils.renderAlignedString( + EnumChatFormatting.DARK_PURPLE + "Title: ", + EnumChatFormatting.WHITE + factionThresholds.get(mageReputationThreshold), + guiLeft + 290, + guiTop + 54 + (selectedFaction.equals("mages") || selectedFaction.equals("N/A") ? 0 : 24), + 130 + ); + + // Barbarian reputation + int barbarianReputationThreshold = 0; + for (Map.Entry<Integer, String> factionThreshold : factionThresholds.entrySet()) { + if (barbarianReputation >= factionThreshold.getKey()) { + barbarianReputationThreshold = factionThreshold.getKey(); + } + } + + Utils.renderAlignedString( + EnumChatFormatting.RED + "Barbarian Reputation: ", + EnumChatFormatting.WHITE + String.valueOf(barbarianReputation), + guiLeft + 290, + guiTop + 42 + (selectedFaction.equals("barbarians") ? 0 : 24), + 130 + ); + + Utils.renderAlignedString( + EnumChatFormatting.RED + "Title: ", + EnumChatFormatting.WHITE + factionThresholds.get(barbarianReputationThreshold), + guiLeft + 290, + guiTop + 54 + (selectedFaction.equals("barbarians") ? 0 : 24), + 130 + ); + } +} 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 37605595..cc13e820 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -218,6 +218,7 @@ public class GuiProfileViewer extends GuiScreen { pages.put(ProfileViewerPage.BINGO, new BingoPage(this)); pages.put(ProfileViewerPage.TROPHY_FISH, new TrophyFishPage(this)); pages.put(ProfileViewerPage.BESTIARY, new BestiaryPage(this)); + pages.put(ProfileViewerPage.CRIMSON_ISLE, new CrimsonIslePage(this)); } private static float getMaxLevelXp(JsonArray levels, int offset, int maxLevel) { @@ -1314,7 +1315,8 @@ public class GuiProfileViewer extends GuiScreen { MINING(6, Items.iron_pickaxe, "§5Heart of the Mountain"), BINGO(7, Items.filled_map, "§zBingo"), TROPHY_FISH(8, Items.fishing_rod, "§3Trophy Fish"), - BESTIARY(9, Items.iron_sword, "§cBestiary"); + BESTIARY(9, Items.iron_sword, "§cBestiary"), + CRIMSON_ISLE(10, Item.getItemFromBlock(Blocks.netherrack), "§4Crimson Isle"); public final ItemStack stack; public final int id; diff --git a/src/main/resources/assets/notenoughupdates/pv_crimson_isle_page.png b/src/main/resources/assets/notenoughupdates/pv_crimson_isle_page.png Binary files differnew file mode 100644 index 00000000..b08c0057 --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/pv_crimson_isle_page.png |