aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java4
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java227
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java5
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java6
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java225
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java84
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java2
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java105
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java255
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java36
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/LevelPage.java195
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/CoreTaskLevel.java169
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/DungeonTaskLevel.java126
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EssenceTaskLevel.java151
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/MiscTaskLevel.java200
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SkillRelatedTaskLevel.java211
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SlayingTaskLevel.java291
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/StoryTaskLevel.java81
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java3
-rw-r--r--src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java85
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt6
-rw-r--r--src/main/resources/assets/notenoughupdates/pv_basic.pngbin2836 -> 2818 bytes
-rw-r--r--src/main/resources/assets/notenoughupdates/pv_levels.pngbin0 -> 3526 bytes
25 files changed, 2097 insertions, 374 deletions
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
index 7159ef89..8442697a 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java
@@ -105,10 +105,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
public class NEUOverlay extends Gui {
- private static final ResourceLocation SUPERGEHEIMNISVERMOGEN = new ResourceLocation(
+ public static final ResourceLocation SUPERGEHEIMNISVERMOGEN = new ResourceLocation(
"notenoughupdates:supersecretassets/bald.png");
- private static final ResourceLocation ATMOULBERRYWHYISMYLUNARCLIENTBUGGING = new ResourceLocation(
+ public static final ResourceLocation ATMOULBERRYWHYISMYLUNARCLIENTBUGGING = new ResourceLocation(
"notenoughupdates:supersecretassets/lunar.png");
private static final ResourceLocation SEARCH_BAR = new ResourceLocation("notenoughupdates:search_bar.png");
private static final ResourceLocation SEARCH_BAR_GOLD = new ResourceLocation("notenoughupdates:search_bar_gold.png");
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java
index 5787c075..0d882358 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java
@@ -147,7 +147,7 @@ public class DevTestCommand extends ClientCommandBase {
})
.thenCompose(obj -> ProfileCollectionInfo.getCollectionData(
obj,
- Minecraft.getMinecraft().thePlayer.getUniqueID()
+ Minecraft.getMinecraft().thePlayer.getUniqueID().toString()
))
.thenAccept(it ->
Utils.addChatMessage("Response: " + it));
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java
index 873ee9f2..0f17bb86 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/BasicPage.java
@@ -19,13 +19,13 @@
package io.github.moulberry.notenoughupdates.profileviewer;
-import com.google.common.base.Splitter;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.core.util.StringUtils;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
import io.github.moulberry.notenoughupdates.profileviewer.weight.lily.LilyWeight;
import io.github.moulberry.notenoughupdates.profileviewer.weight.senither.SenitherWeight;
import io.github.moulberry.notenoughupdates.util.Constants;
@@ -53,11 +53,12 @@ import org.apache.commons.lang3.text.WordUtils;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
-import org.lwjgl.opengl.GL14;
import java.awt.*;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -72,6 +73,34 @@ import static io.github.moulberry.notenoughupdates.util.Utils.roundToNearestInt;
public class BasicPage extends GuiProfileViewerPage {
private static final ResourceLocation pv_basic = new ResourceLocation("notenoughupdates:pv_basic.png");
+
+ public static final ItemStack skull = Utils.createSkull(
+ "egirlefe",
+ "152de44a-43a3-46e1-badc-66cca2793471",
+ "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODdkODg1YjMyYjBkZDJkNmI3ZjFiNTgyYTM0MTg2ZjhhNTM3M2M0NjU4OWEyNzM0MjMxMzJiNDQ4YjgwMzQ2MiJ9fX0="
+ );
+
+ private static final LinkedHashMap<String, ItemStack> dungeonsModeIcons = new LinkedHashMap<String, ItemStack>() {
+ {
+ put(
+ "first_page",
+ Utils.editItemStackInfo(
+ new ItemStack(Items.paper),
+ EnumChatFormatting.GRAY + "Front Page",
+ true
+ )
+ );
+ put(
+ "second_page",
+ Utils.editItemStackInfo(
+ skull,
+ EnumChatFormatting.GRAY + "Level Page",
+ true
+ )
+ );
+ }
+ };
+
private static final ExecutorService profileLoader = Executors.newFixedThreadPool(1);
public EntityOtherPlayerMP entityPlayer = null;
private ResourceLocation playerLocationSkin = null;
@@ -88,9 +117,14 @@ public class BasicPage extends GuiProfileViewerPage {
private int backgroundClickedX = -1;
+ private boolean onSecondPage;
+
+ private final LevelPage levelPage;
+
public BasicPage(GuiProfileViewer instance) {
super(instance);
this.guiProfileViewer = instance;
+ this.levelPage = new LevelPage(guiProfileViewer, this);
}
@Override
@@ -101,6 +135,11 @@ public class BasicPage extends GuiProfileViewerPage {
int guiLeft = GuiProfileViewer.getGuiLeft();
int guiTop = GuiProfileViewer.getGuiTop();
+ if (onSecondPage) {
+ levelPage.drawPage(mouseX, mouseY, partialTicks);
+ return;
+ }
+
String location = null;
JsonObject status = profile.getPlayerStatus();
if (status != null && status.has("mode")) {
@@ -534,116 +573,29 @@ public class BasicPage extends GuiProfileViewerPage {
);
}
- PlayerStats.Stats stats = profile.getStats(profileId);
+ // sb lvlL
- if (stats != null) {
- Splitter splitter = Splitter.on(" ").omitEmptyStrings().limit(2);
- for (int i = 0; i < PlayerStats.defaultStatNames.length; i++) {
- String statName = PlayerStats.defaultStatNames[i];
- //if (statName.equals("mining_fortune") || statName.equals("mining_speed")) continue;
- String statNamePretty = PlayerStats.defaultStatNamesPretty[i];
+ int sbLevelX = guiLeft + 162;
+ int sbLevelY = guiTop + 90;
- int val = Math.round(stats.get(statName));
+ double skyblockLevel = profile.getSkyblockLevel(profileId);
+ EnumChatFormatting skyblockLevelColour = profile.getSkyblockLevelColour(profileId);
- GlStateManager.color(1, 1, 1, 1);
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(
- GL11.GL_SRC_ALPHA,
- GL11.GL_ONE_MINUS_SRC_ALPHA,
- GL11.GL_ONE,
- GL11.GL_ONE_MINUS_SRC_ALPHA
- );
- Utils.renderAlignedString(
- statNamePretty,
- EnumChatFormatting.WHITE.toString() + val,
- guiLeft + 132,
- guiTop + 21 + 11f * i,
- 80
- );
+ GlStateManager.pushMatrix();
+ GlStateManager.translate(sbLevelX, sbLevelY, 0);
+ GlStateManager.scale(1.5f, 1.5f, 1);
+ Utils.drawItemStack(skull, 0, 0);
+ GlStateManager.popMatrix();
+ Utils.drawStringScaled(skyblockLevelColour.toString() + (int) skyblockLevel, fr,
+ sbLevelX - 2, sbLevelY - 15, true, 0, 1.5f
+ );
- if (mouseX > guiLeft + 132 && mouseX < guiLeft + 212) {
- if (mouseY > guiTop + 21 + 11f * i && mouseY < guiTop + 37 + 11f * i) {
- List<String> split = splitter.splitToList(statNamePretty);
- PlayerStats.Stats baseStats = PlayerStats.getBaseStats();
- getInstance().tooltipToDisplay = new ArrayList<>();
- getInstance().tooltipToDisplay.add(statNamePretty);
- int base = Math.round(baseStats.get(statName));
- getInstance()
- .tooltipToDisplay.add(
- EnumChatFormatting.GRAY +
- "Base " +
- split.get(1) +
- ": " +
- EnumChatFormatting.GREEN +
- base +
- " " +
- split.get(0)
- );
- int passive = Math.round(profile.getPassiveStats(profileId).get(statName) - baseStats.get(statName));
- getInstance()
- .tooltipToDisplay.add(
- EnumChatFormatting.GRAY +
- "Passive " +
- split.get(1) +
- " Bonus: +" +
- EnumChatFormatting.YELLOW +
- passive +
- " " +
- split.get(0)
- );
- int itemBonus = Math.round(stats.get(statName) - profile.getPassiveStats(profileId).get(statName));
- getInstance()
- .tooltipToDisplay.add(
- EnumChatFormatting.GRAY +
- "Item " +
- split.get(1) +
- " Bonus: +" +
- EnumChatFormatting.DARK_PURPLE +
- itemBonus +
- " " +
- split.get(0)
- );
- int finalStat = Math.round(stats.get(statName));
- getInstance()
- .tooltipToDisplay.add(
- EnumChatFormatting.GRAY +
- "Final " +
- split.get(1) +
- ": +" +
- EnumChatFormatting.RED +
- finalStat +
- " " +
- split.get(0)
- );
- }
- }
- }
- } else {
- Utils.drawStringCentered(
- EnumChatFormatting.RED + "Skill/Inv/Coll",
- Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 172,
- guiTop + 101 - 10,
- true,
- 0
- );
- Utils.drawStringCentered(
- EnumChatFormatting.RED + "APIs not",
- Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 172,
- guiTop + 101,
- true,
- 0
- );
- Utils.drawStringCentered(
- EnumChatFormatting.RED + "enabled!",
- Minecraft.getMinecraft().fontRendererObj,
- guiLeft + 172,
- guiTop + 101 + 10,
- true,
- 0
- );
- }
+ float progress = (float) (skyblockLevel - (long) skyblockLevel);
+ getInstance().renderBar(sbLevelX - 30, sbLevelY + 30, 80, progress);
+
+ Utils.drawStringScaled(EnumChatFormatting.YELLOW.toString() + (int) (progress * 100) + "/100", fr,
+ sbLevelX - 30, sbLevelY + 20, true, 0, 0.9f
+ );
if (skyblockInfo != null) {
int position = 0;
@@ -672,6 +624,12 @@ public class BasicPage extends GuiProfileViewerPage {
getInstance().renderBar(x, y + 6, 80, level.level % 1);
}
+ if (mouseX >= guiLeft + 128 && mouseX <= guiLeft + 216) {
+ if (mouseY >= guiTop + 69 && mouseY <= guiTop + 131) {
+ if(Mouse.isButtonDown(0)) onSecondPage = true;
+ }
+ }
+
if (mouseX > x && mouseX < x + 80) {
if (mouseY > y - 4 && mouseY < y + 13) {
getInstance().tooltipToDisplay = new ArrayList<>();
@@ -759,6 +717,7 @@ public class BasicPage extends GuiProfileViewerPage {
);
}
+ drawSideButtons();
renderWeight(mouseX, mouseY, skyblockInfo, profileInfo);
}
@@ -992,10 +951,62 @@ public class BasicPage extends GuiProfileViewerPage {
GlStateManager.setActiveTexture(OpenGlHelper.defaultTexUnit);
}
+ @Override
+ public boolean mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException {
+ super.mouseClicked(mouseX, mouseY, mouseButton);
+ int guiLeft = GuiProfileViewer.getGuiLeft();
+ int guiTop = GuiProfileViewer.getGuiTop();
+
+ int i = onSlotToChangePage(mouseX, mouseY, guiLeft, guiTop);
+ switch (i) {
+ case 1:
+ onSecondPage = false;
+ break;
+ case 2:
+ onSecondPage = true;
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+ }
+
+ public int onSlotToChangePage(int mouseX, int mouseY, int guiLeft, int guiTop) {
+ if (mouseX >= guiLeft - 29 && mouseX <= guiLeft) {
+ if (mouseY >= guiTop && mouseY <= guiTop + 28) {
+ return 1;
+ } else if (mouseY + 28 >= guiTop && mouseY <= guiTop + 28 * 2) {
+ return 2;
+ }
+ }
+ return 0;
+ }
+
public String getGameModeType(JsonObject profileInfo) {
if (profileInfo != null && profileInfo.has("game_mode")) {
return profileInfo.get("game_mode").getAsString();
}
return "";
}
+
+ public void drawSideButtons() {
+ GlStateManager.enableDepth();
+ GlStateManager.translate(0, 0, 5);
+ if (onSecondPage) {
+ Utils.drawPvSideButton(1, dungeonsModeIcons.get("second_page"), true, guiProfileViewer);
+ } else {
+ Utils.drawPvSideButton(0, dungeonsModeIcons.get("first_page"), true, guiProfileViewer);
+ }
+ GlStateManager.translate(0, 0, -3);
+
+ GlStateManager.translate(0, 0, -2);
+ if (!onSecondPage) {
+ Utils.drawPvSideButton(1, dungeonsModeIcons.get("second_page"), false, guiProfileViewer);
+ } else {
+ Utils.drawPvSideButton(0, dungeonsModeIcons.get("first_page"), false, guiProfileViewer);
+ }
+ GlStateManager.disableDepth();
+ }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java
index 554e204c..e2e40ed1 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CollectionsPage.java
@@ -37,6 +37,7 @@ import java.awt.*;
import java.io.IOException;
import java.text.NumberFormat;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@@ -217,10 +218,10 @@ public class CollectionsPage extends GuiProfileViewerPage {
String tierString;
int tier = (int) Utils.getElementAsFloat(collectionTiers.get(collection), 0);
- if (tier > 20 || tier < 0) {
+ if (tier > 20 || tier <= 0) {
tierString = String.valueOf(tier);
} else {
- tierString = romans[tier];
+ tierString = romans[tier-1];
}
float amount = Utils.getElementAsFloat(totalAmounts.get(collection), 0);
float maxAmount = Utils.getElementAsFloat(maxAmounts.get(collection), 0);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java
index 95009b1d..c423bab9 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/CrimsonIslePage.java
@@ -63,7 +63,7 @@ public class CrimsonIslePage extends GuiProfileViewerPage {
"Infernal"
};
- private static final LinkedHashMap<String, String> apiDojoTestNames = new LinkedHashMap<String, String>() {{
+ public 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");
@@ -73,7 +73,7 @@ public class CrimsonIslePage extends GuiProfileViewerPage {
put("fireball", EnumChatFormatting.GOLD + "Test of Tenacity");
}};
- private static final LinkedHashMap<Integer, String> dojoPointsToRank = new LinkedHashMap<Integer, String>() {{
+ public 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");
@@ -278,7 +278,7 @@ public class CrimsonIslePage extends GuiProfileViewerPage {
);
}
- public String getRank(int points) {
+ public static String getRank(int points) {
int lastRank = 0;
for (Map.Entry<Integer, String> rank : dojoPointsToRank.entrySet()) {
if (points < rank.getKey()) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java
index cbebb6f4..2c0dc110 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/DungeonPage.java
@@ -54,7 +54,7 @@ public class DungeonPage extends GuiProfileViewerPage {
private static final ResourceLocation pv_dung = new ResourceLocation("notenoughupdates:pv_dung.png");
private static final ItemStack DEADBUSH = new ItemStack(Item.getItemFromBlock(Blocks.deadbush));
- private static final String[] dungSkillsName = { "Healer", "Mage", "Berserk", "Archer", "Tank" };
+ private static final String[] dungSkillsName = {"Healer", "Mage", "Berserk", "Archer", "Tank"};
private static final ItemStack[] BOSS_HEADS = new ItemStack[7];
private static final ItemStack[] dungSkillsStack = {
new ItemStack(Items.potionitem, 1, 16389),
@@ -63,7 +63,7 @@ public class DungeonPage extends GuiProfileViewerPage {
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[] bossFloorArr = {"Bonzo", "Scarf", "Professor", "Thorn", "Livid", "Sadan", "Necron"};
private static final String[] bossFloorHeads = {
"12716ecbf5b8da00b05f316ec6af61e8bd02805b21eb8e440151468dc656549c",
"7de7bbbdf22bfe17980d4e20687e386f11d59ee1db6f8b4762391b79a5ac532d",
@@ -145,7 +145,10 @@ public class DungeonPage extends GuiProfileViewerPage {
//Catacombs level thingy
{
if (levelObjCata == null) {
- float cataXp = Utils.getElementAsFloat(Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.experience"), 0);
+ float cataXp = Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "dungeons.dungeon_types.catacombs.experience"
+ ), 0);
levelObjCata =
ProfileViewer.getLevel(
Utils.getElementOrDefault(leveling, "catacombs", new JsonArray()).getAsJsonArray(),
@@ -181,11 +184,20 @@ public class DungeonPage extends GuiProfileViewerPage {
if (mouseX > x && mouseX < x + sectionWidth && mouseY > y + 16 && mouseY < y + 24 && !onMasterMode) {
float F5 =
- (Utils.getElementAsFloat(Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.tier_completions." + 5), 0)); //this can prob be done better
+ (Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "dungeons.dungeon_types.catacombs.tier_completions." + 5
+ ), 0)); //this can prob be done better
float F6 =
- (Utils.getElementAsFloat(Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.tier_completions." + 6), 0));
+ (Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "dungeons.dungeon_types.catacombs.tier_completions." + 6
+ ), 0));
float F7 =
- (Utils.getElementAsFloat(Utils.getElement(profileInfo, "dungeons.dungeon_types.catacombs.tier_completions." + 7), 0));
+ (Utils.getElementAsFloat(Utils.getElement(
+ profileInfo,
+ "dungeons.dungeon_types.catacombs.tier_completions." + 7
+ ), 0));
if (F5 > 150) {
F5 = 150;
}
@@ -223,7 +235,8 @@ public class DungeonPage extends GuiProfileViewerPage {
getInstance().tooltipToDisplay =
Lists.newArrayList(
- EnumChatFormatting.YELLOW + "Remaining XP: " + EnumChatFormatting.GRAY + String.format("%,d", floorLevelToXP),
+ EnumChatFormatting.YELLOW + "Remaining XP: " + EnumChatFormatting.GRAY +
+ String.format("%,d", floorLevelToXP),
String.format("# F5 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpF5), runsF5),
String.format("# F6 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpF6), runsF6),
String.format("# F7 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpF7), runsF7),
@@ -232,17 +245,26 @@ public class DungeonPage extends GuiProfileViewerPage {
boolean hasTime = false;
if (timeF5 > 1000) {
getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (F5) : %s", Utils.prettyTime(runsF5 * (long) (timeF5 * 1.2))));
+ .tooltipToDisplay.add(String.format(
+ "Expected Time (F5) : %s",
+ Utils.prettyTime(runsF5 * (long) (timeF5 * 1.2))
+ ));
hasTime = true;
}
if (timeF6 > 1000) {
getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (F6) : %s", Utils.prettyTime(runsF6 * (long) (timeF6 * 1.2))));
+ .tooltipToDisplay.add(String.format(
+ "Expected Time (F6) : %s",
+ Utils.prettyTime(runsF6 * (long) (timeF6 * 1.2))
+ ));
hasTime = true;
}
if (timeF7 > 1000) {
getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (F7) : %s", Utils.prettyTime(runsF7 * (long) (timeF7 * 1.2))));
+ .tooltipToDisplay.add(String.format(
+ "Expected Time (F7) : %s",
+ Utils.prettyTime(runsF7 * (long) (timeF7 * 1.2))
+ ));
hasTime = true;
}
if (hasTime) {
@@ -261,19 +283,20 @@ public class DungeonPage extends GuiProfileViewerPage {
getInstance()
.tooltipToDisplay.add(
"The " +
- EnumChatFormatting.DARK_PURPLE +
- "Catacombs Expert Ring" +
- EnumChatFormatting.GRAY +
- " is assumed to be used, unless " +
- EnumChatFormatting.YELLOW +
- "SHIFT" +
- EnumChatFormatting.GRAY +
- " is held."
+ EnumChatFormatting.DARK_PURPLE +
+ "Catacombs Expert Ring" +
+ EnumChatFormatting.GRAY +
+ " is assumed to be used, unless " +
+ EnumChatFormatting.YELLOW +
+ "SHIFT" +
+ EnumChatFormatting.GRAY +
+ " is held."
);
getInstance().tooltipToDisplay.add("[Time per run] is calculated using Fastest S+ x 120%");
} else {
getInstance()
- .tooltipToDisplay.add("[Hold " + EnumChatFormatting.YELLOW + "CTRL" + EnumChatFormatting.GRAY + " to see details]");
+ .tooltipToDisplay.add(
+ "[Hold " + EnumChatFormatting.YELLOW + "CTRL" + EnumChatFormatting.GRAY + " to see details]");
}
}
@@ -371,38 +394,54 @@ public class DungeonPage extends GuiProfileViewerPage {
getInstance().tooltipToDisplay =
Lists.newArrayList(
- EnumChatFormatting.YELLOW + "Remaining XP: " + EnumChatFormatting.GRAY + String.format("%,d", floorLevelToXP),
+ EnumChatFormatting.YELLOW + "Remaining XP: " + EnumChatFormatting.GRAY +
+ String.format("%,d", floorLevelToXP),
String.format("# M3 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM3), runsM3),
String.format("# M4 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM4), runsM4),
String.format("# M5 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM5), runsM5),
String.format("# M6 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM6), runsM6),
- String.format("# M7 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM7), runsM7),
+ String.format("# M7 Runs (%s xp) : %d", StringUtils.shortNumberFormat(xpM7), runsM7),
""
);
boolean hasTime = false;
if (timeM3 > 1000) {
getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (M3) : %s", Utils.prettyTime(runsM3 * (long) (timeM3 * 1.2))));
+ .tooltipToDisplay.add(String.format(
+ "Expected Time (M3) : %s",
+ Utils.prettyTime(runsM3 * (long) (timeM3 * 1.2))
+ ));
hasTime = true;
}
if (timeM4 > 1000) {
getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (M4) : %s", Utils.prettyTime(runsM4 * (long) (timeM4 * 1.2))));
+ .tooltipToDisplay.add(String.format(
+ "Expected Time (M4) : %s",
+ Utils.prettyTime(runsM4 * (long) (timeM4 * 1.2))
+ ));
hasTime = true;
}
if (timeM5 > 1000) {
getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (M5) : %s", Utils.prettyTime(runsM5 * (long) (timeM5 * 1.2))));
+ .tooltipToDisplay.add(String.format(
+ "Expected Time (M5) : %s",
+ Utils.prettyTime(runsM5 * (long) (timeM5 * 1.2))
+ ));
hasTime = true;
}
if (timeM6 > 1000) {
getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (M6) : %s", Utils.prettyTime(runsM6 * (long) (timeM6 * 1.2))));
+ .tooltipToDisplay.add(String.format(
+ "Expected Time (M6) : %s",
+ Utils.prettyTime(runsM6 * (long) (timeM6 * 1.2))
+ ));
hasTime = true;
}
if (timeM7 > 1000) {
getInstance()
- .tooltipToDisplay.add(String.format("Expected Time (M7) : %s", Utils.prettyTime(runsM7 * (long) (timeM7 * 1.2))));
+ .tooltipToDisplay.add(String.format(
+ "Expected Time (M7) : %s",
+ Utils.prettyTime(runsM7 * (long) (timeM7 * 1.2))
+ ));
hasTime = true;
}
if (hasTime) {
@@ -421,26 +460,32 @@ public class DungeonPage extends GuiProfileViewerPage {
getInstance()
.tooltipToDisplay.add(
"The " +
- EnumChatFormatting.DARK_PURPLE +
- "Catacombs Expert Ring" +
- EnumChatFormatting.GRAY +
- " is assumed to be used, unless " +
- EnumChatFormatting.YELLOW +
- "SHIFT" +
- EnumChatFormatting.GRAY +
- " is held."
+ EnumChatFormatting.DARK_PURPLE +
+ "Catacombs Expert Ring" +
+ EnumChatFormatting.GRAY +
+ " is assumed to be used, unless " +
+ EnumChatFormatting.YELLOW +
+ "SHIFT" +
+ EnumChatFormatting.GRAY +
+ " is held."
);
getInstance().tooltipToDisplay.add("[Time per run] is calculated using Fastest S+ x 120%");
} else {
getInstance()
- .tooltipToDisplay.add("[Hold " + EnumChatFormatting.YELLOW + "CTRL" + EnumChatFormatting.GRAY + " to see details]");
+ .tooltipToDisplay.add(
+ "[Hold " + EnumChatFormatting.YELLOW + "CTRL" + EnumChatFormatting.GRAY + " to see details]");
}
}
dungeonLevelTextField.setSize(20, 10);
dungeonLevelTextField.render(x + 22, y + 29);
int calcLen = fontRendererObj.getStringWidth("Calculate");
- Utils.renderShadowedString(EnumChatFormatting.WHITE + "Calculate", x + sectionWidth - 17 - calcLen / 2f, y + 30, 100);
+ Utils.renderShadowedString(
+ EnumChatFormatting.WHITE + "Calculate",
+ x + sectionWidth - 17 - calcLen / 2f,
+ y + 30,
+ 100
+ );
//Random stats
@@ -518,7 +563,8 @@ public class DungeonPage extends GuiProfileViewerPage {
);
Utils.renderAlignedString(
EnumChatFormatting.YELLOW + "Secrets (/Run) ",
- EnumChatFormatting.WHITE.toString() + (secrets == -1 ? "?" : (Math.round(secrets / Math.max(1, totalRuns) * 100) / 100f)),
+ EnumChatFormatting.WHITE.toString() + (secrets == -1 ? "?" : (Math.round(
+ secrets / Math.max(1, totalRuns) * 100) / 100f)),
x,
miscTopY + 30,
sectionWidth
@@ -545,18 +591,6 @@ public class DungeonPage extends GuiProfileViewerPage {
float vMax = 11 / 256f;
GlStateManager.color(1, 1, 1, 1);
- Minecraft.getMinecraft().getTextureManager().bindTexture(GuiProfileViewer.pv_elements);
- Utils.drawTexturedRect(
- bx - 2,
- y3 - 2,
- 9,
- 11,
- invert ? uMax : uMin,
- invert ? uMin : uMax,
- invert ? vMax : vMin,
- invert ? vMin : vMax,
- GL11.GL_NEAREST
- );
Utils.renderShadowedString(EnumChatFormatting.WHITE.toString() + i, bx + w / 2, y3, 10);
}
@@ -614,7 +648,8 @@ public class DungeonPage extends GuiProfileViewerPage {
if (BOSS_HEADS[i - 1] == null) {
String textureLink = bossFloorHeads[i - 1];
- String b64Decoded = "{\"textures\":{\"SKIN\":{\"url\":\"http://textures.minecraft.net/texture/" + textureLink + "\"}}}";
+ 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);
@@ -646,7 +681,11 @@ public class DungeonPage extends GuiProfileViewerPage {
GlStateManager.popMatrix();
Utils.renderAlignedString(
- String.format(EnumChatFormatting.YELLOW + "%s (" + (onMasterMode ? "M" : "F") + "%d) ", bossFloorArr[i - 1], i),
+ String.format(
+ EnumChatFormatting.YELLOW + "%s (" + (onMasterMode ? "M" : "F") + "%d) ",
+ bossFloorArr[i - 1],
+ i
+ ),
EnumChatFormatting.WHITE.toString() + (int) compl,
x + 16,
y + 18 + 20 * (i - 1),
@@ -662,7 +701,12 @@ public class DungeonPage extends GuiProfileViewerPage {
//Gui.drawRect(x, y, x+120, y+147, 0xffffffff);
- Utils.renderShadowedString(EnumChatFormatting.DARK_PURPLE + "Class Levels", x + sectionWidth / 2, y, sectionWidth);
+ Utils.renderShadowedString(
+ EnumChatFormatting.DARK_PURPLE + "Class Levels",
+ x + sectionWidth / 2,
+ y,
+ sectionWidth
+ );
JsonElement activeClassElement = Utils.getElement(profileInfo, "dungeons.selected_dungeon_class");
String activeClass = null;
@@ -675,7 +719,10 @@ public class DungeonPage extends GuiProfileViewerPage {
for (int i = 0; i < dungSkillsName.length; i++) {
String skillName = dungSkillsName[i];
- HashMap<String, ProfileViewer.Level> levelObjClasses = levelObjClasseses.computeIfAbsent(profileId, k -> new HashMap<>());
+ HashMap<String, ProfileViewer.Level> levelObjClasses = levelObjClasseses.computeIfAbsent(
+ profileId,
+ k -> new HashMap<>()
+ );
if (!levelObjClasses.containsKey(skillName)) {
float cataXp = Utils.getElementAsFloat(
Utils.getElement(profileInfo, "dungeons.player_classes." + skillName.toLowerCase() + ".experience"),
@@ -708,7 +755,16 @@ public class DungeonPage extends GuiProfileViewerPage {
ProfileViewer.Level levelObj = levelObjClasses.get(skillName);
getInstance()
- .renderXpBar(colour + skillName, dungSkillsStack[i], x, y + 20 + 24 * i, sectionWidth, levelObj, mouseX, mouseY);
+ .renderXpBar(
+ colour + skillName,
+ dungSkillsStack[i],
+ x,
+ y + 20 + 24 * i,
+ sectionWidth,
+ levelObj,
+ mouseX,
+ mouseY
+ );
}
getInstance().renderXpBar(
@@ -718,7 +774,8 @@ public class DungeonPage extends GuiProfileViewerPage {
y + 20 + 24 * 5,
sectionWidth,
classAverage,
- mouseX, mouseY);
+ mouseX, mouseY
+ );
}
drawSideButtons();
@@ -737,7 +794,8 @@ public class DungeonPage extends GuiProfileViewerPage {
}
int cW = fontRendererObj.getStringWidth("Calculate");
- if (mouseX >= guiLeft + 23 + 110 - 17 - cW && mouseX <= guiLeft + 23 + 110 - 17 && mouseY >= guiTop + 55 && mouseY <= guiTop + 65) {
+ if (mouseX >= guiLeft + 23 + 110 - 17 - cW && mouseX <= guiLeft + 23 + 110 - 17 && mouseY >= guiTop + 55 &&
+ mouseY <= guiTop + 65) {
calculateFloorLevelXP();
}
@@ -774,66 +832,21 @@ public class DungeonPage extends GuiProfileViewerPage {
GlStateManager.enableDepth();
GlStateManager.translate(0, 0, 5);
if (onMasterMode) {
- drawSideButton(1, dungeonsModeIcons.get("master_catacombs"), true);
+ Utils.drawPvSideButton(1, dungeonsModeIcons.get("master_catacombs"), true, getInstance());
} else {
- drawSideButton(0, dungeonsModeIcons.get("catacombs"), true);
+ Utils.drawPvSideButton(0, dungeonsModeIcons.get("catacombs"), true, getInstance());
}
GlStateManager.translate(0, 0, -3);
GlStateManager.translate(0, 0, -2);
if (!onMasterMode) {
- drawSideButton(1, dungeonsModeIcons.get("master_catacombs"), false);
+ Utils.drawPvSideButton(1, dungeonsModeIcons.get("master_catacombs"), false, getInstance());
} else {
- drawSideButton(0, dungeonsModeIcons.get("catacombs"), false);
+ Utils.drawPvSideButton(0, dungeonsModeIcons.get("catacombs"), false, getInstance());
}
GlStateManager.disableDepth();
}
- private void drawSideButton(int yIndex, ItemStack itemStack, boolean pressed) {
- int guiLeft = GuiProfileViewer.getGuiLeft();
- int guiTop = GuiProfileViewer.getGuiTop();
-
- GlStateManager.disableLighting();
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.enableAlpha();
- GlStateManager.alphaFunc(516, 0.1F);
-
- int x = guiLeft - 28;
- int y = guiTop + yIndex * 28;
-
- float uMin = 193 / 256f;
- float uMax = 223 / 256f;
- float vMin = 200 / 256f;
- float vMax = 228 / 256f;
- if (pressed) {
- uMin = 224 / 256f;
- uMax = 1f;
-
- if (yIndex != 0) {
- vMin = 228 / 256f;
- vMax = 1f;
- }
-
- getInstance().renderBlurredBackground(getInstance().width, getInstance().height, x + 2, y + 2, 30, 28 - 4);
- } else {
- getInstance().renderBlurredBackground(getInstance().width, getInstance().height, x + 2, y + 2, 28 - 2, 28 - 4);
- }
-
- GlStateManager.disableLighting();
- GlStateManager.enableBlend();
- GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GlStateManager.enableAlpha();
- GlStateManager.alphaFunc(516, 0.1F);
-
- Minecraft.getMinecraft().getTextureManager().bindTexture(GuiProfileViewer.pv_elements);
-
- Utils.drawTexturedRect(x, y, pressed ? 32 : 28, 28, uMin, uMax, vMin, vMax, GL11.GL_NEAREST);
-
- GlStateManager.enableDepth();
- Utils.drawItemStack(itemStack, x + 8, y + 7);
- }
-
private void calculateFloorLevelXP() {
JsonObject leveling = Constants.LEVELING;
if (leveling == null) return;
@@ -852,7 +865,7 @@ public class DungeonPage extends GuiProfileViewerPage {
if (level < Math.floor(levelObjCata.level)) {
continue;
}
- remaining += levelingArray.get(level).getAsFloat();
+ remaining += levelingArray.get(level).getAsFloat();
}
if (remaining < 0) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
index 59c78dda..90ffd388 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ExtraPage.java
@@ -94,7 +94,7 @@ public class ExtraPage extends GuiProfileViewerPage {
}
// pls update in the future tyvm !!!
- final static HashMap<String, Integer> slayers = new HashMap<String, Integer>() {
+ public final static HashMap<String, Integer> slayers = new HashMap<String, Integer>() {
{
put("zombie", 5);
put("spider", 4);
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 4bf65cc6..c189cbad 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java
@@ -171,7 +171,10 @@ public class GuiProfileViewer extends GuiScreen {
);
public final GuiElementTextField playerNameTextField;
public final GuiElementTextField inventoryTextField = new GuiElementTextField("", GuiElementTextField.SCALE_TEXT);
- public final GuiElementTextField killDeathSearchTextField = new GuiElementTextField("", GuiElementTextField.SCALE_TEXT);
+ public final GuiElementTextField killDeathSearchTextField = new GuiElementTextField(
+ "",
+ GuiElementTextField.SCALE_TEXT
+ );
private final Map<ProfileViewerPage, GuiProfileViewerPage> pages = new HashMap<>();
public int sizeX;
public int sizeY;
@@ -390,7 +393,7 @@ public class GuiProfileViewer extends GuiScreen {
GL11.GL_NEAREST
);
Utils.drawStringCenteredScaledMaxWidth(
- "Open in Skycrypt",
+ "Open in SkyCrypt",
Minecraft.getMinecraft().fontRendererObj,
guiLeft + 50 + 100 + 6,
guiTop + sizeY + 3 + 10,
@@ -838,8 +841,9 @@ public class GuiProfileViewer extends GuiScreen {
profileId != null
) {
if (mouseY > guiTop + sizeY + 3 && mouseY < guiTop + sizeY + 23) {
- String url = "https://sky.shiiyu.moe/stats/" + profile.getHypixelProfile().get("displayname").getAsString() + "/" +
- profileId;
+ String url =
+ "https://sky.shiiyu.moe/stats/" + profile.getHypixelProfile().get("displayname").getAsString() + "/" +
+ profileId;
Utils.openUrl(url);
Utils.playPressSound();
return;
@@ -960,14 +964,17 @@ public class GuiProfileViewer extends GuiScreen {
String totalXpStr = null;
if (skillName.contains("Catacombs")) {
totalXpStr = EnumChatFormatting.GRAY + "Total XP: " + EnumChatFormatting.DARK_PURPLE +
- numberFormat.format(levelObj.totalXp) + EnumChatFormatting.DARK_GRAY + " (" +
+ numberFormat.format(levelObj.totalXp) + EnumChatFormatting.DARK_GRAY + " (" +
DECIMAL_FORMAT.format(getPercentage(skillName.toLowerCase(), levelObj)) + "% to 50)";
}
- // Adds overflow level to each level object that is maxed, avoids hotm level as there is no overflow xp for it
+ // Adds overflow level to each level object that is maxed, avoids hotm level as there is no overflow xp for it
if (levelObj.maxed) {
levelStr = levelObj.maxLevel != 7 ?
- EnumChatFormatting.GOLD + "MAXED!" + EnumChatFormatting.GRAY + " (Overflow level: " + String.format("%.2f", levelObj.level) + ")" :
- EnumChatFormatting.GOLD + "MAXED!";
+ EnumChatFormatting.GOLD + "MAXED!" + EnumChatFormatting.GRAY + " (Overflow level: " + String.format(
+ "%.2f",
+ levelObj.level
+ ) + ")" :
+ EnumChatFormatting.GOLD + "MAXED!";
} else {
if (skillName.contains("Class Average")) {
levelStr = "Progress: " + EnumChatFormatting.DARK_PURPLE + String.format("%.1f", (level % 1 * 100)) + "%";
@@ -1010,6 +1017,67 @@ public class GuiProfileViewer extends GuiScreen {
return ((BasicPage) pages.get(ProfileViewerPage.BASIC)).entityPlayer;
}
+ public void renderLevelBar(
+ String name,
+ ItemStack stack,
+ int x,
+ int y,
+ int xSize,
+ double level,
+ double xp,
+ double max,
+ int mouseX,
+ int mouseY,
+ boolean percentage,
+ List<String> tooltip
+ ) {
+
+ if (xp < 0) xp = 0;
+ double experienceRequired = (xp / max);
+
+ String second = EnumChatFormatting.WHITE.toString() + (int) level;
+ if (percentage) {
+ second = EnumChatFormatting.WHITE.toString() + (int) (experienceRequired * 100) + "%";
+ }
+ Utils.renderAlignedString(
+ EnumChatFormatting.RED + name,
+ second,
+ x + 14,
+ y - 4,
+ xSize - 20
+ );
+
+ if (xp >= max) {
+ renderGoldBar(x, y + 6, xSize);
+ } else {
+ renderBar(x, y + 6, xSize, (float) experienceRequired);
+ }
+ String levelStr;
+ if (mouseX > x && mouseX < x + 120) {
+ if (mouseY > y - 4 && mouseY < y + 13) {
+ levelStr =
+ EnumChatFormatting.GRAY + "Progress: " + EnumChatFormatting.DARK_PURPLE + (int) (experienceRequired * 100) +
+ "%" +
+ " §8(" + (int) xp + "/" + (int) max + " XP)";
+ if (tooltip != null && !tooltip.isEmpty()) {
+ tooltip.add("");
+ tooltip.add(levelStr);
+ tooltipToDisplay = tooltip;
+ } else {
+ tooltipToDisplay = Utils.createList(levelStr);
+ }
+ }
+ }
+
+ GlStateManager.enableDepth();
+ GL11.glTranslatef((x), (y - 6f), 0);
+ GL11.glScalef(0.7f, 0.7f, 1);
+ Utils.drawItemStackLinear(stack, 0, 0);
+ GL11.glScalef(1 / 0.7f, 1 / 0.7f, 1);
+ GL11.glTranslatef(-(x), -(y - 6f), 0);
+ GlStateManager.disableDepth();
+ }
+
public void renderGoldBar(float x, float y, float xSize) {
if (!OpenGlHelper.areShadersSupported()) {
renderBar(x, y, xSize, 1);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java
index a981183a..164f5d78 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/InventoriesPage.java
@@ -154,7 +154,7 @@ public class InventoriesPage extends GuiProfileViewerPage {
getInstance().tooltipToDisplay = entry.getValue().getTooltip(Minecraft.getMinecraft().thePlayer, false);
if (Objects.equals(entry.getKey(), "talisman_bag")) {
StringBuilder magicalPowerString = new StringBuilder(EnumChatFormatting.DARK_GRAY + "Magical Power: ");
- int magicalPower = PlayerStats.getMagicalPower(inventoryInfo, profileInformation);
+ int magicalPower = profile.getMagicalPower(profileId);
getInstance()
.tooltipToDisplay.add(
magicalPower == -1
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java
index 56ecd3a2..64ea0f6c 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java
@@ -170,12 +170,10 @@ public class PlayerStats {
return skillBonus;
}
- private static Stats getTamingBonus(JsonObject profile) {
+ public static int getPetScore(JsonObject profile) {
JsonObject bonuses = Constants.BONUSES;
- if (bonuses == null) return null;
-
JsonElement petsElement = Utils.getElement(profile, "pets");
- if (petsElement == null) return new Stats();
+ if (petsElement == null) return 0;
JsonArray pets = petsElement.getAsJsonArray();
@@ -190,11 +188,19 @@ public class PlayerStats {
for (String value : highestRarityMap.values()) {
petScore += Utils.getElementAsFloat(Utils.getElement(bonuses, "pet_value." + value.toUpperCase()), 0);
}
+ return petScore;
+ }
+
+ private static Stats getTamingBonus(JsonObject profile) {
+ JsonObject bonuses = Constants.BONUSES;
+ if (bonuses == null) return null;
JsonElement petRewardsElement = Utils.getElement(bonuses, "pet_rewards");
if (petRewardsElement == null) return null;
JsonObject petRewards = petRewardsElement.getAsJsonObject();
+ int petScore = getPetScore(profile);
+
Stats petBonus = new Stats();
for (int i = 0; i <= petScore; i++) {
if (petRewards.has("" + i)) {
@@ -655,97 +661,6 @@ public class PlayerStats {
}
/**
- * Calculates the amount of Magical Power the player has using the list of accessories
- *
- * @param inventoryInfo inventory info object
- * @return the amount of Magical Power or -1
- * @see io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer.Profile#getInventoryInfo(String)
- */
- public static int getMagicalPower(JsonObject inventoryInfo, JsonObject profileInfo) {
- if (inventoryInfo == null || !inventoryInfo.has("talisman_bag") || !inventoryInfo.get("talisman_bag").isJsonArray()) {
- return -1;
- }
-
- Map<String, Integer> accessories = JsonUtils.getJsonArrayAsStream(inventoryInfo.get("talisman_bag").getAsJsonArray())
- .map(o -> {
- try {
- return JsonToNBT.getTagFromJson(o.getAsJsonObject().get("nbttag").getAsString());
- } catch (Exception ignored) {
- return null;
- }
- }).filter(Objects::nonNull).map(tag -> {
- NBTTagList loreTagList = tag.getCompoundTag("display").getTagList("Lore", 8);
- String lastElement = loreTagList.getStringTagAt(loreTagList.tagCount() - 1);
- if (lastElement.contains(EnumChatFormatting.OBFUSCATED.toString())) {
- lastElement = lastElement.substring(lastElement.indexOf(' ')).trim().substring(4);
- }
- JsonArray lastElementJsonArray = new JsonArray();
- lastElementJsonArray.add(new JsonPrimitive(lastElement));
- return new AbstractMap.SimpleEntry<>(
- tag.getCompoundTag("ExtraAttributes").getString("id"),
- Utils.getRarityFromLore(lastElementJsonArray)
- );
- }).sorted(Comparator.comparingInt(e -> -e.getValue())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2)->v1, LinkedHashMap::new));
-
- Set<String> ignoredTalismans = new HashSet<>();
- int powderAmount = 0;
- for (Map.Entry<String, Integer> entry : accessories.entrySet()) {
- if (ignoredTalismans.contains(entry.getKey())) {
- continue;
- }
-
- JsonArray children = Utils.getElementOrDefault(Constants.PARENTS, entry.getKey(), new JsonArray()).getAsJsonArray();
- for (JsonElement child : children) {
- ignoredTalismans.add(child.getAsString());
- }
-
- if (entry.getKey().equals("HEGEMONY_ARTIFACT")) {
- switch (entry.getValue()) {
- case 4:
- powderAmount += 16;
- break;
- case 5:
- powderAmount += 22;
- break;
- }
- }
- if (entry.getKey().equals("ABICASE")) {
- if (profileInfo.has("nether_island_player_data") &&
- profileInfo.get("nether_island_player_data").getAsJsonObject().has("abiphone") && profileInfo.get(
- "nether_island_player_data").getAsJsonObject().get("abiphone").getAsJsonObject().has("active_contacts")) { // BatChest
- int contact =
- profileInfo.get("nether_island_player_data").getAsJsonObject().get("abiphone").getAsJsonObject().get(
- "active_contacts").getAsJsonArray().size();
- powderAmount += Math.floor(contact / 2);
- }
- }
- switch (entry.getValue()) {
- case 0:
- case 6:
- powderAmount += 3;
- break;
- case 1:
- case 7:
- powderAmount += 5;
- break;
- case 2:
- powderAmount += 8;
- break;
- case 3:
- powderAmount += 12;
- break;
- case 4:
- powderAmount += 16;
- break;
- case 5:
- powderAmount += 22;
- break;
- }
- }
- return powderAmount;
- }
-
- /**
* Finds the Magical Power the player selected if applicable
*
* @param profileInfo profile information object
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 63c2435a..d1d2f553 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/ProfileViewer.java
@@ -25,14 +25,18 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import io.github.moulberry.notenoughupdates.NEUManager;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.profileviewer.bestiary.BestiaryData;
import io.github.moulberry.notenoughupdates.profileviewer.weight.senither.SenitherWeight;
import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.JsonUtils;
import io.github.moulberry.notenoughupdates.util.Utils;
+import io.github.moulberry.notenoughupdates.util.hypixelapi.ProfileCollectionInfo;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompressedStreamTools;
+import net.minecraft.nbt.JsonToNBT;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.util.EnumChatFormatting;
@@ -40,19 +44,27 @@ import net.minecraft.util.EnumChatFormatting;
import javax.annotation.Nullable;
import java.io.ByteArrayInputStream;
import java.io.IOException;
+import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
public class ProfileViewer {
@@ -247,7 +259,7 @@ public class ProfileViewer {
"REDSTONE",
"QUARTZ",
"OBSIDIAN",
- "GLOWSTONE",
+ "GLOWSTONE_DUST",
"GRAVEL",
"ICE",
null,
@@ -449,6 +461,10 @@ public class ProfileViewer {
private final NEUManager manager;
private final HashMap<String, JsonObject> uuidToHypixelProfile = new HashMap<>();
private final HashMap<String, Profile> uuidToProfileMap = new HashMap<>();
+ private final HashMap<String, Double> skyBlockExperience = new HashMap<>();
+
+ private final HashMap<String, EnumChatFormatting> skyBlockExperienceColour = new HashMap<>();
+
private final HashMap<String, String> nameToUuid = new HashMap<>();
public ProfileViewer(NEUManager manager) {
@@ -648,6 +664,10 @@ public class ProfileViewer {
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<>();
+ private final HashMap<String, Integer> magicalPower = new HashMap<>();
+
+ private final HashMap<String, CompletableFuture<ProfileCollectionInfo>> collectionInfoHashMap = new HashMap<>();
+
private final HashMap<String, SoopyNetworthData> soopyNetworth = new HashMap<>();
private final AtomicBoolean updatingSkyblockProfilesState = new AtomicBoolean(false);
private final AtomicBoolean updatingGuildInfoState = new AtomicBoolean(false);
@@ -671,6 +691,118 @@ public class ProfileViewer {
this.uuid = uuid;
}
+ /**
+ * Calculates the amount of Magical Power the player has using the list of accessories
+ *
+ * @return the amount of Magical Power or -1
+ * @see io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer.Profile#getInventoryInfo(String)
+ */
+ public int getMagicalPower(String profileId) {
+ JsonObject inventoryInfo = getInventoryInfo(profileId);
+ JsonObject profileInfo = getProfileInformation(profileId);
+ if (magicalPower.containsKey(profileId)) return magicalPower.get(profileId);
+ if (inventoryInfo == null || !inventoryInfo.has("talisman_bag") ||
+ !inventoryInfo.get("talisman_bag").isJsonArray()) {
+ return -1;
+ }
+
+ Map<String, Integer> accessories = JsonUtils.getJsonArrayAsStream(inventoryInfo
+ .get("talisman_bag")
+ .getAsJsonArray())
+ .map(o -> {
+ try {
+ return JsonToNBT.getTagFromJson(o
+ .getAsJsonObject()
+ .get("nbttag")
+ .getAsString());
+ } catch (Exception ignored) {
+ return null;
+ }
+ }).filter(Objects::nonNull).map(tag -> {
+ NBTTagList loreTagList = tag.getCompoundTag("display").getTagList("Lore", 8);
+ String lastElement = loreTagList.getStringTagAt(loreTagList.tagCount() - 1);
+ if (lastElement.contains(EnumChatFormatting.OBFUSCATED.toString())) {
+ lastElement = lastElement.substring(lastElement.indexOf(' ')).trim().substring(4);
+ }
+ JsonArray lastElementJsonArray = new JsonArray();
+ lastElementJsonArray.add(new JsonPrimitive(lastElement));
+ return new AbstractMap.SimpleEntry<>(
+ tag.getCompoundTag("ExtraAttributes").getString("id"),
+ Utils.getRarityFromLore(lastElementJsonArray)
+ );
+ }).sorted(Comparator.comparingInt(e -> -e.getValue())).collect(Collectors.toMap(
+ Map.Entry::getKey,
+ Map.Entry::getValue,
+ (v1, v2) -> v1,
+ LinkedHashMap::new
+ ));
+
+ Set<String> ignoredTalismans = new HashSet<>();
+ int powerAmount = 0;
+ for (Map.Entry<String, Integer> entry : accessories.entrySet()) {
+ if (ignoredTalismans.contains(entry.getKey())) {
+ continue;
+ }
+
+ JsonArray children = Utils
+ .getElementOrDefault(Constants.PARENTS, entry.getKey(), new JsonArray())
+ .getAsJsonArray();
+ for (JsonElement child : children) {
+ ignoredTalismans.add(child.getAsString());
+ }
+
+ if (entry.getKey().equals("HEGEMONY_ARTIFACT")) {
+ switch (entry.getValue()) {
+ case 4:
+ powerAmount += 16;
+ break;
+ case 5:
+ powerAmount += 22;
+ break;
+ }
+ }
+ if (entry.getKey().equals("ABICASE")) {
+ if (profileInfo != null && profileInfo.has("nether_island_player_data") &&
+ profileInfo.get("nether_island_player_data").getAsJsonObject().has("abiphone") && profileInfo
+ .get(
+ "nether_island_player_data")
+ .getAsJsonObject()
+ .get("abiphone")
+ .getAsJsonObject()
+ .has("active_contacts")) { // BatChest
+ int contact =
+ profileInfo.get("nether_island_player_data").getAsJsonObject().get("abiphone").getAsJsonObject().get(
+ "active_contacts").getAsJsonArray().size();
+ powerAmount += Math.floor(contact / 2);
+ }
+ }
+ switch (entry.getValue()) {
+ case 0:
+ case 6:
+ powerAmount += 3;
+ break;
+ case 1:
+ case 7:
+ powerAmount += 5;
+ break;
+ case 2:
+ powerAmount += 8;
+ break;
+ case 3:
+ powerAmount += 12;
+ break;
+ case 4:
+ powerAmount += 16;
+ break;
+ case 5:
+ powerAmount += 22;
+ break;
+ }
+ }
+ magicalPower.put(profileId, powerAmount);
+ return powerAmount;
+ }
+
public JsonObject getPlayerStatus() {
if (playerStatus != null) return playerStatus;
if (updatingPlayerStatusState.get()) return null;
@@ -924,6 +1056,69 @@ public class ProfileViewer {
return null;
}
+ /*
+ public LevelData getLevelData(String profileName) {
+ if (levelData.containsKey(profileName)) {
+ return levelData.get(profileName);
+ }
+ LevelData data = new LevelData(
+ new CoreTaskData().loadInformation(profileName),
+ new DungeonTaskData().loadInformation(profileName),
+ new EssenceTaskData().loadInformation(profileName),
+ new MiscTaskData().loadInformation(profileName),
+ new SkillRelatedTaskData().loadInformation(profileName),
+ new SlayingTaskData().loadInformation(profileName),
+ new StoryTaskData().loadInformation(profileName),
+ Constants.SBLEVELS
+ );
+ levelData.put(profileName, data);
+
+ return data;
+ }
+
+ */
+
+ public EnumChatFormatting getSkyblockLevelColour(String profileName) {
+ if (skyBlockExperienceColour.containsKey(profileName)) {
+ return skyBlockExperienceColour.get(profileName);
+ }
+
+ double skyblockLevel = getSkyblockLevel(profileName);
+
+ EnumChatFormatting previousColor = EnumChatFormatting.WHITE;
+ JsonObject sblevelColours = Constants.SBLEVELS.getAsJsonObject("sblevel_colours");
+ try {
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : sblevelColours.entrySet()) {
+ int key = Integer.parseInt(stringJsonElementEntry.getKey());
+ EnumChatFormatting valueByName = EnumChatFormatting.getValueByName(stringJsonElementEntry
+ .getValue()
+ .getAsString());
+ if (skyblockLevel <= key) {
+
+ skyBlockExperienceColour.put(profileName, previousColor);
+ return previousColor;
+ }
+ previousColor = valueByName;
+ }
+ } catch (RuntimeException ignored) { // catch both numberformat and getValueByName being wrong
+ }
+ return EnumChatFormatting.WHITE;
+ }
+
+ public double getSkyblockLevel(String profileName) {
+ if (skyBlockExperience.containsKey(profileName)) {
+ return skyBlockExperience.get(profileName);
+ }
+ final JsonObject profileInfo = getProfileInformation(profileName);
+ JsonElement element = Utils.getElement(profileInfo, "leveling.experience");
+ double level = 0;
+ if (element != null) {
+ level = (element.getAsLong() / 100F);
+ }
+ skyBlockExperience.put(profileName, level);
+ return level;
+ }
+
public long getNetWorth(String profileName) {
if (profileName == null) profileName = latestProfile;
if (networth.get(profileName) != null) return networth.get(profileName);
@@ -1163,6 +1358,10 @@ public class ProfileViewer {
if (profile.has("game_mode")) {
profileInfo.add("game_mode", profile.get("game_mode"));
}
+ if (profile.has("community_upgrades")) {
+ profileInfo.add("community_upgrades", profile.get("community_upgrades"));
+ }
+ profileInfo.add("members", members);
profileMap.put(profileName, profileInfo);
return profileInfo;
}
@@ -1216,6 +1415,7 @@ public class ProfileViewer {
inventoryCacheMap.clear();
collectionInfoMap.clear();
networth.clear();
+ magicalPower.clear();
}
public int getCap(JsonObject leveling, String skillName) {
@@ -1225,6 +1425,40 @@ public class ProfileViewer {
: 50;
}
+ public int getBestiaryTiers(JsonObject profileInfo) {
+ int beLevel = 0;
+ for (ItemStack items : BestiaryData.getBestiaryLocations().keySet()) {
+ List<String> mobs = BestiaryData.getBestiaryLocations().get(items);
+ if (mobs != null) {
+ for (String mob : mobs) {
+ if (mob != null) {
+ float kills = Utils.getElementAsFloat(Utils.getElement(profileInfo, "bestiary.kills_" + mob), 0);
+ String type;
+ if (BestiaryData.getMobType().get(mob) != null) {
+ type = BestiaryData.getMobType().get(mob);
+ } else {
+ type = "MOB";
+ }
+ JsonObject leveling = Constants.LEVELING;
+ ProfileViewer.Level level = null;
+ if (leveling != null && Utils.getElement(leveling, "bestiary." + type) != null) {
+ JsonArray levelingArray = Utils.getElement(leveling, "bestiary." + type).getAsJsonArray();
+ int levelCap = Utils.getElementAsInt(Utils.getElement(leveling, "bestiary.caps." + type), 0);
+ level = ProfileViewer.getLevel(levelingArray, kills, levelCap, false);
+ }
+
+ float levelNum = 0;
+ if (level != null) {
+ levelNum = level.level;
+ }
+ beLevel += (int) Math.floor(levelNum);
+ }
+ }
+ }
+ }
+ return beLevel;
+ }
+
public Map<String, Level> getSkyblockInfo(String profileName) {
JsonObject profileInfo = getProfileInformation(profileName);
@@ -1560,6 +1794,23 @@ public class ProfileViewer {
return null;
}
+ public ProfileCollectionInfo getCollectionInfoNew(String profileName, String uuid)
+ throws ExecutionException, InterruptedException {
+ if (collectionInfoHashMap.containsKey(profileName)) {
+ return collectionInfoHashMap.get(profileName).getNow(null);
+ }
+ JsonObject profileInfo = getProfileInformation(profileName);
+ CompletableFuture<ProfileCollectionInfo> collectionData = ProfileCollectionInfo.getCollectionData(
+ profileInfo,
+ uuid
+ );
+ if(collectionData.isDone()) {
+ collectionInfoHashMap.put(profileName, collectionData);
+ return collectionData.get();
+ }
+ return null;
+ }
+
public JsonObject getCollectionInfo(String profileName) {
JsonObject profileInfo = getProfileInformation(profileName);
if (profileInfo == null) return null;
@@ -1666,7 +1917,7 @@ public class ProfileViewer {
}
maxAmountRequired = amountRequired;
}
- if (maxTierAcquired >= 0 && maxTierAcquired > collTier) {
+ if (maxTierAcquired >= 0) {
updatedCollectionTiers.addProperty(collName, maxTierAcquired);
}
maxAmount.addProperty(collName, maxAmountRequired);
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java
index 70ea051a..7da6c627 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/bestiary/BestiaryPage.java
@@ -117,7 +117,7 @@ public class BestiaryPage extends GuiProfileViewerPage {
Color color = new Color(128, 128, 128, 255);
Utils.renderAlignedString(
EnumChatFormatting.RED + "Bestiary Level: ",
- EnumChatFormatting.GRAY + "" + (float) getBestiaryTiers(profileInfo) / 10,
+ EnumChatFormatting.GRAY + "" + (float) GuiProfileViewer.getProfile().getBestiaryTiers(profileInfo) / 10,
guiLeft + 220,
guiTop + 50,
110
@@ -265,38 +265,4 @@ public class BestiaryPage extends GuiProfileViewerPage {
yIndex++;
}
}
-
- private int getBestiaryTiers(JsonObject profileInfo) {
- int beLevel = 0;
- for (ItemStack items : BestiaryData.getBestiaryLocations().keySet()) {
- List<String> mobs = BestiaryData.getBestiaryLocations().get(items);
- if (mobs != null) {
- for (String mob : mobs) {
- if (mob != null) {
- float kills = Utils.getElementAsFloat(Utils.getElement(profileInfo, "bestiary.kills_" + mob), 0);
- String type;
- if (BestiaryData.getMobType().get(mob) != null) {
- type = BestiaryData.getMobType().get(mob);
- } else {
- type = "MOB";
- }
- JsonObject leveling = Constants.LEVELING;
- ProfileViewer.Level level = null;
- if (leveling != null && Utils.getElement(leveling, "bestiary." + type) != null) {
- JsonArray levelingArray = Utils.getElement(leveling, "bestiary." + type).getAsJsonArray();
- int levelCap = Utils.getElementAsInt(Utils.getElement(leveling, "bestiary.caps." + type), 0);
- level = ProfileViewer.getLevel(levelingArray, kills, levelCap, false);
- }
-
- float levelNum = 0;
- if (level != null) {
- levelNum = level.level;
- }
- beLevel += (int) Math.floor(levelNum);
- }
- }
- }
- }
- return beLevel;
- }
}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/LevelPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/LevelPage.java
new file mode 100644
index 00000000..ed5a1534
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/LevelPage.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2023 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.level;
+
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.NEUOverlay;
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
+import io.github.moulberry.notenoughupdates.profileviewer.BasicPage;
+import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.CoreTaskLevel;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.DungeonTaskLevel;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.EssenceTaskLevel;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.MiscTaskLevel;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.SkillRelatedTaskLevel;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.SlayingTaskLevel;
+import io.github.moulberry.notenoughupdates.profileviewer.level.task.StoryTaskLevel;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.GlStateManager;
+import net.minecraft.util.EnumChatFormatting;
+import net.minecraft.util.ResourceLocation;
+import org.lwjgl.opengl.GL11;
+
+import java.util.Collections;
+import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class LevelPage {
+
+ private final GuiProfileViewer instance;
+ private final BasicPage basicPage;
+ private ProfileViewer.Profile profile;
+
+ private final int randomNumber;
+
+ private final int randomNumber2;
+
+ private String profileId;
+
+ private int guiLeft, guiTop;
+
+ private JsonObject constant;
+
+ private final CoreTaskLevel coreTaskLevel;
+ private final DungeonTaskLevel dungeonTaskLevel;
+ private final EssenceTaskLevel essenceTaskLevel;
+ private final MiscTaskLevel miscTaskLevel;
+ private final SkillRelatedTaskLevel skillRelatedTaskLevel;
+ private final SlayingTaskLevel slayingTaskLevel;
+ private final StoryTaskLevel storyTaskLevel;
+
+ private static final ResourceLocation pv_levels = new ResourceLocation("notenoughupdates:pv_levels.png");
+
+ public LevelPage(GuiProfileViewer instance, BasicPage basicPage) {
+ this.instance = instance;
+ this.basicPage = basicPage;
+ constant = Constants.SBLEVELS;
+
+ coreTaskLevel = new CoreTaskLevel(this);
+ dungeonTaskLevel = new DungeonTaskLevel(this);
+ essenceTaskLevel = new EssenceTaskLevel(this);
+ miscTaskLevel = new MiscTaskLevel(this);
+ skillRelatedTaskLevel = new SkillRelatedTaskLevel(this);
+ slayingTaskLevel = new SlayingTaskLevel(this);
+ storyTaskLevel = new StoryTaskLevel(this);
+
+
+ ThreadLocalRandom current = ThreadLocalRandom.current();
+ randomNumber = current.nextInt(0, 69 + 69 + 69 + 69 + 69 + 69 + 7);
+ randomNumber2 = current.nextInt(0, 1);
+ }
+
+ public void drawPage(int mouseX, int mouseY, float partialTicks) {
+ this.guiLeft = GuiProfileViewer.getGuiLeft();
+ this.guiTop = GuiProfileViewer.getGuiTop();
+ this.profile = GuiProfileViewer.getProfile();
+ this.profileId = GuiProfileViewer.getProfileId();
+
+ basicPage.drawSideButtons();
+
+ if (constant == null) {
+ Utils.showOutdatedRepoNotification();
+ return;
+ }
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(pv_levels);
+ Utils.drawTexturedRect(guiLeft, guiTop, instance.sizeX, instance.sizeY, GL11.GL_NEAREST);
+
+ double skyblockLevel = profile.getSkyblockLevel(profileId);
+ JsonObject profileInfo = profile.getProfileInformation(profileId);
+
+ if (randomNumber == (69 + 69 + 69 + 69 + 69 + 69 + 6)) {
+ iVMMXVII(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ }
+ drawMainBar(skyblockLevel, mouseX, mouseY, guiLeft, guiTop);
+ coreTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ dungeonTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ essenceTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ miscTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ skillRelatedTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ slayingTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ storyTaskLevel.drawTask(profileInfo, mouseX, mouseY, guiLeft, guiTop);
+ }
+
+ private void iVMMXVII(
+ JsonObject llllllllll,
+ int IIIIIIIIilIIIIIII,
+ int lllllIIIIlllII,
+ int llIIlll,
+ int iiIIIIlllLIIII
+ ) {
+ if (randomNumber2 == 1) {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(NEUOverlay.SUPERGEHEIMNISVERMOGEN);
+ } else {
+ Minecraft.getMinecraft().getTextureManager().bindTexture(NEUOverlay.ATMOULBERRYWHYISMYLUNARCLIENTBUGGING);
+ }
+
+ GlStateManager.color(1, 1, 1, 1);
+
+ Utils.drawTexturedRect(llIIlll + 187, iiIIIIlllLIIII + (int) (69 + 42.0 + 2), 69 - 5, 69 - 5, GL11.GL_LINEAR);
+ GlStateManager.bindTexture(0);
+ }
+
+ private void drawMainBar(double skyblockLevel, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ instance.renderLevelBar(
+ "Level",
+ BasicPage.skull,
+ guiLeft + 163,
+ guiTop + 30,
+ 110,
+ skyblockLevel,
+ (skyblockLevel - (long) skyblockLevel) * 100,
+ 100,
+ mouseX,
+ mouseY,
+ false,
+ Collections.emptyList()
+ );
+ }
+
+ public String buildLore(String name, double xpGotten, double xpGainful, boolean hasNoLimit) {
+ if (xpGainful == 0 && xpGotten == 0 && !hasNoLimit) {
+ return EnumChatFormatting.GOLD + name + ": §c§lNOT DETECTABLE!";
+ }
+ if (hasNoLimit) {
+ return EnumChatFormatting.GOLD + name + ": " + EnumChatFormatting.YELLOW + (int) xpGotten + " XP";
+ }
+ int percentage = (int) ((xpGotten / xpGainful) * 100);
+ if (xpGotten >= xpGainful) {
+ return EnumChatFormatting.GOLD + name + ": " + EnumChatFormatting.GREEN
+ + percentage + "%" + " §8(" + (int) xpGotten + "/" + (int) xpGainful + " XP)";
+ } else if (xpGotten == -1) {
+ return EnumChatFormatting.GOLD + name + ": §c§lCOLLECTION DISABLED!";
+ } else {
+
+ return EnumChatFormatting.GOLD + name + ": " + EnumChatFormatting.YELLOW
+ + percentage + "%" + " §8(" + (int) xpGotten + "/" + (int) xpGainful + " XP)";
+ }
+ }
+
+ public JsonObject getConstant() {
+ return constant;
+ }
+
+ public ProfileViewer.Profile getProfile() {
+ return profile;
+ }
+
+ public String getProfileId() {
+ return profileId;
+ }
+
+ public GuiProfileViewer getInstance() {
+ return instance;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/CoreTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/CoreTaskLevel.java
new file mode 100644
index 00000000..559966f7
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/CoreTaskLevel.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2023 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.level.task;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.PlayerStats;
+import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.hypixelapi.ProfileCollectionInfo;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+public class CoreTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public CoreTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ private final List<String> skills = Arrays.asList(
+ "taming",
+ "mining",
+ "foraging",
+ "enchanting",
+ "carpentry",
+ "farming",
+ "combat",
+ "fishing",
+ "alchemy"
+ );
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ JsonObject coreTask = levelPage.getConstant().get("core_task").getAsJsonObject();
+ // skills
+ Map<String, ProfileViewer.Level> skyblockInfo = levelPage.getProfile().getSkyblockInfo(levelPage.getProfileId());
+
+ int sbXpGainedSkillLVL = 0;
+ if (skyblockInfo != null) {
+ for (String skill : skills) {
+ ProfileViewer.Level level = skyblockInfo.get(skill);
+ for (int i = 1; i <= level.level; i++) {
+ if (i <= 10) {
+ sbXpGainedSkillLVL += 5;
+ }
+ if (i <= 25 && i > 10) {
+ sbXpGainedSkillLVL += 10;
+ }
+ if (i <= 50 && i > 25) {
+ sbXpGainedSkillLVL += 20;
+ }
+ if (i <= 60 && i > 50) {
+ sbXpGainedSkillLVL += 30;
+ }
+ }
+ }
+ } else {
+ sbXpGainedSkillLVL = -1;
+ }
+
+ // mp acc
+ int sbXpGainedMp = levelPage.getProfile().getMagicalPower(levelPage.getProfileId());
+
+ // pets
+
+ int petScore = PlayerStats.getPetScore(object);
+ int sbXpPetScore = petScore * coreTask.get("pet_score_xp").getAsInt();
+
+ // museum is not possible
+
+ // fairy soul
+ int fairySoulsCollected = object.get("fairy_souls_collected").getAsInt();
+ int sbXpGainedFairy = ((fairySoulsCollected / 5)) * coreTask.get("fairy_souls_xp").getAsInt();
+
+ int sbXpCollection = -1;
+ int sbXpMinionTier = -1; // keeping at -1 here because cobblestone 1 minion XP isn't included for some reason?
+ JsonObject minionXp = Constants.MISC.get("minionXp").getAsJsonObject();
+ int collectionsXp = coreTask.get("collections_xp").getAsInt();
+ try {
+ ProfileCollectionInfo collection;
+ collection = levelPage.getProfile().getCollectionInfoNew(
+ levelPage.getProfileId(),
+ levelPage.getProfile().getUuid()
+ );
+ if (collection != null) {
+ for (Map.Entry<String, ProfileCollectionInfo.CollectionInfo> stringCollectionInfoEntry : collection
+ .getCollections()
+ .entrySet()) {
+ ProfileCollectionInfo.CollectionInfo value = stringCollectionInfoEntry.getValue();
+ sbXpCollection = value.getUnlockedTiers().size() * collectionsXp;
+ }
+ for (Map.Entry<String, Integer> stringIntegerEntry : collection.getCraftedGenerators().entrySet()) {
+ String key = stringIntegerEntry.getKey();
+ int value = stringIntegerEntry.getValue();
+ for (int i = 1; i <= value; i++) {
+ if (minionXp.has(i + "")) sbXpMinionTier += minionXp.get(i + "").getAsInt();
+ }
+ }
+ }
+ } catch (ExecutionException | InterruptedException e) {
+ }
+ List<String> lore = new ArrayList<>();
+
+ lore.add(levelPage.buildLore("Skill Level Up",
+ sbXpGainedSkillLVL, coreTask.get("skill_level_up").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Museum Progression",
+ 0, 0, false
+ ));
+ lore.add(levelPage.buildLore("Fairy Soul",
+ sbXpGainedFairy, coreTask.get("fairy_souls").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Accessory Bag",
+ sbXpGainedMp, 0, true
+ ));
+ lore.add(levelPage.buildLore("Pet Score",
+ sbXpPetScore, 0, true
+ ));
+ lore.add(levelPage.buildLore("Collections",
+ sbXpCollection, coreTask.get("collections").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Craft Minions",
+ sbXpMinionTier, coreTask.get("craft_minions").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Bank Upgrade",
+ 0, 0, false
+ ));
+
+ levelPage.getInstance().renderLevelBar(
+ "Core Task",
+ new ItemStack(Items.nether_star),
+ guiLeft + 23,
+ guiTop + 25,
+ 110,
+ 0,
+ sbXpGainedSkillLVL + sbXpGainedFairy +
+ sbXpCollection + sbXpMinionTier,
+ levelPage.getConstant().getAsJsonObject("category_xp").get("core_task").getAsInt(),
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/DungeonTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/DungeonTaskLevel.java
new file mode 100644
index 00000000..e32d660a
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/DungeonTaskLevel.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2023 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.level.task;
+
+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.profileviewer.ProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import io.github.moulberry.notenoughupdates.util.Utils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class DungeonTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public DungeonTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ JsonObject dungeonTask = levelPage.getConstant().get("dungeon_task").getAsJsonObject();
+
+ Map<String, ProfileViewer.Level> skyblockInfo =
+ levelPage.getProfile().getSkyblockInfo(levelPage.getProfileId());
+
+ double sbLevelGainedFloor = 0;
+ double sbXpGainedClass = 0;
+ double sbXpGainedLvl = 0;
+ int catacombsLvl = 0;
+ if (skyblockInfo != null && skyblockInfo.containsKey("catacombs")) {
+ ProfileViewer.Level catacombs = skyblockInfo.get("catacombs");
+
+ catacombsLvl = (int) catacombs.level;
+ for (int i = 1; i <= catacombs.level; i++) {
+ if (40 > i) {
+ sbXpGainedLvl += 20;
+ } else {
+ sbXpGainedLvl += 40;
+ }
+ }
+
+ List<String> dungeonClasses = Arrays.asList("healer", "tank", "mage", "archer", "berserk");
+ for (String dungeonClass : dungeonClasses) {
+ ProfileViewer.Level level = skyblockInfo.get(dungeonClass);
+ for (int i = 1; i <= level.level; i++) {
+ if(i <= 50) sbXpGainedClass += dungeonTask.get("class_xp").getAsInt();
+ }
+ }
+
+ JsonArray completeCatacombs = dungeonTask.get("complete_catacombs").getAsJsonArray();
+ int index = 0;
+ for (JsonElement completeCatacomb : completeCatacombs) {
+ int value = completeCatacomb.getAsInt();
+ JsonObject normalCompletions = Utils
+ .getElement(object, "dungeons.dungeon_types.catacombs.tier_completions")
+ .getAsJsonObject();
+ if (normalCompletions.has(index + "")) {
+ sbLevelGainedFloor = sbLevelGainedFloor + value;
+ }
+ index++;
+ }
+
+ int masterCatacombs = dungeonTask.get("complete_master_catacombs").getAsInt();
+ for (int i = 0; i <= 7; i++) {
+ JsonElement masterCompletions = Utils
+ .getElementOrDefault(object, "dungeons.dungeon_types.master_catacombs.tier_completions", null);
+ if (masterCompletions != null) {
+ if (masterCompletions.getAsJsonObject().has(i + "")) {
+ sbLevelGainedFloor = sbLevelGainedFloor + masterCatacombs;
+ }
+ }
+ }
+ }
+
+ int catacombsLevelUp = dungeonTask.get("catacombs_level_up").getAsInt();
+ int classLevelUp = dungeonTask.get("class_level_up").getAsInt();
+ int completeDungeon = dungeonTask.get("complete_dungeon").getAsInt();
+ int totalGainful = catacombsLevelUp + classLevelUp + completeDungeon;
+ double totalXp = sbXpGainedLvl + sbXpGainedClass + sbLevelGainedFloor;
+
+ List<String> lore = new ArrayList<>();
+
+ lore.add(levelPage.buildLore("Catacombs Level Up", sbXpGainedLvl, catacombsLevelUp, false));
+ lore.add(levelPage.buildLore("Class Level Up", sbXpGainedClass, classLevelUp, false));
+ lore.add(levelPage.buildLore("Complete Dungeons", sbLevelGainedFloor, completeDungeon, false));
+
+ levelPage.getInstance().renderLevelBar(
+ "Dungeon",
+ NotEnoughUpdates.INSTANCE.manager
+ .createItemResolutionQuery()
+ .withKnownInternalName("WITHER_RELIC")
+ .resolveToItemStack(),
+ guiLeft + 23,
+ guiTop + 55,
+ 110,
+ catacombsLvl,
+ totalXp,
+ totalGainful,
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EssenceTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EssenceTaskLevel.java
new file mode 100644
index 00000000..4d7ed85c
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/EssenceTaskLevel.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2023 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.level.task;
+
+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.profileviewer.level.LevelPage;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import net.minecraft.util.EnumChatFormatting;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class EssenceTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public EssenceTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ List<String> lore = new ArrayList<>();
+
+ JsonObject categoryXp = levelPage.getConstant().get("category_xp").getAsJsonObject();
+ JsonObject essenceShopTask = levelPage.getConstant().get("essence_shop_task").getAsJsonObject();
+ JsonArray essenceSteps = essenceShopTask.get("essence_shop_xp").getAsJsonArray();
+ JsonObject essencePerks = object.get("perks").getAsJsonObject();
+
+ Map<String, EssenceShop> loreMap = new HashMap<>();
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : Constants.ESSENCESHOPS.entrySet()) {
+ String name = stringJsonElementEntry.getKey();
+ JsonObject individualObjects = stringJsonElementEntry.getValue().getAsJsonObject();
+ for (Map.Entry<String, JsonElement> jsonElementEntry : individualObjects.entrySet()) {
+ String key = jsonElementEntry.getKey();
+ if (!essencePerks.has(key)) {
+ continue;
+ }
+
+ int essenceAmount = essencePerks.get(key).getAsInt();
+
+ int amountReceivedForEach = 0;
+ for (int i = essenceAmount - 1; i >= 0; i--) {
+ amountReceivedForEach += essenceSteps.get(i).getAsInt();
+ }
+ if (!loreMap.containsKey(name)) {
+ EssenceShop value = new EssenceShop();
+ value.current += amountReceivedForEach;
+ value.name = name;
+ loreMap.put(name, value);
+ } else {
+ EssenceShop essenceShop = loreMap.get(name);
+ essenceShop.current += amountReceivedForEach;
+ }
+ }
+ }
+
+ // bad workaround (pls fix later maybe)
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : essenceShopTask.entrySet()) {
+ String key = stringJsonElementEntry.getKey();
+ if (!key.endsWith("_shop")) continue;
+ String name = key.split("_shop")[0].toUpperCase();
+ if (!loreMap.containsKey(name)) {
+ loreMap.put(name, new EssenceShop().setName(name).setCurrent(0));
+ }
+ }
+
+ int total = 0;
+ for (Map.Entry<String, EssenceShop> stringEssenceShopEntry : loreMap.entrySet()) {
+ String key = stringEssenceShopEntry.getKey();
+ EssenceShop value = stringEssenceShopEntry.getValue();
+ value.name = NotEnoughUpdates.INSTANCE.manager
+ .createItemResolutionQuery()
+ .withKnownInternalName(key)
+ .resolveToItemListJson()
+ .get("displayname")
+ .getAsString();
+ value.max = essenceShopTask.get(key.toLowerCase() + "_shop").getAsInt();
+ lore.add(levelPage.buildLore(
+ EnumChatFormatting.getTextWithoutFormattingCodes(value.name),
+ value.current,
+ value.max,
+ false
+ ));
+ total += value.current;
+ }
+
+ levelPage.getInstance().renderLevelBar(
+ "Essence",
+ NotEnoughUpdates.INSTANCE.manager.createItemResolutionQuery()
+ .withKnownInternalName("ESSENCE_WITHER")
+ .resolveToItemStack(),
+ guiLeft + 299,
+ guiTop + 25,
+ 110,
+ total,
+ total,
+ categoryXp.get("essence_shop_task").getAsInt(),
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+ }
+
+ class EssenceShop {
+ String name;
+ double percentage;
+ double max;
+ double current;
+
+ public EssenceShop setCurrent(double current) {
+ this.current = current;
+ return this;
+ }
+
+ public EssenceShop setPercentage(double percentage) {
+ this.percentage = percentage;
+ return this;
+ }
+
+ public EssenceShop setMax(double max) {
+ this.max = max;
+ return this;
+ }
+
+ public EssenceShop setName(String name) {
+ this.name = name;
+ return this;
+ }
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/MiscTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/MiscTaskLevel.java
new file mode 100644
index 00000000..ec588116
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/MiscTaskLevel.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2023 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.level.task;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.profileviewer.CrimsonIslePage;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumChatFormatting;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class MiscTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public MiscTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ JsonObject miscellaneousTask = levelPage.getConstant().getAsJsonObject("miscellaneous_task");
+ // I love doing this on god!!!
+
+ int sbXpAccessoryUpgrade = 0;
+ int sbXpReaperPeppers = 0;
+ int sbXpUnlockedPowers = 0;
+ int sbXpAbiphone = 0;
+ if (object.has("accessory_bag_storage")) {
+ JsonObject accessoryBagStorage = object.getAsJsonObject("accessory_bag_storage");
+
+ sbXpAccessoryUpgrade = Utils.getElementAsInt(Utils.getElement(
+ accessoryBagStorage,
+ "bag_upgrades_purchased"
+ ), 0) * miscellaneousTask.get("accessory_bag_upgrades_xp").getAsInt();
+ sbXpReaperPeppers =
+ miscellaneousTask.get("reaper_peppers_xp").getAsInt() * Utils.getElementAsInt(Utils.getElement(
+ object,
+ "reaper_peppers_eaten"
+ ), 0);
+ if (accessoryBagStorage.has("unlocked_powers")) sbXpUnlockedPowers = accessoryBagStorage.getAsJsonArray(
+ "unlocked_powers").size() * miscellaneousTask.get("unlocking_powers_xp").getAsInt();
+ }
+
+ int sbXpDojo = 0;
+ if (object.has("nether_island_player_data")) {
+ JsonObject netherIslandPlayerData = object.getAsJsonObject("nether_island_player_data");
+ if (netherIslandPlayerData.has("dojo")) {
+ JsonObject dojoScoresObj = netherIslandPlayerData.getAsJsonObject("dojo");
+
+ int pointsTotal = 0;
+ for (int i = 0; i < CrimsonIslePage.apiDojoTestNames.size(); i++) {
+ for (Map.Entry<String, JsonElement> dojoData : dojoScoresObj.entrySet()) {
+ if (dojoData.getKey().equals("dojo_points_" + CrimsonIslePage.apiDojoTestNames.keySet().toArray()[i])) {
+ pointsTotal += dojoData.getValue().getAsInt();
+ }
+ }
+ }
+ int index = getRankIndex(pointsTotal);
+ JsonArray theDojoXp = miscellaneousTask.getAsJsonArray("the_dojo_xp");
+ for (int i = 0; i < index; i++) {
+ sbXpDojo += theDojoXp.get(i).getAsInt();
+ }
+ }
+
+ // abiphone
+ if (netherIslandPlayerData.has("abiphone")) {
+ JsonObject abiphone = netherIslandPlayerData.getAsJsonObject("abiphone");
+ if (abiphone.has("active_contacts")) sbXpAbiphone =
+ abiphone.getAsJsonArray("active_contacts").size() * miscellaneousTask.get("abiphone_contacts_xp").getAsInt();
+ }
+ }
+
+ // harp
+ int sbXpGainedHarp = 0;
+ JsonObject harpSongsNames = miscellaneousTask.get("harp_songs_names").getAsJsonObject();
+ if (object.has("harp_quest")) {
+ JsonObject harpQuest = object.get("harp_quest").getAsJsonObject();
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : harpSongsNames.entrySet()) {
+ String key = stringJsonElementEntry.getKey();
+ int value = stringJsonElementEntry.getValue().getAsInt();
+ if (harpQuest.has(key)) {
+ sbXpGainedHarp += value;
+ }
+ }
+ }
+
+ // community upgrades
+ int sbXpCommunityUpgrade = 0;
+ JsonObject profileInformation = levelPage.getProfile().getProfileInformation(levelPage.getProfileId());
+ if (profileInformation.has("community_upgrades")) {
+ JsonObject communityUpgrades = profileInformation.getAsJsonObject("community_upgrades");
+ JsonArray upgradeStates = communityUpgrades.getAsJsonArray("upgrade_states");
+ JsonObject communityShopUpgradesMax = miscellaneousTask.getAsJsonObject("community_shop_upgrades_max");
+
+ int communityShopUpgradesXp = miscellaneousTask.get("community_shop_upgrades_xp").getAsInt();
+
+ for (
+ JsonElement upgradeState : upgradeStates) {
+ if (!upgradeState.isJsonObject()) continue;
+ JsonObject value = upgradeState.getAsJsonObject();
+ String upgrade = value.get("upgrade").getAsString();
+ int tier = value.get("tier").getAsInt();
+ if (communityShopUpgradesMax.has(upgrade)) {
+ int max = communityShopUpgradesMax.get(upgrade).getAsInt();
+ if (max >= tier) {
+ sbXpCommunityUpgrade += communityShopUpgradesXp;
+ }
+ }
+ }
+ }
+
+ // personal bank
+ int sbXpPersonalBank = 0;
+ if (object.has("personal_bank_upgrade")) {
+ int personalBankUpgrade = object.get("personal_bank_upgrade").getAsInt();
+ JsonArray personalBankUpgradesXpArr = miscellaneousTask.getAsJsonArray("personal_bank_upgrades_xp");
+ for (int i = 1; i <= personalBankUpgrade; i++) {
+ sbXpPersonalBank += personalBankUpgradesXpArr.get(i - 1).getAsInt();
+ }
+ }
+
+ List<String> lore = new ArrayList<>();
+
+ lore.add(levelPage.buildLore("Accessory Bag Upgrades",
+ sbXpAccessoryUpgrade, 0, true
+ ));
+ lore.add(levelPage.buildLore("Reaper Peppers",
+ sbXpReaperPeppers, miscellaneousTask.get("reaper_peppers").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Unlocking Powers",
+ sbXpUnlockedPowers, 0, true
+ ));
+ lore.add(levelPage.buildLore("The Dojo",
+ sbXpDojo, miscellaneousTask.get("the_dojo").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore(
+ EnumChatFormatting.ITALIC + "Harp Songs",
+ sbXpGainedHarp, miscellaneousTask.get("harp_songs").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore(EnumChatFormatting.ITALIC + "Abiphone Contacts",
+ sbXpAbiphone, miscellaneousTask.get("abiphone_contacts").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Community Shop Upgrades",
+ sbXpCommunityUpgrade, miscellaneousTask.get("community_shop_upgrades").getAsInt(), false
+ ));
+ lore.add(levelPage.buildLore("Personal Bank Upgrades",
+ sbXpPersonalBank, miscellaneousTask.get("personal_bank_upgrades").getAsInt(), false
+ ));
+
+ levelPage.getInstance().renderLevelBar(
+ "Misc. Task",
+ new ItemStack(Items.map),
+ guiLeft + 299,
+ guiTop + 55,
+ 110,
+ 0,
+ sbXpReaperPeppers + sbXpDojo + sbXpGainedHarp + sbXpAbiphone +
+ sbXpCommunityUpgrade + sbXpPersonalBank,
+ levelPage.getConstant().getAsJsonObject("category_xp").get("miscellaneous_task").getAsInt(),
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+
+ }
+
+ private int getRankIndex(int pointsTotal) {
+ AtomicInteger index = new AtomicInteger();
+ CrimsonIslePage.dojoPointsToRank.forEach((required, name) -> {
+ if (pointsTotal > required) {
+ index.getAndIncrement();
+ }
+ });
+ return index.get();
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SkillRelatedTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SkillRelatedTaskLevel.java
new file mode 100644
index 00000000..8c0d7a55
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SkillRelatedTaskLevel.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2023 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.level.task;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import io.github.moulberry.notenoughupdates.util.Constants;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class SkillRelatedTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public SkillRelatedTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ JsonObject skillRelatedTask = levelPage.getConstant().get("skill_related_task").getAsJsonObject();
+ JsonObject miningObj = skillRelatedTask.get("mining").getAsJsonObject();
+
+ float mithril = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_spent_mithril"), 0);
+ float gemstone = (Utils.getElementAsFloat(Utils.getElement(object, "mining_core.powder_spent_gemstone"), 0));
+
+ float hotmXp = Utils.getElementAsFloat(Utils.getElement(object, "mining_core.experience"), 0);
+ ProfileViewer.Level levelObjhotm =
+ ProfileViewer.getLevel(
+ Utils.getElementOrDefault(Constants.LEVELING, "HOTM", new JsonArray()).getAsJsonArray(),
+ hotmXp,
+ 7,
+ false
+ );
+
+ int hotmXP = 0;
+ float level = levelObjhotm.level;
+ JsonArray hotmXpArray = miningObj.get("hotm_xp").getAsJsonArray();
+ for (int i = 1; i <= level; i++) {
+ hotmXP += hotmXpArray.get(i - 1).getAsInt();
+ }
+
+ double gainByFirstMithrilThing;
+ if (mithril >= 350_000) {
+ gainByFirstMithrilThing = (350000 / 2400d);
+ mithril -= 350_000;
+ } else {
+ gainByFirstMithrilThing = (mithril / 2400d);
+ mithril = 0;
+ }
+
+ double gainByFirstGemstoneThing;
+ if (gemstone >= 350_000) {
+ gainByFirstGemstoneThing = (350_000 / 2500d);
+ gemstone -= 350_000;
+ } else {
+ gainByFirstGemstoneThing = (gemstone / 2500d);
+ gemstone = 0;
+ }
+
+
+ double mithrilXP = 3.75 * (Math.sqrt(
+ 1 + 8 * (Math.sqrt((1758267 / 12_500_000D) * mithril + 9))) - 3);
+ double gemstoneXP = 4.25 * (Math.sqrt(
+ 1 + 8 * (Math.sqrt((1758267 / 20_000_000D) * gemstone + 9))) - 3);
+
+ double sbXpHotmTier = (mithrilXP + gainByFirstMithrilThing) + (gemstoneXP + gainByFirstGemstoneThing)
+ + hotmXP;
+
+
+
+ int sbXpPotmTier = 0;
+ JsonArray potmXpArray = miningObj.get("potm_xp").getAsJsonArray();
+
+ int potm = ((Utils.getElementAsInt(Utils.getElement(object, "mining_core.nodes.special_0"), 0)));
+ for (int i = 1; i <= potm; i++) {
+ sbXpPotmTier += potmXpArray.get(i - 1).getAsInt();
+ }
+
+ int sbXpCommissionMilestone = 0;
+ JsonArray tutorialArray = object.get("tutorial").getAsJsonArray();
+ JsonArray commissionMilestoneXpArray = miningObj.get("commission_milestone_xp").getAsJsonArray();
+ for (JsonElement jsonElement : tutorialArray) {
+ if (jsonElement.getAsJsonPrimitive().isString() && jsonElement.getAsString().startsWith(
+ "commission_milestone_reward_skyblock_xp_tier"))
+ for (int i = 1; i <= commissionMilestoneXpArray.size(); i++) {
+ int value = commissionMilestoneXpArray.get(i - 1).getAsInt();
+ if (jsonElement.getAsString().equals("commission_milestone_reward_skyblock_xp_tier_" + i)) {
+ sbXpCommissionMilestone += value;
+ }
+ }
+ }
+
+ // rock mines
+ float pet_milestone_ores_mined = Utils.getElementAsFloat(Utils.getElement(
+ object,
+ "stats.pet_milestone_ores_mined"
+ ), 0);
+
+ int sbXpRockPet = 0;
+ int rockMilestoneXp = miningObj.get("rock_milestone_xp").getAsInt();
+ JsonArray rockMilestoneRequired = miningObj.get("rock_milestone_required").getAsJsonArray();
+ for (JsonElement jsonElement : rockMilestoneRequired) {
+ int value = jsonElement.getAsInt();
+ if (pet_milestone_ores_mined >= value) {
+ sbXpRockPet += rockMilestoneXp;
+ }
+ }
+
+ // farming
+ JsonObject farmingObj = skillRelatedTask.get("farming").getAsJsonObject();
+ int anitaShopUpgradesXp = farmingObj.get("anita_shop_upgrades_xp").getAsInt();
+ int doubleDrops = Utils.getElementAsInt(Utils.getElement(object, "jacob2.perks.double_drops"), 0);
+ int farmingLevelCap = Utils.getElementAsInt(Utils.getElement(object, "jacob2.perks.farming_level_cap"), 0);
+
+ int sbXpGainedByAnita = (doubleDrops + farmingLevelCap) * anitaShopUpgradesXp;
+
+ // fishing
+ int sbXpTrophyFish = 0;
+ JsonObject fishingObj = skillRelatedTask.get("fishing").getAsJsonObject();
+
+ JsonArray trophyFishXpArr = fishingObj.get("trophy_fish_xp").getAsJsonArray();
+ if (object.has("trophy_fish")) {
+
+ JsonObject trophyFish = object.get("trophy_fish").getAsJsonObject();
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : trophyFish.entrySet()) {
+ String key = stringJsonElementEntry.getKey();
+ if (stringJsonElementEntry.getValue().isJsonPrimitive()) {
+ if (key.endsWith("_bronze")) sbXpTrophyFish += trophyFishXpArr.get(0).getAsInt();
+ if (key.endsWith("_silver")) sbXpTrophyFish += trophyFishXpArr.get(1).getAsInt();
+ if (key.endsWith("_gold")) sbXpTrophyFish += trophyFishXpArr.get(2).getAsInt();
+ if (key.endsWith("_diamond")) sbXpTrophyFish += trophyFishXpArr.get(3).getAsInt();
+ }
+ }
+
+ }
+ float pet_milestone_sea_creatures_killed = Utils.getElementAsFloat(
+ Utils.getElement(object, "stats.pet_milestone_sea_creatures_killed"),
+ 0
+ );
+
+ int sbXpDolphinPet = 0;
+ int dolphinMilestoneXp = fishingObj.get("dolphin_milestone_xp").getAsInt();
+ JsonArray dolphinMilestoneRequired = fishingObj.get("dolphin_milestone_required").getAsJsonArray();
+ for (JsonElement jsonElement : dolphinMilestoneRequired) {
+ int value = jsonElement.getAsInt();
+ if (pet_milestone_sea_creatures_killed >= value) {
+ sbXpDolphinPet += dolphinMilestoneXp;
+ }
+ }
+
+ List<String> lore = new ArrayList<>();
+ lore.add(levelPage.buildLore("Heart of the Mountain", sbXpHotmTier, miningObj.get("hotm").getAsInt(), false));
+ lore.add(levelPage.buildLore(
+ "Commission Milestones",
+ sbXpCommissionMilestone,
+ miningObj.get("commission_milestone").getAsInt(),
+ false
+ ));
+ lore.add(levelPage.buildLore("Crystal Nucleus", 0, 0, false));
+ lore.add(levelPage.buildLore(
+ "Anita's Shop Upgrade",
+ sbXpGainedByAnita,
+ farmingObj.get("anita_shop_upgrades").getAsInt(),
+ false
+ ));
+ lore.add(levelPage.buildLore("Peak of the Mountain", sbXpPotmTier, miningObj.get("potm").getAsInt(), false));
+ lore.add(levelPage.buildLore("Trophy Fish", sbXpTrophyFish, fishingObj.get("trophy_fish").getAsInt(), false));
+ lore.add(levelPage.buildLore("Rock Milestone", sbXpRockPet, miningObj.get("rock_milestone").getAsInt(), false));
+ lore.add(levelPage.buildLore("Dolphin Milestone", sbXpDolphinPet, fishingObj.get("dolphin_milestone").getAsInt(), false));
+
+ levelPage.getInstance().renderLevelBar(
+ "Skill Related Task",
+ new ItemStack(Items.diamond_sword),
+ guiLeft + 23,
+ guiTop + 115,
+ 110,
+ 0,
+ sbXpHotmTier + sbXpCommissionMilestone + +sbXpGainedByAnita + sbXpPotmTier + sbXpTrophyFish + sbXpRockPet +
+ sbXpDolphinPet,
+ levelPage.getConstant().getAsJsonObject("category_xp").get("skill_related_task").getAsInt(),
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+ }
+
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SlayingTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SlayingTaskLevel.java
new file mode 100644
index 00000000..906fe1cd
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/SlayingTaskLevel.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2023 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.level.task;
+
+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.profileviewer.ExtraPage;
+import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import io.github.moulberry.notenoughupdates.util.Utils;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class SlayingTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public SlayingTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ // slayer
+ JsonObject slayingTask = levelPage.getConstant().get("slaying_task").getAsJsonObject();
+ JsonArray slayerLevelUpXp = slayingTask.get("slayer_level_up_xp").getAsJsonArray();
+ Map<String, ProfileViewer.Level> skyblockInfo = levelPage.getProfile().getSkyblockInfo(levelPage.getProfileId());
+ List<String> slayers = Arrays.asList("zombie", "spider", "wolf", "enderman", "blaze");
+
+ int sbXpGainedSlayer = 0;
+ if (skyblockInfo != null) {
+ for (String slayer : slayers) {
+ ProfileViewer.Level level = skyblockInfo.get(slayer);
+ for (int i = 0; i < (int) level.level; i++) {
+ int asInt = slayerLevelUpXp.get(i).getAsInt();
+ sbXpGainedSlayer += asInt;
+ }
+ }
+ }
+
+ JsonObject bossCollectionsXp = slayingTask.getAsJsonObject("boss_collections_xp");
+
+ HashMap<String, Double> allComps = new HashMap<>();
+ JsonElement normalCompletions = Utils
+ .getElement(object, "dungeons.dungeon_types.catacombs.tier_completions");
+
+ JsonElement masterCompletions = Utils
+ .getElement(object, "dungeons.dungeon_types.master_catacombs.tier_completions");
+
+ if (normalCompletions != null) {
+ HashMap<String, Double> normalCompMap = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(
+ normalCompletions.getAsJsonObject(),
+ HashMap.class
+ );
+ normalCompMap.forEach((floor, value) -> {
+ if (allComps.containsKey(floor)) {
+ allComps.put(floor, allComps.get(floor) + value);
+ } else {
+ allComps.put(floor, value);
+ }
+ });
+ }
+ if (masterCompletions != null) {
+ HashMap<String, Double> masterCompMap = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(
+ masterCompletions.getAsJsonObject(),
+ HashMap.class
+ );
+
+ masterCompMap.forEach((floor, value) -> {
+ if (allComps.containsKey(floor)) {
+ allComps.put(floor, allComps.get(floor) + value);
+ } else {
+ allComps.put(floor, value);
+ }
+ });
+ }
+ int[] bossLow = {25, 50, 100, 150, 250, 1000};
+ int[] thorn = {25, 50, 150, 250, 400, 1000};
+ int[] bossHigh = {50, 100, 150, 250, 500, 750, 1000};
+ // THIS SERVER IS AWESOME I LOVE CONSISTENCY!!!!!!!
+
+ int bossCollectionXp = 0;
+ JsonArray dungeonCollectionXp = bossCollectionsXp.getAsJsonArray("dungeon_collection_xp");
+ for (int i = 1; i <= 7; i++) {
+ if (!allComps.containsKey(i + "")) continue;
+ double value = allComps.get(i + "");
+ switch (i) {
+ case 1:
+ case 2:
+ case 3:
+ bossCollectionXp += loopThroughCollection(
+ bossLow,
+ value,
+ dungeonCollectionXp
+ );
+ break;
+ case 4:
+ bossCollectionXp += loopThroughCollection(
+ thorn,
+ value,
+ dungeonCollectionXp
+ );
+ break;
+ case 5:
+ case 6:
+ case 7:
+ bossCollectionXp += loopThroughCollection(
+ bossHigh,
+ value,
+ dungeonCollectionXp
+ );
+ break;
+ }
+ }
+
+ JsonArray defeatKuudraXp = slayingTask.get("defeat_kuudra_xp").getAsJsonArray();
+ // kuudra
+
+ int sbXpDefeatKuudra = 0;
+
+ int kuudraBossCollection = 0;
+ if (object.has("nether_island_player_data")) {
+ JsonObject jsonObject = object.getAsJsonObject("nether_island_player_data").getAsJsonObject(
+ "kuudra_completed_tiers");
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : jsonObject.entrySet()) {
+ String key = stringJsonElementEntry.getKey();
+ int value = stringJsonElementEntry.getValue().getAsInt();
+ if (key.equals("none")) {
+ sbXpDefeatKuudra += defeatKuudraXp.get(0).getAsInt();
+ kuudraBossCollection += value;
+ }
+ if (key.equals("hot")) {
+ sbXpDefeatKuudra += defeatKuudraXp.get(1).getAsInt();
+ kuudraBossCollection += 2 * value;
+ }
+ if (key.equals("burning")) {
+ sbXpDefeatKuudra += defeatKuudraXp.get(2).getAsInt();
+ kuudraBossCollection += 3 * value;
+ }
+ if (key.equals("fiery")) {
+ sbXpDefeatKuudra += defeatKuudraXp.get(3).getAsInt();
+ kuudraBossCollection += 4 * value;
+ }
+ if (key.equals("infernal")) {
+ sbXpDefeatKuudra += defeatKuudraXp.get(4).getAsInt();
+ kuudraBossCollection += 5 * value;
+ }
+ }
+ if (kuudraBossCollection >= 10) bossCollectionXp += 10;
+ if (kuudraBossCollection >= 100) bossCollectionXp += 15;
+ if (kuudraBossCollection >= 500) bossCollectionXp += 20;
+ if (kuudraBossCollection >= 2000) bossCollectionXp += 25;
+ if (kuudraBossCollection >= 5000) bossCollectionXp += 30;
+ }
+
+ int sbXpBestiary = 0;
+ int bestiaryTiers = GuiProfileViewer.getProfile().getBestiaryTiers(object);
+ sbXpBestiary += bestiaryTiers;
+ sbXpBestiary = sbXpBestiary + (sbXpBestiary / 10) * 2;
+
+ int mythologicalKillsXp = 0;
+ if (object.has("stats")) {
+ JsonObject stats = object.get("stats").getAsJsonObject();
+ if (stats.has("mythos_kills")) mythologicalKillsXp += (mythologicalKillsXp += stats.get("mythos_kills").getAsLong() / 100);
+ }
+
+ int mythologicalKillsMax = slayingTask.get("mythological_kills").getAsInt();
+ if(mythologicalKillsXp > mythologicalKillsMax) mythologicalKillsXp = mythologicalKillsMax;
+
+ // dragons
+ int sbXpFromDragonKills = 0;
+ JsonObject slayDragonsXp = slayingTask.getAsJsonObject("slay_dragons_xp");
+ for (Map.Entry<String, JsonElement> stringJsonElementEntry : slayDragonsXp.entrySet()) {
+ String key = stringJsonElementEntry.getKey();
+ int value = stringJsonElementEntry.getValue().getAsInt();
+ // kills_superior_dragon_100
+ float element = Utils.getElementAsFloat(Utils.getElement(object, "bestiary.kills_"
+ + key + "_100"), 0);
+ if (element > 0) {
+ sbXpFromDragonKills += value;
+ }
+ }
+
+ // slasyer kills
+ int sbXpFromSlayerDefeat = 0;
+
+ JsonArray defeatSlayersXp = slayingTask.get("defeat_slayers_xp").getAsJsonArray();
+ for (String s : ExtraPage.slayers.keySet()) {
+ int maxLevel = ExtraPage.slayers.get(s);
+ for (int i = 0; i < 5; i++) {
+ if (i >= maxLevel) break;
+ float tier = Utils.getElementAsFloat(
+ Utils.getElement(object, "slayer_bosses." + s + ".boss_kills_tier_" + i),
+ 0
+ );
+ if (tier != 0) {
+ int value = defeatSlayersXp.get(i).getAsInt();
+ sbXpFromSlayerDefeat += value;
+ }
+ }
+ }
+
+ // arachne
+ JsonArray defeatArachneXp = slayingTask.get("defeat_arachne_xp").getAsJsonArray();
+ int sbXpGainedArachne = 0;
+
+ JsonElement tier1 = Utils.getElement(object, "bestiary.kills_arachne_300");
+ if (tier1 != null) {
+ sbXpGainedArachne += defeatArachneXp.get(0).getAsInt();
+ }
+
+ JsonElement tier2 = Utils.getElement(object, "bestiary.kills_arachne_500");
+ if (tier2 != null) {
+ sbXpGainedArachne += defeatArachneXp.get(1).getAsInt();
+ }
+
+ List<String> lore = new ArrayList<>();
+
+ int slayerLevelUpMax = slayingTask.get("slayer_level_up").getAsInt();
+ int bossCollectionsMax = slayingTask.get("boss_collections").getAsInt();
+ int slayDragonsMax = slayingTask.get("slay_dragons").getAsInt();
+ int defeatSlayersMax = slayingTask.get("defeat_slayers").getAsInt();
+ int defeatKuudraMax = slayingTask.get("defeat_kuudra").getAsInt();
+ int defeatArachneMax = slayingTask.get("defeat_arachne").getAsInt();
+
+ lore.add(levelPage.buildLore("Slayer Level Up", sbXpGainedSlayer, slayerLevelUpMax, false));
+ lore.add(levelPage.buildLore("Boss Collections", bossCollectionXp, bossCollectionsMax, false));
+ lore.add(levelPage.buildLore("Bestiary Progress", sbXpBestiary, 0, true));
+ lore.add(levelPage.buildLore("Mythological Kills", mythologicalKillsXp, mythologicalKillsMax, false));
+ lore.add(levelPage.buildLore("Slay Dragons", sbXpFromDragonKills, slayDragonsMax, false));
+ lore.add(levelPage.buildLore("Defeat Slayers", sbXpFromSlayerDefeat, defeatSlayersMax, false));
+ lore.add(levelPage.buildLore("Defeat Kuudra", sbXpDefeatKuudra, defeatKuudraMax, false));
+ lore.add(levelPage.buildLore("Defeat Arachne", sbXpGainedArachne, defeatArachneMax, false));
+
+ int slayingTaskMax = levelPage.getConstant().getAsJsonObject("category_xp").get("slaying_task").getAsInt();
+
+ levelPage.getInstance().renderLevelBar(
+ "Slaying Task",
+ new ItemStack(Items.golden_sword),
+ guiLeft + 23,
+ guiTop + 85,
+ 110,
+ 0, sbXpGainedSlayer + bossCollectionXp + mythologicalKillsXp +
+ +sbXpFromDragonKills + sbXpFromSlayerDefeat + sbXpDefeatKuudra + sbXpGainedArachne,
+ slayingTaskMax,
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+ }
+
+ private int loopThroughCollection(int[] array, double value, JsonArray jsonArray) {
+ int i = 0;
+ int gain = 0;
+ for (int bossReq : array) {
+ if (value >= bossReq) {
+ int gained = jsonArray.get(i).getAsInt();
+ gain += gained;
+ }
+ i++;
+ }
+ return gain;
+ }
+}
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/StoryTaskLevel.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/StoryTaskLevel.java
new file mode 100644
index 00000000..909f7b8e
--- /dev/null
+++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/level/task/StoryTaskLevel.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2023 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.level.task;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import io.github.moulberry.notenoughupdates.profileviewer.level.LevelPage;
+import net.minecraft.init.Items;
+import net.minecraft.item.ItemStack;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class StoryTaskLevel {
+
+ private final LevelPage levelPage;
+
+ public StoryTaskLevel(LevelPage levelPage) {this.levelPage = levelPage;}
+
+ public void loadInformation() {
+
+ }
+
+ public void drawTask(JsonObject object, int mouseX, int mouseY, int guiLeft, int guiTop) {
+ JsonObject storyTask = levelPage.getConstant().getAsJsonObject("story_task");
+ JsonArray storyTaskNames = storyTask.getAsJsonArray("complete_objectives_names");
+
+ JsonObject objectives = object.getAsJsonObject("objectives");
+
+ int storyTaskXp = storyTask.get("complete_objectives_xp").getAsInt();
+ int sbXpStory = 0;
+ for (JsonElement storyTaskName : storyTaskNames) {
+ String value = storyTaskName.getAsString();
+ if (objectives.has(value)) {
+ JsonObject jsonObject = objectives.get(value).getAsJsonObject();
+ if (jsonObject.has("status") && jsonObject.get("status").getAsString().equals("COMPLETE")) {
+ sbXpStory += storyTaskXp;
+ }
+ } else {
+ }
+ }
+
+ List<String> lore = new ArrayList<>();
+ lore.add(levelPage.buildLore("Complete Objectives",
+ sbXpStory, storyTask.get("complete_objectives").getAsInt(), false
+ ));
+
+ levelPage.getInstance().renderLevelBar(
+ "Story Task",
+ new ItemStack(Items.map),
+ guiLeft + 299,
+ guiTop + 85,
+ 110,
+ 0,
+ sbXpStory,
+ levelPage.getConstant().getAsJsonObject("category_xp").get("story_task").getAsInt(),
+ mouseX,
+ mouseY,
+ true,
+ lore
+ );
+ }
+}
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 0105ba1f..27ffe4d0 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Constants.java
@@ -41,6 +41,7 @@ import java.util.concurrent.locks.ReentrantLock;
import java.util.regex.Pattern;
public class Constants {
+
private static class PatternSerializer implements JsonDeserializer<Pattern>, JsonSerializer<Pattern> {
@Override
public Pattern deserialize(
@@ -78,6 +79,7 @@ public class Constants {
public static JsonObject RNGSCORE;
public static JsonObject ABIPHONE;
public static JsonObject ESSENCESHOPS;
+ public static JsonObject SBLEVELS;
private static final ReentrantLock lock = new ReentrantLock();
@@ -102,6 +104,7 @@ public class Constants {
RNGSCORE = Utils.getConstant("rngscore", gson);
ABIPHONE = Utils.getConstant("abiphone", gson);
ESSENCESHOPS = Utils.getConstant("essenceshops", gson);
+ SBLEVELS = Utils.getConstant("sblevels", gson);
parseEssenceCosts();
} catch (Exception ex) {
diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
index 571a43f9..78fb5669 100644
--- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
+++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java
@@ -28,6 +28,7 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking;
+import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.PositionedSoundRecord;
@@ -569,6 +570,70 @@ public class Utils {
drawTexturedRect(x, y, width, height, 0, 1, 0, 1);
}
+ public static void drawPvSideButton(
+ int yIndex,
+ ItemStack itemStack,
+ boolean pressed,
+ GuiProfileViewer guiProfileViewer
+ ) {
+ int guiLeft = GuiProfileViewer.getGuiLeft();
+ int guiTop = GuiProfileViewer.getGuiTop();
+
+ GlStateManager.disableLighting();
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.enableAlpha();
+ GlStateManager.alphaFunc(516, 0.1F);
+
+ int x = guiLeft - 28;
+ int y = guiTop + yIndex * 28;
+
+ float uMin = 193 / 256f;
+ float uMax = 223 / 256f;
+ float vMin = 200 / 256f;
+ float vMax = 228 / 256f;
+ if (pressed) {
+ uMin = 224 / 256f;
+ uMax = 1f;
+
+ if (yIndex != 0) {
+ vMin = 228 / 256f;
+ vMax = 1f;
+ }
+
+ guiProfileViewer.renderBlurredBackground(
+ guiProfileViewer.width,
+ guiProfileViewer.height,
+ x + 2,
+ y + 2,
+ 30,
+ 28 - 4
+ );
+ } else {
+ guiProfileViewer.renderBlurredBackground(
+ guiProfileViewer.width,
+ guiProfileViewer.height,
+ x + 2,
+ y + 2,
+ 28 - 2,
+ 28 - 4
+ );
+ }
+
+ GlStateManager.disableLighting();
+ GlStateManager.enableBlend();
+ GL14.glBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GlStateManager.enableAlpha();
+ GlStateManager.alphaFunc(516, 0.1F);
+
+ Minecraft.getMinecraft().getTextureManager().bindTexture(GuiProfileViewer.pv_elements);
+
+ Utils.drawTexturedRect(x, y, pressed ? 32 : 28, 28, uMin, uMax, vMin, vMax, GL11.GL_NEAREST);
+
+ GlStateManager.enableDepth();
+ Utils.drawItemStack(itemStack, x + 8, y + 7);
+ }
+
public static void drawTexturedRect(float x, float y, float width, float height, int filter) {
drawTexturedRect(x, y, width, height, 0, 1, 0, 1, filter);
}
@@ -1961,13 +2026,13 @@ public class Utils {
if (NotEnoughUpdates.INSTANCE.config.notifications.outdatedRepo) {
NotificationHandler.displayNotification(Lists.newArrayList(
EnumChatFormatting.RED + EnumChatFormatting.BOLD.toString() + "Missing repo data",
- EnumChatFormatting.RED +
- "Data used for many NEU features is not up to date, this should normally not be the case.",
- EnumChatFormatting.RED + "You can try " + EnumChatFormatting.BOLD + "/neuresetrepo" + EnumChatFormatting.RESET +
- EnumChatFormatting.RED + " and restart your game" +
- " to see if that fixes the issue.",
- EnumChatFormatting.RED + "If the problem persists please join " + EnumChatFormatting.BOLD +
- "discord.gg/moulberry" +
+ EnumChatFormatting.RED +
+ "Data used for many NEU features is not up to date, this should normally not be the case.",
+ EnumChatFormatting.RED + "You can try " + EnumChatFormatting.BOLD + "/neuresetrepo" + EnumChatFormatting.RESET +
+ EnumChatFormatting.RED + " and restart your game" +
+ " to see if that fixes the issue.",
+ EnumChatFormatting.RED + "If the problem persists please join " + EnumChatFormatting.BOLD +
+ "discord.gg/moulberry" +
EnumChatFormatting.RESET + EnumChatFormatting.RED + " and message in " + EnumChatFormatting.BOLD +
"#neu-support" + EnumChatFormatting.RESET + EnumChatFormatting.RED + " to get support"
),
@@ -2064,4 +2129,10 @@ public class Utils {
slot, 0, 0, Minecraft.getMinecraft().thePlayer
);
}
+
+ public static void drawItemStackWithTextScaled(ItemStack skull, int x, int y, String s, double factor) {
+ GlStateManager.scale(factor, factor, 1);
+ drawItemStackWithText(skull,x,y,s);
+ GlStateManager.scale(1 / factor, 1 / factor, 1);
+ }
}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt
index 51361bd3..2f2419eb 100644
--- a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt
@@ -91,10 +91,10 @@ data class ProfileCollectionInfo(
fun getCollectionData(
profileData: JsonObject,
- mainPlayer: UUID,
+ mainPlayer: String,
collectionData: CollectionMetadata
): ProfileCollectionInfo? {
- val mainPlayerUUID = mainPlayer.toString().replace("-", "")
+ val mainPlayerUUID = mainPlayer.replace("-", "")
val members = profileData["members"] as? JsonObject ?: return null
val mainPlayerData =
(members[mainPlayerUUID] as? JsonObject ?: return null)
@@ -136,7 +136,7 @@ data class ProfileCollectionInfo(
* should contain profile_id, members, cute_name, etc.)
*/
@JvmStatic
- fun getCollectionData(profileData: JsonObject, mainPlayer: UUID): CompletableFuture<ProfileCollectionInfo?> {
+ fun getCollectionData(profileData: JsonObject, mainPlayer: String): CompletableFuture<ProfileCollectionInfo?> {
return hypixelCollectionInfo.thenApply {
getCollectionData(profileData, mainPlayer, it)
}
diff --git a/src/main/resources/assets/notenoughupdates/pv_basic.png b/src/main/resources/assets/notenoughupdates/pv_basic.png
index 4d5236f5..de254644 100644
--- a/src/main/resources/assets/notenoughupdates/pv_basic.png
+++ b/src/main/resources/assets/notenoughupdates/pv_basic.png
Binary files differ
diff --git a/src/main/resources/assets/notenoughupdates/pv_levels.png b/src/main/resources/assets/notenoughupdates/pv_levels.png
new file mode 100644
index 00000000..21810476
--- /dev/null
+++ b/src/main/resources/assets/notenoughupdates/pv_levels.png
Binary files differ